一、前言

上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权流程及refreshtoken。

系列文章目录(没看过的先看这几篇文章再来阅读本文章):

为了继续保持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的应用的更多相关文章

  1. Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

    一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...

  2. Asp.Net Core 中IdentityServer4 授权中心之应用实战

    一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...

  3. Asp.Net Core 中IdentityServer4 实战之角色授权详解

    一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...

  4. Asp.Net Core 中IdentityServer4 实战之 Claim详解

    一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...

  5. ASP.NET Core 中jwt授权认证的流程原理

    目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...

  6. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  7. 聊聊 asp.net core 认证和授权

    使用asp.net core 开发应用系统过程中,基本上都会涉及到用户身份的认证,及授权访问控制,因此了解认证和授权流程也相当重要,下面通过分析asp.net core 框架中的认证和授权的源码来分析 ...

  8. ASP.NET Core 认证与授权[5]:初识授权

    经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...

  9. ASP.NET Core 认证与授权[6]:授权策略是怎么执行的?

    在上一章中,详细介绍了 ASP.NET Core 中的授权策略,在需要授权时,只需要在对应的Controler或者Action上面打上[Authorize]特性,并指定要执行的策略名称即可,但是,授权 ...

随机推荐

  1. Jenkins+jmeter设置定时执行任务

    1.准备好你的jmeter脚本 2.测试命令行下脚本执行 1)cd进入脚本目录 2)dir命令查看该目录下的脚本文件 3)jmeter -n -t test.jmx -l result.jtl  命令 ...

  2. JAVA的堆栈和内存、垃圾回收解说

    1.有关java健壮性特点的真相 很多书上都说java健壮性的特点是因为java使用数组代替了c++的指针:c++最令人头痛的问题就是内存问题,java的健壮性使编程人员不用再考虑内存的问题:这种观点 ...

  3. 吴裕雄--天生自然python学习笔记:Python3 OS 文件/目录方法

    os 模块提供了非常丰富的方法用来处理文件和目录.常用的方法如下表所示: 序号 方法及描述 1 os.access(path, mode) 检验权限模式 2 os.chdir(path) 改变当前工作 ...

  4. estt

    1.路由控制的定义 1.1.IP地址与路由控制 互联网是由路由器连接的网络组合而成的.为了能让数据包正确地到达目标主机,路由器必须在途中进行正确地转发.这种向"正确的方法"转发数据 ...

  5. hibernate需要注意的点

    1.需要用Hibernate做实体的类(@Entity)需要在配置文件中配置对应的包(例如:spring/appContext-hibernate.xml). 2.hibernateTemplate中 ...

  6. 谁来破解公交WiFi的尴尬困局?

      在咖啡馆.饭店坐定,菜单可以待会再看,远远看见服务员迎上来,赶紧先问一句:"这里有无线网吗,密码是多少",和笔者一样养成类似习惯的人越来越多.所以,当公交WiFi"大 ...

  7. python标准库-calendar 模块

    原文地址:http://www.bugingcode.com/blog/python_calendar.html calendar 模块是python实现的unix 的 cal命令.它可以以标准的模式 ...

  8. Python---7函数(调用&定义函数)

    函数 Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs(),只有一个参数.可以直接从Python的官方网站查看文档: http: ...

  9. Web 项目刚要打包,却找不到项目资源?

    编程无小事,不管是语言层面还是工具层面,都要熟悉,方能在编程中过程中众享丝滑,不然就随处卡顿,耗费时间不说,还没有任何成就感.撸码过程中用 Idea 也很多年了,工具或环境遇到问题,问下度娘就完事了, ...

  10. C++走向远洋——23(项目一,三角形,类)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:sanjiaoxing.cpp * 作者:常轩 * 微信公众号: ...