Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用
一、前言
上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权流程及refreshtoken。
系列文章目录(没看过的先看这几篇文章再来阅读本文章):
- Asp.Net Core IdentityServer4 中的基本概念
- Asp.Net Core 中IdentityServer4 授权中心之应用实战
- Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式
为了继续保持IdentityServer4 系列博客分享上下文一致,我这里再把上回授权中心拆分后的图贴出来,如图:

图中的授权中心就是通过IdentityServer4实现的授权服务中心,我下面就直接用授权中心代替IdentityServer4的授权服务来继续述说,也感谢大家对我的支持,一直阅读我的文章。
二、授权流程
2.1 客户端验证流程图

流程图中,客户端仅仅会到授权中心 请求一次,并拿到验证公钥返回给Api资源拥有端,后面客户端再次尝试请求Api资源时候就不会再到授权中心去获取验证公钥,会直接用之前获取到的公钥进行验证,验证通过则授权通过。
2.2 授权及刷新refresh_token 流程图
然而通过授权中心 获取到的access_token 是有有效时间的,如果失效则需要通过refresh_token 重新到授权中心去刷新获取最新的access_token,整体的流程图如下:

客户端携带上一次获取到的access_token 请求受保护的Api资源时,通过公钥进行验证时发现access_token已经过期,则客户端再携带refresh_token 向授权中心再次发起请求,刷新access_token以获得最新的access_token和refresh_token,用最新的access_token 去获取受保护的Api资源,这样可以减少客户端多次跳转登录授权页面,提高用户体验。
三、应用实战
说到例子,我这里不从零开始撸代码, 还是在之前的代码基础上继续改造代码,在原有的定义客户端的代码中新增刷新access_token的相关配置,代码如下:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client()
{
ClientId =OAuthConfig.UserApi.ClientId,
AllowedGrantTypes = new List<string>()
{
GrantTypes.ResourceOwnerPassword.FirstOrDefault(),//Resource Owner Password模式
GrantTypeConstants.ResourceWeixinOpen,
},
ClientSecrets = {new Secret(OAuthConfig.UserApi.Secret.Sha256()) },
AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true
AllowedScopes= {
OAuthConfig.UserApi.ApiName,
StandardScopes.OfflineAccess,
},
AccessTokenLifetime = OAuthConfig.ExpireIn,
},
};
}
如果你需要刷新access_token,则需要把AllowOfflineAccess设置true,同时添加StandardScopes.OfflineAccess 这个Scopes,主要代码如下:
AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true
AllowedScopes= {
OAuthConfig.UserApi.ApiName,
StandardScopes.OfflineAccess,//如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess
},
授权中心,完整代码如下:
OAuthMemoryData 代码如下:
/// <summary>
///
/// </summary>
public class OAuthMemoryData
{
/// <summary>
/// 资源
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource(OAuthConfig.UserApi.ApiName,OAuthConfig.UserApi.ApiName),
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client()
{
ClientId =OAuthConfig.UserApi.ClientId,
AllowedGrantTypes = new List<string>()
{
GrantTypes.ResourceOwnerPassword.FirstOrDefault(),//Resource Owner Password模式
GrantTypeConstants.ResourceWeixinOpen,
},
ClientSecrets = {new Secret(OAuthConfig.UserApi.Secret.Sha256()) },
AllowOfflineAccess = true,//如果要获取refresh_tokens ,必须把AllowOfflineAccess设置为true
AllowedScopes= {
OAuthConfig.UserApi.ApiName,
StandardScopes.OfflineAccess,
},
AccessTokenLifetime = OAuthConfig.ExpireIn,
},
};
}
/// <summary>
/// 测试的账号和密码
/// </summary>
/// <returns></returns>
public static List<TestUser> GetTestUsers()
{
return new List<TestUser>
{
new TestUser()
{
SubjectId = "1",
Username = "test",
Password = "123456"
},
};
}
/// <summary>
/// 微信openId 的测试用户
/// </summary>
/// <returns></returns>
public static List<TestUser> GetWeiXinOpenIdTestUsers()
{
return new List<TestUser>
{
new TestUser(){
SubjectId="owerhwroogs3902openId",
}
};
}
}
Startup 完整代码如下:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
#region 内存方式
//services.AddIdentityServer()
// .AddDeveloperSigningCredential()
// .AddInMemoryApiResources(OAuthMemoryData.GetApiResources())
// .AddInMemoryClients(OAuthMemoryData.GetClients())
// .AddTestUsers(OAuthMemoryData.GetTestUsers());
#endregion
#region 数据库存储方式
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(OAuthMemoryData.GetApiResources())
//.AddInMemoryClients(OAuthMemoryData.GetClients())
.AddClientStore<ClientStore>()
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
.AddExtensionGrantValidator<WeiXinOpenGrantValidator>();//添加微信端自定义方式的验证
#endregion
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
授权中心代码基本上已经改造完成,我们用postman 访问授权中心 试一试,如下图:

