使用ASP.NET角色授权与IdentityServer3隐式流 [英] Using ASP.NET Role Authorisation with IdentityServer3 implicit flow

查看:1358
本文介绍了使用ASP.NET角色授权与IdentityServer3隐式流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的单页的应用程序使用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 query User.IsInRole("Administrator") it is always false, even when the user is assigned to that role. Further, if I add a role name to the Authorize 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 and role, because their names get transformed and no longer map to what you were expecting. This results in the [Authorize(Roles = "")] and User.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 the Name and Role claims to be included when accessing the API, you need to specifically mark them as alwaysInclude in your ScopeClaim 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