使用ASP.NET角色授权与IdentityServer3隐式流 [英] Using ASP.NET Role Authorisation with IdentityServer3 implicit flow
问题描述
我的单页的应用程序使用OidcTokenManager使用隐式流程连接到IdentityServer3 STS。客户端呈现IDS3访问令牌到ASP.NET核心(的WebAPI)Web服务作为一个承载令牌; ,Web服务应用程序配置为使用IDS3中间件和限制访问使用授权属性,它的方法。
SPA客户端配置:
<预类=郎-JS prettyprint-覆盖>
函数configureTokenManager(){
的console.log(configureTokenManager());
无功配置= {
权威:$ config.authority,
CLIENT_ID:BNRegistry,
REDIRECT_URI:$ config.webRoot +/#/授权/,
post_logout_redirect_uri:$ config.webRoot +/#/,
RESPONSE_TYPE:id_token令牌,
范围:OpenID的个人资料的电子邮件BNApi,
silent_redirect_uri:$ config.webRoot +/#/更新/,
silent_renew:真的,
filter_protocol_claims:假
};
返回新OidcTokenManager(配置);
};
在STS范围配置:
新范围
{
NAME =BNApi,
显示名称=BN阿比,
启用=真,
类型= ScopeType.Resource,
=经新的List< ScopeClaim>
{
新ScopeClaim(Constants.ClaimTypes.Name),
新ScopeClaim(Constants.ClaimTypes.Role)
}
}
的WebAPI的配置:
app.UseIdentityServerBearerTokenAuthentication(新IdentityServerBearerTokenAuthenticationOptions
{
管理局=配置[管理局],
RequiredScopes =新[] {BNApi},
NameClaimType = IdentityModel.JwtClaimTypes.Name,
RoleClaimType = IdentityModel.JwtClaimTypes.Role
});
的WebAPI方式:
[授权]
公共IActionResult获得()
{
:
}
这正常工作,拒绝了401未认证用户如果我检查在API控制器方法用户索赔,(如: User.Claims.ToList()
),它包含该用户已被分配任何角色条目。
不过,如果我检查 User.Identity.Name
属性始终是空的,如果我查询 User.IsInRole(管理员)
它始终是假的,即使用户被分配到该角色。此外,如果我添加角色名称为授权
属性( [授权(角色=管理员)]
) ,用户与401拒绝他们是否属于规定的作用。
我怎样才能得到IdentityServer3与ASP.NET角色授权很好玩呢?
你试过重置 InboundClaimTypeMap
?
从IdentityServer3文档页面这里:
当您检查有关页面上的说法,你会发现两个
的事情:一些声称具有奇长的类型名称和有更索赔
可能比你需要在你的应用程序。
长索赔名来自微软的智威汤逊处理程序试图映射
有些人声称类型NET的ClaimTypes类类型。
块引用>
不幸的是这种映射最终打破已定义为
具体的要求名字命名
和角色
,因为他们的名字得到转变,不再映射到您所期望的东西。这导致在[授权(角色=)]
和User.IsInRole()
未正常工作。预计
在您的API
Startup.cs
您应该添加以下内容:
<预类=郎-CS prettyprint-覆盖>JwtSecurityTokenHandler.InboundClaimTypeMap =新词典<字符串,字符串>();
app.UseIdentityServerBearerTokenAuthentication(新IdentityServerBearerTokenAuthenticationOptions()
{
:
});
编辑:的以下信息是不正确的!如由@保罗泰勒指出的
AlwaysInclude
属性确保有关权利要求总是存在于一个身份令牌(它用来与客户端,而不是在API)。这是一个资源范围,所以,酒店有没有效果。感谢您帮助我了解一点关于IdentityServer是如何工作的: - )
<击>
对于名称
和角色
声称被列入访问该API时,你需要明确它们标记为alwaysInclude
在你的ScopeClaim
列表。
<预类=郎-CS prettyprint-覆盖>新范围
{
NAME =BNApi,
显示名称=BN阿比,
启用=真,
类型= ScopeType.Resource,
=经新清单< ScopeClaim>
{
新ScopeClaim(Constants.ClaimTypes.Name,真),//< - 在这里$ B $添加对b新ScopeClaim(Constants.ClaimTypes.Role,真)//这里!
}
}
行使>
My single page application uses OidcTokenManager to connect to an IdentityServer3 STS using implicit flow. The client presents the IDS3 access token to a ASP.NET Core (WebApi) web service as a Bearer Token; the web service application is configured to use IDS3 middleware and restricts access to its methods using an Authorize attribute.
SPA client configuration:
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); };
Scope configuration in 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 configuration:
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions { Authority = Configuration["Authority"], RequiredScopes = new[] {"BNApi"}, NameClaimType = IdentityModel.JwtClaimTypes.Name, RoleClaimType = IdentityModel.JwtClaimTypes.Role });
WebApi method:
[Authorize] public IActionResult Get() { ... }
This works as expected, rejecting an unauthenticated user with a 401. If I examine the claims for the user in the api controller method, (eg.
User.Claims.ToList()
), it contains entries for any roles to which the user has been assigned.However, if I examine the
User.Identity.Name
property it is always null, and if I queryUser.IsInRole("Administrator")
it is always false, even when the user is assigned to that role. Further, if I add a role name to theAuthorize
attribute ([Authorize(Role="Administrator")]
), users are rejected with a 401 whether or not they belong to the stated role.How can I get IdentityServer3 to play nicely with ASP.NET Role authorisation?
解决方案Have you tried resetting the
InboundClaimTypeMap
?From the IdentityServer3 documentation page here:
When you inspect the claims on the about page, you will notice two things: some claims have odd long type names and there are more claims than you probably need in your application.
The long claim names come from Microsoft’s JWT handler trying to map some claim types to .NET's ClaimTypes class types.
Unfortunately this mapping ends up breaking the specific claim names you have defined as
name
androle
, because their names get transformed and no longer map to what you were expecting. This results in the[Authorize(Roles = "")]
andUser.IsInRole("")
not working as expected.In your API
Startup.cs
you should add the following:JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions() { ... });
EDIT: The below information was incorrect!. As pointed out by @Paul Taylor "the
AlwaysInclude
property ensures that the relevant claim is always present in an identity token (which is used with the client, not the API). This is a resource scope so the property has no effect.". Thanks for helping me understand a little more about how IdentityServer works :-)
For theName
andRole
claims to be included when accessing the API, you need to specifically mark them asalwaysInclude
in yourScopeClaim
list.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! } }
这篇关于使用ASP.NET角色授权与IdentityServer3隐式流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!