分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

asp.net core 使用identityServer4的密码模式来进行身份认证(一)

发布时间:2023-09-06 02:35责任编辑:熊小新关键词:暂无标签
原文: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(), "admin", GetUserClaim(accountResult.User)); ???????????} ??????????????????????else ???????????{ ???????????????//验证失败 ???????????????context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "密码错误"); ???????????} ???????} ???????public Claim[] GetUserClaim(UserInfo userInfo) ???????{ ???????????????????????var claims = new Claim[] { new Claim("USERID", userInfo.UserId), new Claim("USERNAME", 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","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 ???????????????????} ?????????????} ?????????};

而且也要在 AllowedScopes里面给加上。

结果

 这个时候我们就拿到了access_token和过期时间和refresh_token,

就用了IdentityServer4搞了一个access_token出来。算什么身份认证?

答:下一节解释。

asp.net core 使用identityServer4的密码模式来进行身份认证(一)

原文地址:https://www.cnblogs.com/lonelyxmas/p/10527605.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved