问题
I'm trying to set up a simple example using IdentityServer3 with the Client Credential flow. The example contains a console client calling a Web API resource with a token recieved from the IdentityServer. The Web API and IdentityServer is hosted in IIS.
I manage to get the token from the IdentityServer using:
var client = new TokenClient(
"https://machine+domain/WebHostedId3/connect/token",
"client",
"secret");
but when I try calling the Web API using:
var client = new HttpClient();
client.SetBearerToken(token);
var response = client.GetStringAsync("http://localhost/WebHostedApi/api/products").Result;
I recevie a 401 (Response status code does not indicate success: 401 (Unauthorized).
The IdentityServer is set up as follows:
public class Clients
{
public static List<Client> Get()
{
return new List<Client>
{
new Client
{
ClientName = "Client Credentials Flow Client",
Enabled = true,
ClientId = "client",
AccessTokenType = AccessTokenType.Reference,
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
},
Flow = Flows.ClientCredentials,
AllowedScopes = new List<string>
{
"api"
}
}
};
}
}
public class Scopes
{
public static IEnumerable<Scope> Get()
{
return new[]
{
new Scope
{
Name = "api",
DisplayName = "API Scope",
Type = ScopeType.Resource,
Emphasize = false
}
};
}
}
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({Name}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
var factory = new IdentityServerServiceFactory()
.UseInMemoryUsers(new System.Collections.Generic.List<InMemoryUser>())
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get());
var options = new IdentityServerOptions
{
Factory = factory,
};
appBuilder.UseIdentityServer(options);
}
}
The Web API:
public static class WebApiConfig
{
public static HttpConfiguration Register()
{
var config = new HttpConfiguration();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultRouting",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute());
return config;
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({Name}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "machine+domain:443",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api" }
});
app.UseWebApi(WebApiConfig.Register());
}
}
The certificate used for SSL is created using the IIS Create Self-Signed Certificate function and connected to the https binding for the IdentityServer. Except for the "Response status code does not indicate success: 401 (Unauthorized)" exception I can't find any more details. The logs from IdentityServer looks good. Help would be greatly appreciated.
回答1:
I know it is very late reply. Try to update all nugets, especially Newtonsoft.Json to 8.0.3
回答2:
Sorry for the very late response but if you enable full logging in IdentityServer it will pretty much tell you what the problem is.
Change
var options = new IdentityServerOptions
{
Factory = factory,
};
to
var options = new IdentityServerOptions
{
Factory = factory,
LoggingOptions = new LoggingOptions
{
EnableWebApiDiagnostics = true,
WebApiDiagnosticsIsVerbose = true,
EnableHttpLogging = true,
EnableKatanaLogging = true
}
}
You'll then see an awful lot of great debugging information that tells you what is going wrong.
回答3:
In your WebAPI configuration, in IdentityServerBearerTokenAuthenticationOptions
you have incorrect value for property Authority
. It has to be the base URI of your IdentityServer instance, i.e. https://localhost/WebHostedId3
, and not just localhost
, neither localhost:443
.
Taken into account that IdentityServer3 requires TLS per default, then you'll need to specify https
scheme and not just http
.
So, as long as your IdentityServer base URI is https://localhost/WebHostedId3
, then the correct setup will look like this
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost/WebHostedId3",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api" }
});
来源:https://stackoverflow.com/questions/33480517/401-unauthorized-when-calling-web-api-using-identityserver3