IdentityServer4 接入自己的用户体系

2021-11-04  本文已影响0人  wwmin_

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

上一篇 下一篇

猜你喜欢

热点阅读