IdentityServer4 Identity Resource中的user Claim

↘锁芯ラ 提交于 2020-02-07 01:46:24

 

Identity Resource

身份资源,里面的UserClaims是用户的一些属性,默认情况下,即使写再多的属性,token中也只会返回sub一个,我们需要在代码中加入

 var builder = services.AddIdentityServer()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.Apis)
                .AddInMemoryClients(Config.Clients)
             .AddTestUsers(TestUsers.Users)
            .AddProfileService<ProfileService>();
            // not recommended for production - you need to store your key material somewhere secure
            builder.AddDeveloperSigningCredential();

然后去实现IProfileService

 public class ProfileService : IProfileService
    {
        protected readonly TestUserStore Users;
        public ProfileService(TestUserStore users)
        {
            Users = users;
        }
        public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var user = Users.FindBySubjectId(context.Subject.GetSubjectId());
            if (user != null) {
                //context.IssuedClaims = user.Claims.ToList();
                context.IssuedClaims.AddRange(user.Claims);
            }
                
            return Task.CompletedTask;
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            context.IsActive = true;
        }
    }

这样就能将所有的claim返回在token中

有了包含claim的token可以去访问受保护的API,token中携带的不同的scope和Role,可以对同一个API server 中不同的API

进行不同的访问权限

在API在进行配置

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAuthorization(options =>
            {
                options.AddPolicy("fullaccess", policy =>
                                  policy.RequireClaim("scope", "api2.full_access"));
                options.AddPolicy("readonly", policy =>
                                  policy.RequireClaim("scope", "api2.read_only"));
            });
            services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "http://localhost:5000";
                  
                    options.RequireHttpsMetadata = false;
                    options.Audience = "api1";
                });
        }

这里的policy是为了对不同的scope访问不同的api做限制,在IDS服务上可以这样配置

 public static IEnumerable<ApiResource> Apis =>
             new List<ApiResource>
       {
            new ApiResource("api1", "My API"),
            new ApiResource
            {
                Name = "api2",

                Scopes =
                {
                    new Scope()
                    {
                        Name = "api2.full_access",
                        DisplayName = "Full access to API 2"
                    },
                    new Scope
                    {
                        Name = "api2.read_only",
                        DisplayName = "Read only access to API 2"
                    }
                }
            }
       };

API的Controller如下配置 

namespace Api
{
    [Route("identity")]
    [Authorize(Roles= "admin")]
   
    public class IdentityController : ControllerBase
    {
        [Authorize(Policy = "fullaccess")]
        [HttpGet]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
        }
        [Authorize(Policy = "readonly")]
        [HttpGet]
        [Route("get1")]
        public IActionResult Get1()
        {
            return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
        }
    }
}

[Authorize(Roles= "admin")]这样首先可以保证这个Controller只有admin才能访问

第一个API只有在token中scope为full_access的才能访问

第二个API只有在token中scope为read_only的才能访问

主要运用场景是给不同的客户端使用,但是客户端拿到token以后并不可以访问里面所有的API,做到相互隔离

参考:http://docs.identityserver.io/en/latest/topics/resources.html

https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/roles?view=aspnetcore-3.1

在Client中也有个Claims

 Claims = new List<Claim>
                {
                    new Claim(JwtClaimTypes.Role, "admin")
                }
官网描述:

但其实默认情况下不会包含在access_token中,官网如下描述:

所以需要设置下这两个参数,最后解析token后发现

自动加了client_,没想好这个的使用场景

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!