zoukankan      html  css  js  c++  java
  • .net core 基于AspNetCore.Identity+Identityserver4用户的权限管理

    一般权限控制,是先给角色分配对应权限,然后再给用户分配角色;总权限应该是在代码编写的时候就已经固定了,例如有个用户更新的接口,这里就会诞生一个用户更新的权限,接口在权限就在,没有接口也就没有了这个权限;

    所以总权限我是维护在代码中静态常量,在AuthorizeAttribute中设置权限也是要常量;

    使用原生AuthorizeAttribute的Policy和用户的Claim(有userClaim和roleClaim),userClaim和roleClaim是AspNetCore.Identity的表,保存用户的声明信息和角色声明信息,也就是可以在roleClaim中保存角色的权限;

    用户登录后获取token,token经过ProfileService处理,带有用户的权限Claim,用户请求需要权限的接口时,会检查token中有没有这个权限要求的Claim;

    分为两个服务,一个Identityserver4服务,一个UserAPI服务;

    Identityserver4服务

    ConfigureServices

    string mysqlConnectionStrings = $"Data Source={Host};port={Port};Initial Catalog={Database};user id={UserID};password={Password};";
    services.AddDbContext<ApplicationDbContext>(options =>
    options.UseMySql(mysqlConnectionStrings));
    
    services.AddIdentity<ApplicationUser, ApplicationRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
    
    var builder = services.AddIdentityServer()
    .AddInMemoryIdentityResources(Config.Ids)
    .AddInMemoryApiResources(Config.Apis)
    .AddInMemoryClients(Config.Clients(Configuration))
    .AddAspNetIdentity<ApplicationUser>()
    //.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
    .AddProfileService<ProfileService>();
    // not recommended for production - you need to store your key material somewhere secure
    builder.AddDeveloperSigningCredential();
    需要注意ProfileService,这里返回token中Claim,去数据库获取用户的Claim
            /// <summary>
            /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)
            /// 
            /// </summary>
            /// <param name="context">The context.</param>
            /// <returns></returns>
            public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)
            {
                var sub = context.Subject?.GetSubjectId();
                //context.Subject.Claims  为登录设置的Claims,此处直接用数据库中的claims,忽略context.Subject.Claims
                if (sub == null) throw new Exception("No sub claim present");
    
                var user = await _userServer.FindByIdAsync(sub);
                if (user == null)
                {
                    Logger?.LogWarning("No user found matching subject Id: {0}", sub);
                }
                else
                {
              //获取用户的权限
    var userPermissions = await _rolePermissionServer.GetUserPermissions(user.Id); List<Claim> claims = new List<Claim>(); claims = userPermissions.Select(a => new Claim("UserPermission", a.NormalizedName)).ToList(); claims.Add(new Claim("username", user.UserName)); claims.Add(new Claim("name", user.Name)); context.IssuedClaims = claims; } }

    UserAPI服务

    UserApi服务除了正常的配置Identityserver4服务以外,还需要添加认证需要的Policy,因为权限都需要认证,所以我把所有的权限都加进去;

          
            //获取所有的权限列表
            var
    permissionsList = PermissionNames.GetPermissionsList(); //设置Authorize的policy,可以添加多个 services.AddAuthorization(options => { foreach (var item in permissionsList) { options.AddPolicy(item.NormalizedName, policyAdmin => { policyAdmin.RequireClaim("UserPermission", item.NormalizedName); }); } });

    下面两个中间件也不能忘记

    app.UseAuthentication();
    app.UseAuthorization();

    接下来是Controller部分

            [HttpGet]
            [Route("manage")]
            [Authorize(PermissionNames.UserManage_list)]
            public async Task<PageBase<UserListItemDto>> UserManageList([FromQuery]UserListRequestDto request)
            {
                return await _userServer.UserManageList(request);
            }
            [HttpGet]
            [Route("manage/{id}")]
            [Authorize(PermissionNames.UserManage_detail)]
            public async Task<UserDetailDto> UserManageDetail(int id)
            {
                return await _userServer.UserManageDetail(id);
            }
            [HttpPut]
            [Route("manage")]
            [Authorize(PermissionNames.UserManage_update)]
            public async Task<bool> UserManageUpdate(UserEditDto  userEditDto)
            {
                return await _userServer.UserManageUpdate(UserId, userEditDto);
            }
            [HttpDelete]
            [Route("manage/{id}")]
            [Authorize(PermissionNames.UserManage_delete)]
            public async Task<bool> UserManageDelete(int id)
            {
                return await _userServer.UserManageDelete(UserId, id);
            }

    具体代码,还有更多内容学习:https://github.com/zhanghm1/DiuDiuTemplate

  • 相关阅读:
    ArrayList的几种初始化方法
    Java中date和calendar的用法
    Android中XML的命名空间、自定义属性
    Android中shape属性详解
    五分钟学GIS | 快速生成地图瓦片秘籍
    adb 提示adb server version(31) doesn't match this client(40) 解决办法
    mysql @value := 用法
    Mysql中(@i:=@i+1)的作用
    $.ajax()方法详解
    最少代码实现购物车所有功能
  • 原文地址:https://www.cnblogs.com/zhanghm1/p/12894042.html
Copyright © 2011-2022 走看看