美文网首页
IdentityServer4 接入自己的用户体系

IdentityServer4 接入自己的用户体系

作者: wwmin_ | 来源:发表于2021-11-04 18:31 被阅读0次

    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");
                }
            }
        }
    
         //add identity server 4
                 services.AddIdentityServer()
                       .AddInMemoryApiScopes(Config.GetApiScopes())
                        .AddInMemoryApiResources(Config.GetApiResources())
                       .AddInMemoryIdentityResources(Config.GetIdentityResources())
                        .AddInMemoryClients(Config.GetClients())
                        .AddDeveloperSigningCredential(persistKey: false)
                        .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()//用户校验
                    .AddProfileService<ProfileService>();
    
    image.png

    参考资料:https://buildmedia.readthedocs.org/media/pdf/identityserver4/release/identityserver4.pdf

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

    相关文章

      网友评论

          本文标题:IdentityServer4 接入自己的用户体系

          本文链接:https://www.haomeiwen.com/subject/caicgltx.html