asp.net core 使用identityServer4的密码模式来进行身份认证(一
原文:
asp.net core 使用identityServer4的密码模式来进行身份认证(一)
IdentityServer4是ASP.NET Core的一个包含OpenID和OAuth 2.0协议的框架。具体Oauth 2.0和openId请百度。 前言本博文适用于前后端分离或者为移动产品来后端api的身份认证功能。 一 首先第一步使用Nuge包管理器下载IdentityServer4的包。 第二部,添加一个名叫Config的类。 这个类的作用是对一些api和client进行配置的。 public static IEnumerable<IdentityResource> GetIdentityResource() { return new List<IdentityResource> { new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Email() }; } public static IEnumerable<ApiResource> GetApiResource() { return new List<ApiResource> { new ApiResource("gateway_api","gateway service"),new ApiResource("user_api","user_api service"),//并且要把contactapi加入到apiResource,并加入到 client的allowedScopes中 // new ApiResource("contact_api","contact_api service") }; } public static IEnumerable<Client> GetClients() { return new List<Client>() { new Client { ClientId="pc",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,//这里是指定授权的模式,选择密码模式, ClientSecrets = { new Secret("yemobai".Sha256()) },RefreshTokenUsage=TokenUsage.ReUse,AlwaysIncludeUserClaimsInIdToken = true,AllowOfflineAccess = true,AllowedScopes=new List<string> { "user_api",IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.OfflineAccess } } }; } 第三步 添加start up的配置 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResource()) .AddInMemoryIdentityResources(Config.GetIdentityResource()) .AddInMemoryClients(Config.GetClients()) .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>() .AddProfileService<ProfileService>() .AddCorsPolicyService<CorsPolicyService>() //这是IdentityServer跨域的,我尝试开启asp.net core 的跨域,但是identityServer不接受请求。 ; public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseIdentityServer(); //启用identityServer中间件 app.UseCors(buider => { buider.WithOrigins("http://localhost:8080") .AllowAnyHeader(); }); app.UseMvc(); } ? 第四步 用户验证 其实identityServier4也提供了一些测试用户来进行身份认证的实验,这些东西都在identityServer4的官网上都有介绍。 新建一个类ResourceOwnerPasswordValidator继承与IResourceOwnerPasswordValidator接口(IResourceOwnerPasswordValidator是Identityserver4提供的一个接口其主要工作就是验证我们的用户名和密码)。 这个接口只有一个方法 public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) 怎么获取我们传过来的用户名和密码呢? 答:在方法的参数context中,按F12进入到ResourceOwnerPasswordValidationContext这个类的定义中,具体定义的属性如下 // // 摘要: // Class describing the resource owner password validation context public class ResourceOwnerPasswordValidationContext { public ResourceOwnerPasswordValidationContext(); // // 摘要: // Gets or sets the name of the user. public string UserName { get; set; } // // 摘要: // Gets or sets the password. public string Password { get; set; } // // 摘要: // Gets or sets the request. public ValidatedTokenRequest Request { get; set; } // // 摘要: // Gets or sets the result. public GrantValidationResult Result { get; set; } } 可以看到 userName和passWord都已经定义好了,我们只管用就行了。 context.UserName,context.Password 就算用户名和密码和我的数据库的数据对上了,该怎么返回我对用户名和密码的认证结果呢? 答: 如果你是一个细心的人,你会发现上面?ValidateAsync这个方法返回一个Task,可以基本上认为无返回值了。不要着急,看看ResourceOwnerPasswordValidationContext这个类的定义。 GrantValidationResult Result { get; set; } 里面有这么一个属性。看名字都知道是验证结果了。不出意外,我们对用户名和密码的验证接口应该放在这个里面。 那下面就很简单了。 if (accountResult.Status=="登陆成功") { context.Result= new GrantValidationResult(accountResult.User.Id.ToString(),"admin",GetUserClaim(accountResult.User)); } else { //验证失败 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,"密码错误"); } 具体的构造函数重载,请自己看。如果有需求的不要忘了,把claim给加上。怎么 加claim呢, 最简单的方式你数据库验证用户名和密码完后,把一些claim给带上。 向我这样 public Claim[] GetUserClaim(UserInfo userInfo) { var claims = new Claim[] { new Claim("USERID",userInfo.UserId),new Claim("USERNAME",userInfo.UserName) }; return claims; } 完整代码 public class ResourceOwnerPasswordValidator: IResourceOwnerPasswordValidator { private readonly IAccountService accountService; public ResourceOwnerPasswordValidator(IAccountService _accountService) { accountService = _accountService; } public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var accountResult = await accountService.SignInAsync(context.UserName,context.Password); if (accountResult.Status=="登陆成功") { context.Result= new GrantValidationResult(accountResult.User.Id.ToString(),"密码错误"); } } public Claim[] GetUserClaim(UserInfo userInfo) { var claims = new Claim[] { new Claim("USERID",userInfo.UserName) }; return claims; } 测试结果。 是用postmen来进行测试。没有的话请自行下载。 忘了说了,把IdentityServer4的包下载下来后 ,运行项目浏览器输入http://localhost:5000/.well-known/openid-configuration ? 看看identiyServer4一些接口地址。 ? 然后在在postMen中输入一下Key和value(不要把我的给抄了上去) scope写不写无所谓,如果你写的了话必须在config类中 public static IEnumerable<ApiResource> GetApiResource() { return new List<ApiResource> { new ApiResource("gateway_api","contact_api service") }; } 在这个方法中添加上。而且也要在 public static IEnumerable<Client> GetClients() { return new List<Client>() { new Client { ClientId="pc",ClientSecrets = { new Secret("yemobai".Sha256()) },IdentityServerConstants.StandardScopes.OfflineAccess } } }; 而且也要在?AllowedScopes里面给加上。 ? 结果 ? ?这个时候我们就拿到了access_token和过期时间和refresh_token, 就用了IdentityServer4搞了一个access_token出来。算什么身份认证? 答:下一节解释。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp-classic – 从fso对象创建ado记录集
- asp.net – 与IIS7的ASP MVC路由问题
- ASP.Net控件是否通过viewstate公开SQL查询?
- asp.net – Microsoft Report Viewer 2010部署
- asp.net-mvc – ASP.Net MVC – 处理不好的URL参数
- Asp.net初识
- asp.net-mvc – 为什么在我的ASP MVC4应用程序中重定向资源
- asp.net-mvc-3 – MVC3中的模型级错误?
- asp.net-mvc – 使用NHibernate.AspNet.Identity
- .net – Nuget包,没有nuget包管理器?