asp.net-mvc IdentityServer4 基于角色的授权

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40844310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:34:31  来源:igfitidea点击:

Role based authorization with IdentityServer4

asp.net-mvcasp.net-coreidentityserver4

提问by muhammad waqas

I am trying to implement "Role Based Authorization" using IdentityServer4 to give access to my API based on the user roles.

我正在尝试使用 IdentityServer4 实现“基于角色的授权”,以便根据用户角色访问我的 API。

For example , I want to have two roles for the user i.e. FreeUser and PaidUser and want to give access to the API through the Authorize Attribute using [Authorize(Roles = "FreeUser"))], Kindly help me that How can I achieve this.

例如,我想为用户提供两个角色,即 FreeUser 和 PaidUser,并希望使用 [Authorize(Roles = "FreeUser"))] 通过授权属性授予对 API 的访问权限,请帮助我如何实现这一点.

I have the following solution structure :

我有以下解决方案结构:

  1. IdentityServer
  2. WebApi
  3. Javascript Client
  1. 身份服务器
  2. 网络接口
  3. Javascript客户端

I have registered my Javascript client as follows:

我已按如下方式注册了我的 Javascript 客户端:

 new Client
            {
                ClientId = "js",
                ClientName = "javascript client",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser= true,
                RedirectUris = {"http://localhost:5004/callback.html"},
                PostLogoutRedirectUris = {"http://localhost:5004/index.html"},
                AllowedCorsOrigins = {"http://localhost:5004"},

                AllowedScopes =
                {
                    StandardScopes.OpenId.Name,
                    StandardScopes.Profile.Name,
                    "api1",
                    "role",
                    StandardScopes.AllClaims.Name
                }
            }

Scopes

范围

 return new List<Scope>
        {
            StandardScopes.OpenId,
            StandardScopes.Profile,

            new Scope
            {
                Name = "api1",
                Description = "My API"
            },
           new Scope
           {
               Enabled = true,
               Name  = "role",
               DisplayName = "Role(s)",
               Description = "roles of user",
               Type = ScopeType.Identity,
               Claims = new List<ScopeClaim>
               {
                   new ScopeClaim("role",false)
               }
           },
           StandardScopes.AllClaims
        };

Users

用户

 return new List<InMemoryUser>
        {
            new InMemoryUser
            {
                Subject = "1",
                Username = "alice",
                Password = "password",

                Claims = new List<Claim>
                {
                    new Claim("name", "Alice"),
                    new Claim("website", "https://alice.com"),
                    new Claim("role","FreeUser")
                }
            },
            new InMemoryUser
            {
                Subject = "2",
                Username = "bob",
                Password = "password",

                Claims = new List<Claim>
                {
                    new Claim("name", "Bob"),
                    new Claim("website", "https://bob.com"),
                    new Claim("role","PaidUser")
                }
            }
        };

WebApi Startup.cs

WebApi Startup.cs

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();


        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        app.UseCors("default");
        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            ScopeName = "api1",
            //  AdditionalScopes = new List<string> { "openid","profile", "role" },
            RequireHttpsMetadata = false
        });

        app.UseMvc();
    }

Web Api controller

Web API 控制器

namespace Api.Controllers
{
 [Route("[controller]")]

public class IdentityController : ControllerBase
{
    [HttpGet]
    [Authorize(Roles = "PaidUser")]
    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims select new { c.Type,    c.Value });
    }

    [Authorize(Roles = "FreeUser")]
    [HttpGet]
    [Route("getfree")]
    public IActionResult GetFreeUser()
    {
        return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }
}
}

Javascript Client app.jsHere I am trying to login the user through IdentityServer and make an API Request.

Javascript Client app.js这里我试图通过 IdentityServer 登录用户并发出 API 请求。

var mgr = new Oidc.UserManager(config);
mgr.getUser().then(function (user) {
if (user) {
    log("User logged in", user.profile);
} else {
    log("User is not logged in.");
}
});

function login() {
  mgr.signinRedirect();
 }

function api() {
mgr.getUser().then(function (user) {
    var url = "http://localhost:5001/identity/getfree";

    var xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = function () {
        log(xhr.status, JSON.parse(xhr.responseText));
    };

    xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
    xhr.send();
  });
 }

 function logout() {
   mgr.signoutRedirect();
 }

The Login flow works fine and I can login successfully, and I can receive the role in the access token.

登录流程工作正常,我可以成功登录,并且可以在访问令牌中接收角色。

enter image description here

在此处输入图片说明

When I make a request to the API by clicking the button (Call Api) then I get the following error.. enter image description here

当我通过单击按钮(调用 Api)向 API 发出请求时,出现以下错误。 在此处输入图片说明

采纳答案by rawel

Given that you have not provided config object for javascript client, I assume you have scope configured as follows.

鉴于您尚未为 javascript 客户端提供配置对象,我假设您的范围配置如下。

scope:"openid profile api1 role"

I believe that the main reason for your issue is that role claim is not included in your access token.

我相信您的问题的主要原因是角色声明未包含在您的访问令牌中。

Add role claim to api1 scope as follows to include it in the access token.

将角色声明添加到 api1 范围,如下所示,将其包含在访问令牌中。

             new Scope
                {
                    Name = "api1",
                    DisplayName = "API1 access",
                    Description = "My API",
                    Type = ScopeType.Resource,
                    IncludeAllClaimsForUser = true,
                    Claims = new List<ScopeClaim>
                    {
                        new ScopeClaim(ClaimTypes.Name),
                        new ScopeClaim(ClaimTypes.Role)
                    }
                }

You can read my answer here for help debug the issue. implementing roles in identity server 4 with asp.net identity

您可以在此处阅读我的回答以帮助调试问题。 使用 asp.net 身份在身份服务器 4 中实现角色

The complete working solution is here. https://github.com/weliwita/IdentityServer4.Samples/tree/40844310

完整的工作解决方案在这里。 https://github.com/weliwita/IdentityServer4.Samples/tree/40844310

回答by adem caglin

Change new Claim("role","FreeUser")to new Claim(ClaimTypes.Role, "FreeUser")

更改new Claim("role","FreeUser")new Claim(ClaimTypes.Role, "FreeUser")

Or create a policy like this:

或者创建一个这样的策略:

services.AddAuthorization(options =>
{
    options.AddPolicy("FreeUser", policy => policy.RequireClaim("role", "FreeUser"));
});

and use it :

并使用它:

Authorize[(Policy = "FreeUser")]

回答by Mohammad Karimi

I wrote a sample on this post

我在这篇文章上写了一个样本

Identity Server 4: adding claims to access token

身份服务器 4:向访问令牌添加声明

I have tested with Roles and claims also I can use [Authorize(Role="SuperAdmin, Admin")] in both client web app and API app.

我已经对角色和声明进行了测试,我也可以在客户端 Web 应用程序和 API 应用程序中使用 [Authorize(Role="SuperAdmin, Admin")]。