IdentityServer4 接入自己的用戶體系


IdentityServer4提供的demo 是用的自己的表結構,但是對於我們來說就不是很適用了,研究了下他的源碼發現他的密碼模式,大概就是更改下面幾個方法大,致就是讀取數據庫數據,與context.username ,password,進行比對,一致則通過,不一致就是失敗

 
          
 public class ProfileService : IProfileService {
        //services
        private IUserRepository _userRepository = new UserRepository();


        //build claims array from user data
        public static Claim[] GetUserClaims(User user)
        {
            var c = new Claim[] { };
            c[0] = new Claim("user_id", "465464");
            c[1] = new Claim("sub", "465464");            
            return c;
        }

        /// <summary>
        /// 每當請求有關用戶的聲明時(例如,在令牌創建期間或通過userinfo端點),都會調用此方法
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            try
            {
                //depending on the scope accessing the user data.
                if (!string.IsNullOrEmpty(context.Subject.Identity.Name))
                {
                    //get user from db (in my case this is by email)
                    var user = await _userRepository.FindAsync(45121);

                    if (user != null)
                    {
                         var claims = GetUserClaims(user);

                        //set issued claims to return
                        context.IssuedClaims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
                    }
                }
                else
                {
                    //get subject from context (this was set ResourceOwnerPasswordValidator.ValidateAsync),
                    //where and subject was set to my user id.
                    var userId = context.Subject.Claims.FirstOrDefault(x => x.Type == "sub");

                    if (!string.IsNullOrEmpty(userId?.Value) && long.Parse(userId.Value) > 0)
                    {
                        //get user from db (find user by user id)
                        var user = await _userRepository.FindAsync(long.Parse(userId.Value));

                        // issue the claims for the user
                        if (user != null)
                        {
                            var claims = ResourceOwnerPasswordValidator.GetUserClaims(user);

                            context.IssuedClaims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log your error
            }
        }

        //check if user account is active.
        public async Task IsActiveAsync(IsActiveContext context)
        {
            try
            {
                //get subject from context (set in ResourceOwnerPasswordValidator.ValidateAsync),
                var userId = context.Subject.Claims.FirstOrDefault(x => x.Type == "user_id");

                if (!string.IsNullOrEmpty(userId?.Value) && long.Parse(userId.Value) > 0)
                {
                    var user = await _userRepository.FindAsync(long.Parse(userId.Value));

                    if (user != null)
                    {
                        if (user.IsActive)
                        {
                            context.IsActive = user.IsActive;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //handle error logging
            }
        }
    }
 
          

  

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator {
        private IUserRepository _userRepository = new UserRepository();
        //build claims array from user data
        //build claims array from user data
        public static Claim[] GetUserClaims(User user)
        {
            var c = new Claim[] { };
            c[0] = new Claim("user_id", "465464");
            c[1] = new Claim("sub", "465464");
            return c;
        }
        //this is used to validate your user account with provided grant at /connect/token
        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            try
            {
                //get your user model from db (by username - in my case its email)
                var user = await _userRepository.FindAsync(1241);
                if (user != null)
                {
                    //check if password match - remember to hash password if stored as hash in db
                    if (true)
                    {
                        //set the result
                        context.Result = new GrantValidationResult(
                            subject: user.Id.ToString(),
                            authenticationMethod: "custom",
                            claims: GetUserClaims(user));

                        return;
                    }

                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Incorrect password");
                    return;
                }
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "User does not exist.");
                return;
            }
            catch (Exception ex)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Invalid username or password");
            }
        }
    }

  

 
         
1     //add identity server 4
2             services.AddIdentityServer()
3                    .AddInMemoryApiScopes(Config.GetApiScopes())
4                    .AddInMemoryApiResources(Config.GetApiResources())
5                    .AddInMemoryIdentityResources(Config.GetIdentityResources())
6                    .AddInMemoryClients(Config.GetClients())
7                    .AddDeveloperSigningCredential(persistKey: false)
8                    .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()//用戶校驗
9                 .AddProfileService<ProfileService>();
Startup 里面修改文件

 

 

參考資料:https://buildmedia.readthedocs.org/media/pdf/identityserver4/release/identityserver4.pdf

源碼地址:https://github.com/imfrank/Galaxy.IdentityServer

 


免責聲明!

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



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