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的密码模式来进行身份认证(一)的更多相关文章
- asp.net core 使用identityServer4的密码模式来进行身份认证(2) 认证授权原理
前言:本文将会结合asp.net core 认证源码来分析起认证的原理与流程.asp.net core版本2.2 对于大部分使用asp.net core开发的人来说. 下面这几行代码应该很熟悉了. s ...
- Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式
一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...
- Asp.Net Core 中IdentityServer4 授权中心之应用实战
一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...
- Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用
一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...
- Asp.Net Core 中IdentityServer4 实战之 Claim详解
一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...
- Asp.Net Core 中IdentityServer4 实战之角色授权详解
一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...
- ASP.NET Core路由中间件[2]: 路由模式
一个Web应用本质上体现为一组终结点的集合.终结点则体现为一个暴露在网络中可供外界采用HTTP协议调用的服务,路由的作用就是建立一个请求URL模式与对应终结点之间的映射关系.借助这个映射关系,客户端可 ...
- 【.NET Core】ASP.NET Core之IdentityServer4(1):快速入门
[.NET Core]ASP.NET Core之IdentityServer4 本文中的IdentityServer4基于上节的jenkins 进行docker自动化部署. 使用了MariaDB,EF ...
- 避免在ASP.NET Core中使用服务定位器模式
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:服务定位器(Service Locator)作为一种反模式,一般情况下应该避免使用,在 ...
随机推荐
- Jmeter元件作用域
转载自飞测团队
- Java SE-基本数据类型对应包装类
包装类 Java是面向对象的编程语言,包装类的出现更好的体现这一思想. 其次,包装类作为类是有属性有方法的,功能比基本数据类型要强大. [八种基本数据类型的包装类] byte ——Byte short ...
- 源码安装php时出现Sorry, I cannot run apxs. Possible reasons follow:
1.可能的原因是你没有安装perl > yum install perl > yum install httpd-devel 2.在你apache安装目录下的bin下找到apxs,并用vi ...
- linux下每次git clone不需输入账号密码的方法
在~/下, touch创建文件 .git-credentials, 用vim编辑此文件,输入内容格式: ame@zhenyun ~ $touch .git-credentials ame@zhenyu ...
- centos一键安装lnmp成功后无法访问ip(解决办法)
自己搞了个服务器 (我的服务器网络类型是 专有网络)如下图点击 配置规则 进入到 进.出端口规则配置 点击添加安全组规则 如图所配置 添加完成后 就如下面所示 (配置完成后 通过ip就已经可以访问了 ...
- MapReduce 计算模式
声明:本文摘录自<大数据日知录——架构与算法>一书. 较常见的计算模式有4类,实际应用中大部分ETL任务都可以归结为这些计算模式或者变体. 1.求和模式 a.数值求和 比如我们熟悉的单词计 ...
- Codeforces 681C. Heap Operations 优先队列
C. Heap Operations time limit per test:1 second memory limit per test:256 megabytes input:standard i ...
- ERR_UNSAFE_PORT
报错: 解决办法:
- WinScp获取一个文件
CD /d C:\Program Files (x86)\WinSCPWinSCP.exe /console /command "option batch continue" &q ...
- [Selenium]显式等待 Explicit wait & 隐式等待 Implicit wait
显式等待 Explicit wait 显示等待 , 就是明确的要等到某个元素出现或者某个元素满足某种条件,每隔一段时间检查一次,等不到,就一直等,如果在规定的时间内还没有找到,就跳出来检查间隔的时间和 ...