我的单页应用程序使用OidcTokenManager使用隐式流连接到IdentityServer3 STS。客户端将IDS3访问令牌作为承载令牌呈现给ASP.NET Core(WebApi)Web服务; Web服务应用程序配置为使用IDS3中间件,并使用Authorize属性限制对其方法的访问。
SPA客户端配置:
function configureTokenManager() {
console.log("configureTokenManager()");
var config = {
authority: $config.authority,
client_id: "BNRegistry",
redirect_uri: $config.webRoot + "/#/authorised/",
post_logout_redirect_uri: $config.webRoot + "/#/",
response_type: "id_token token",
scope: "openid profile email BNApi",
silent_redirect_uri: $config.webRoot + "/#/renew/",
silent_renew: true,
filter_protocol_claims: false
};
return new OidcTokenManager(config);
};
STS中的范围配置:
new Scope
{
Name = "BNApi",
DisplayName = "BN Api",
Enabled = true,
Type = ScopeType.Resource,
Claims = new List<ScopeClaim>
{
new ScopeClaim(Constants.ClaimTypes.Name),
new ScopeClaim(Constants.ClaimTypes.Role)
}
}
WebApi配置:
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = Configuration["Authority"],
RequiredScopes = new[] {"BNApi"},
NameClaimType = IdentityModel.JwtClaimTypes.Name,
RoleClaimType = IdentityModel.JwtClaimTypes.Role
});
WebApi方法:
[Authorize]
public IActionResult Get()
{
...
}
这可以正常工作,拒绝使用401的未经身份验证的用户。如果我在api控制器方法中检查用户的声明(例如。User.Claims.ToList()
),它包含用户的任何角色的条目已被分配。
但是,如果我检查User.Identity.Name
属性它始终为null,并且如果我查询User.IsInRole("Administrator")
它始终为false,即使将用户分配给该角色也是如此。此外,如果我向Authorize
属性([Authorize(Role="Administrator")]
)添加角色名称,则无论用户是否属于所述角色,都会拒绝用户。
如何使IdentityServer3能够很好地使用ASP.NET角色授权?
答案 0 :(得分:1)
您是否尝试重置InboundClaimTypeMap
?
从IdentityServer3文档页面here:
当您检查关于页面的声明时,您会注意到两个 事情:一些声称有奇怪的长型名称,还有更多的声明 比您在申请中可能需要的那样。
长索赔名称来自微软试图映射的JWT处理程序 一些声称类型为.NET的ClaimTypes类类型。
不幸的是,这种映射最终会破坏您定义为name
和role
的特定声明名称,因为它们的名称会被转换,不再映射到您期望的名称。这导致[Authorize(Roles = "")]
和User.IsInRole("")
无法正常工作。
在您的API Startup.cs
中,您应添加以下内容:
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions()
{
...
});
编辑:以下信息不正确!正如@Paul Taylor指出的那样,AlwaysInclude
属性确保相关声明始终存在于身份令牌中(与客户端一起使用,而不是API)。这是一个资源范围,因此该属性无效。&#34;。感谢您帮助我更多地了解IdentityServer的工作原理: - )
<击>
对于访问API时要包含的Name
和Role
声明,您需要在alwaysInclude
列表中将其标记为ScopeClaim
。
new Scope
{
Name = "BNApi",
DisplayName = "BN Api",
Enabled = true,
Type = ScopeType.Resource,
Claims = new List<ScopeClaim>
{
new ScopeClaim(Constants.ClaimTypes.Name, true), //<-- Add true here
new ScopeClaim(Constants.ClaimTypes.Role, true) // and here!
}
}
击> <击> 撞击>