访问结果中已经包含了refresh_token和access_token等相关信息。
我们再来通过access_token 访问Api资源(上两篇有相关代码,未阅读上两篇先去查阅)这里我就直接携带access_token去访问,如图:

访问成功!!
我们再来刷新下refresh_token ,访问如图:

刷新refresh_token成功。
我们到这里再来做一个小小的测试,测试上面的授权流程中的,第4,5 步,上面说到第4步主要是客户端第一次请求Api资源时会向ids4服务网关去请求获取验证公钥,
获取成功返回给Api资源并存储在内存中,后续不再会到ids4服务去获取验证公钥
我们把上面的授权中心 (ids4服务网关)停止运行,再来用之前的access_token请求Api资源,如下图:

现在已经确定授权中心(ids4服务网关)确实停止了,不能访问了,那我们再来通过之前未过期的access_token来请求Api资源网关,结果如下图:

完美,请求还是成功,这完全证明:客户端请求Api资源网关(受保护的资源)时,第一次收到请求会到授权中心(ids4服务网关)获取验证公钥,并保持到内存中,后面的请求不会再到授权中心去获得验证公钥,而是Api资源网关(受保护的资源)中直接通过保存下来的验证公钥进行验证,从而通过授权。
Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用的更多相关文章
- Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式
一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...
- Asp.Net Core 中IdentityServer4 授权中心之应用实战
一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...
- Asp.Net Core 中IdentityServer4 实战之角色授权详解
一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...
- Asp.Net Core 中IdentityServer4 实战之 Claim详解
一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...
- ASP.NET Core 中jwt授权认证的流程原理
目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...
- 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权
OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...
- 聊聊 asp.net core 认证和授权
使用asp.net core 开发应用系统过程中,基本上都会涉及到用户身份的认证,及授权访问控制,因此了解认证和授权流程也相当重要,下面通过分析asp.net core 框架中的认证和授权的源码来分析 ...
- ASP.NET Core 认证与授权[5]:初识授权
经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...
- ASP.NET Core 认证与授权[6]:授权策略是怎么执行的?
在上一章中,详细介绍了 ASP.NET Core 中的授权策略,在需要授权时,只需要在对应的Controler或者Action上面打上[Authorize]特性,并指定要执行的策略名称即可,但是,授权 ...
随机推荐
- but for|lest,in case和for fear (that)|confidential|item|adapted for|fee|debates| retain|substantial|proceeded to|refrain from|clear|perceive
He ________ you if you ________ to see him that afternoon. A. might tell, were going B. told, were ...
- undefined reference to 问题汇总及解决方法 ----- 还有一种问题没有解决(可能是顺序问题)
1.链接时缺失了相关的目标文件 2.链接时缺少了相关的库文件 3.链接的库文件中有使用了另一个库文件 4.多个库文件链接顺序问题 5.定义与实现不一致 6.在c++代码中链接C语言的库 转载地址: ...
- PHP生成word文档的三种实现方式
PHP生成word原理 利用windows下面的 com组件 利用PHP将内容写入doc文件之中 具体实现: 利用windows下面的 com组件 原理:com作为PHP的一个扩展类,安装过offic ...
- The Process class relies on proc_open, which is not available on your PHP installation报错解决
同事laravel框架开发的代码有如下错误日志 production.ERROR: The Process class relies on proc_open, which is not availa ...
- mysql关系型数据库
参考:https://www.cnblogs.com/alex3714/articles/5950372.html 关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数 ...
- Bootstrap插件及其应用方法网址
全局CCS样式 https://v3.bootcss.com/css/#type-lists 组件 https://v3.bootcss.com/components/#pagination Boot ...
- C++银行储蓄程序代码
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 浅析TCP/IP协议
浅析TCP/IP协议 0x00 什么是TCP/IP协议? 想一想人与人之间交流需要什么?我们是不是要掌握一种我们都能体会到对方意思的语言.那么计算机与网络设备之间进行通信,是不是不同设备之间是不是 ...
- tab 切换下划线跟随实现
HTML 结构如下: <ul> <li class="active">不可思议的CSS</li> <li>导航栏</li> ...
- localstorage浏览器储存
需求 a.html页面生成订单信息,b.html中调用. 通过不操作数据库,直接在浏览器自带的数据库中进行操作,当然主要是对Json数据的操作. a.html代码部分: <!--html--&g ...