如何使用 Identityserver4 添加/检查策略和角色 .net 核心 API 保护

Posted

技术标签:

【中文标题】如何使用 Identityserver4 添加/检查策略和角色 .net 核心 API 保护【英文标题】:How to add/check policy and role .net core API securing with Identityserver4 【发布时间】:2021-07-20 17:25:55 【问题描述】:

我对使用身份服务器4 保护 API 有疑问

身份资源

Name Claims
Roles role

APIResource

Name Scopes
testapi api1

APIScopes

Name Claims
api1 address

在 Startup.cs 中

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddJwtBearer("Bearer", opt =>
                
                    opt.Audience = "testapi";

                    opt.Authority = "https://localhost:5001";
                    opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    
                       ValidateAudience = true
                       
                    ;
                );
//Policy "Apiscope" created 
services.AddAuthorization(opt =>
            
                opt.AddPolicy("Apiscope", policy =>
                
                    policy.RequireAuthenticatedUser();
                    policy.RequireClaim("Scope", "api1");
                    
                );

            );

services.AddAuthorization(opt =>
            
                opt.AddPolicy("AdminUsers", policy =>
                
                    policy.RequireAuthenticatedUser();
                    policy.RequireRole("admin");

                );

            );

在控制器中

[HttpPost]
        [Authorize(Policy = "AdminUsers")]
        public IActionResult GetAdminMessage()
        
            return Ok("Hello Admin");
        
    .Net Core API 中是否可以访问身份范围?如果是,怎么办? 要获取角色值,是否需要在“api1”用户声明的 APIScopes 中添加为“地址,角色”可以通过上述 Q1 完成? 在策略“AdminUser”中,我通过将“api1”(APIScopes)用户声明添加为“地址、角色”来检查角色,但我无法访问 GetAdminMessage()。如何做到这一点?

【问题讨论】:

【参考方案1】:

.Net Core API 中是否可以访问身份范围?如果是,怎么办?

IdentityResources 中的声明进入 ID-Token。当您登录客户端 (AddOpenIDConnect) 时,ID-Token 的内容被“转换”为 ClaimsPrincipal User 对象。之后不使用 ID-token。

要获取角色值,我是否需要在“api1”用户声明的 APIScopes 中添加“地址、角色”或可以通过上述 Q1 来完成?

APIScopes 在 API 端。 API 接收访问令牌,它包含来自 ApiSCopes 和 ApiResources 的用户声明。 access-token 中的声明被转换为 API 中的用户对象(使用 AddJwtBearer),您可以使用 AddPolicy 系统对用户进行授权。

在策略“AdminUser”中,我通过将“api1”(APIScopes)用户声明添加为“地址、角色”来检查角色,但我无法访问 GetAdminMessage()。如何做到这一点?

ASP.NET Core 和 IdentityServer 对声明类型(名称)应该是什么有不同的看法,因此您需要通过以下方式告诉 AddJwtBearer 您的角色声明的真实名称是什么:

    .AddJwtBearer(opt =>
    
        ...
        opt.TokenValidationParameters.RoleClaimType = "roles";
        opt.TokenValidationParameters.NameClaimType = "name";

您也可以在 ConfigureServices 方法的顶部添加它:

public void ConfigureServices(IServiceCollection services)

    // By default, Microsoft has some legacy claim mapping that converts
    // standard JWT claims into proprietary ones. This removes those mappings.
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

如果还是不行,你也可以试试添加:

options.ClaimActions.MapUniqueJsonKey("role", "role");

【讨论】:

但它不工作 services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddJwtBearer("Bearer", opt => opt.TokenValidationParameters.RoleClaimType = "roles"; opt.TokenValidationParameters.NameClaimType = JwtClaimTypes.Name; //opt.TokenValidationParameters.NameClaimType = JwtClaimTypes.Scope; 在访问令牌中角色是现有的 "role": "admin", 你在这里写角色 opt.TokenValidationParameters.RoleClaimType = "roles";你也写现有的 "role": "admin", ?角色或角色? APIResource "testapi" 有 Scopes "api1" 和 userclaims 作为 "role, name" 我改变了 roleClaimType = role 但没有工作。 Services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddJwtBearer("Bearer", opt => opt.TokenValidationParameters.RoleClaimType = "role"; opt.TokenValidationParameters.NameClaimType = JwtClaimTypes.Name; 排除故障的第 1 步是使用 jwt.io 网站检查访问令牌中的实际内容。第 2 步是检查您的 ClaimPrincipal 用户对象中实际包含的声明... . 随意将其发布到您的问题中 在我的上一条评论中,我已经提到访问令牌具有 "role": "admin", (cheked using jwt.io) 。如何检查 ClaimPrincipal 用户对象中的对象。我正在通过return Ok( new JsonResult(from c in User.Claims select new c.Type, c.Value )); 打印用户calims,结果为Type: "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Value: "admin"

以上是关于如何使用 Identityserver4 添加/检查策略和角色 .net 核心 API 保护的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IdentityServer4 中添加自定义声明以访问令牌? [关闭]

如何使用 Identityserver4 添加/检查策略和角色 .net 核心 API 保护

IdentityServer 4,如何添加自定义登录页面

IdentityServer4 使用OpenID Connect添加用户身份验证

如何通过 IdentityServer4 将 OpenId Connect 添加到 ASP.NET Core 服务器端 Blazor Web 应用程序?

IdentityServer4 Ws 联合声明