为了验证密码授权模式信息,这里需要往数据库插入测试的用户数据,插入脚本如下。
--密码123456 MD5加密结果 INSERT INTO CzarUsers VALUES('13888888888','E10ADC3949BA59ABBE56E057F20F883E','金焰的世界','13888888888','541869544@qq.com',1); 四、测试密码授权模式注意:测试密码授权模式之前,我们需要对测试的客户端ClientGrantTypes表添加password授权方式。
打开我们的测试神器Postman,然后开始调试密码授权模式,测试结果如下图所示。
是不是很完美,得到了我们想要的授权结果,那我们查看下这个access_token是什么信息,可以使用https://jwt.io/查看到详细的内容,发现除了客户端信息和用户主键无其他附加信息,那如何添加自定义的Claim信息呢?
先修改下CzarUsers实体,增加如下代码,如果有其他属性可自行扩展。
public List<Claim> Claims { get { return new List<Claim>() { new Claim("nickname",uNickName??""), new Claim("email",uEmail??""), new Claim("mobile",uMobile??"") }; } }再修改校验方法,增加Claim输出,CzarResourceOwnerPasswordValidator修改代码如下。
/// <summary> /// 验证用户身份 /// </summary> /// <param></param> /// <returns></returns> public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var user = _czarUsersServices.FindUserByuAccount(context.UserName, context.Password); if (user != null) { context.Result = new GrantValidationResult( user.Uid.ToString(), OidcConstants.AuthenticationMethods.Password, DateTime.UtcNow, user.Claims); } return Task.CompletedTask; }然后需要把用户的claims应用到Token,这里我们需要重写IProfileService,然后把用户的claim输出,实现代码如下。
public class CzarProfileService : IProfileService { public Task GetProfileDataAsync(ProfileDataRequestContext context) { //把用户返回的Claims应用到返回 context.IssuedClaims = context.Subject.Claims.ToList(); return Task.CompletedTask; } /// <summary> /// 验证用户是否有效 /// </summary> /// <param></param> /// <returns></returns> public Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; return Task.CompletedTask; } }然后别忘了注入.AddProfileService<CzarProfileService>(),好了现在我们再次测试下授权,最终得到的结果如下所示。
奈斯,得到了我们预期授权结果。
那如何获取refresh_token呢?通过前面的介绍,我们需要增加scope为offline_access,并且需要设置客户端支持,因此AllowOfflineAccess属性需要设置为True,现在来测试下获取的授权结果。
最终完成了refresh_token的获取,至此整个密码授权模式全部讲解并实现完成。
五、总结及思考本篇文章我们从密码授权模式使用场景、源码剖析、自定义用户授权来讲解了密码授权模式的详细思路和代码实现,从中不难发现Ids4设计的巧妙,在默认实现的同时也预留了很多自定义扩展,本篇的自定义用户体系也是重新实现接口然后注入就完成集成工作。本篇主要难点就是要理解Ids4的实现思路和数据库的相关配置,希望通过本篇的讲解让我们熟练掌握密码验证的流程,便于应用到实际生产环境。
上篇的客户端授权模式和本篇的密码授权模式都讲解完可能有人会存在以下几个疑问。
1、如何校验令牌信息的有效性?
2、如何强制有效令牌过期?
3、如何实现单机登录?
下篇文章我将会从这3个疑问出发,来详细讲解下这三个问题的实现思路和代码。