使用IdentityServer3调用Web API时未经授权401 [英] 401 Unauthorized when calling Web API using IdentityServer3
问题描述
我正在尝试使用IdentityServer3和Client Credential流创建一个简单的示例.该示例包含一个控制台客户端,该客户端使用从IdentityServer接收到的令牌来调用Web API资源. Web API和IdentityServer托管在IIS中.
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.
我设法使用以下方法从IdentityServer获取令牌:
I manage to get the token from the IdentityServer using:
var client = new TokenClient(
"https://machine+domain/WebHostedId3/connect/token",
"client",
"secret");
但是当我尝试使用以下方法调用Web API时:
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;
我收到401(响应状态代码不表示成功:401(未授权).
I recevie a 401 (Response status code does not indicate success: 401 (Unauthorized).
IdentityServer的设置如下:
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);
}
}
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());
}
}
用于SSL的证书是使用IIS创建自签名证书功能创建的,并连接到IdentityServer的https绑定.除了响应状态代码不表示成功:401(未授权)"例外,我找不到更多详细信息. IdentityServer的日志看起来不错.帮助将不胜感激.
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.
推荐答案
在WebAPI配置中,在IdentityServerBearerTokenAuthenticationOptions
中,属性Authority
的值不正确.它必须是IdentityServer实例的基本URI,即https://localhost/WebHostedId3
,而不仅仅是localhost
,也不是localhost:443
.
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
.
考虑到IdentityServer3默认情况下需要TLS,那么您需要指定https
方案,而不仅仅是http
.
Taken into account that IdentityServer3 requires TLS per default, then you'll need to specify https
scheme and not just http
.
因此,只要您的IdentityServer基本URI为https://localhost/WebHostedId3
,则正确的设置将如下所示
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" }
});
这篇关于使用IdentityServer3调用Web API时未经授权401的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!