.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM