IdentityServer4之Authorization Code(授权码)相对更安全
前言
接着授权模式聊,这次说说Authorization Code(授权码)模式,熟悉的微博接入、微信接入、QQ接入都是这种方式(这里说的是oauth2.0的授权码模式),从用户体验上来看,交互方式和Implicit没啥改变,随便找个网站瞅瞅,如慕课网(很不错的学习网站)的登录流程,见下图:

但其实在代码流程上是不太一样的,接下来边撸(我说的是敲代码)边聊。
正文
Authorization Code(授权码)模式比Implicit多了一个授权码的流程,即用户认证成功之后,授权服务器不会马上返回AccessToken,而是先返回一个code(这里称为授权码),然后客户端通过code再去获取Token,主要流程大概如下图:

流程说明:
- 用户通过浏览器(User-Agent)访问第三方客户端(Client);
- 如果客户端需要进行认证授权,则将其重定向到认证服务器(Authorization server);
- 用户(ResorceOwner)在认证服务器上进行认证;
- 认证服务器(Authorization server)验证成功之后,返回code(授权码);
- 客户端带上code(授权码)再去授权服务器请求获取AccessToken/IdToken;
- 授权服务器验证code(授权码)的有效性,验证成功后返回Token;
- 后续用户再操作客户端的时候,若需访问保护资源,直接在请求中带上AccessToken即可;
- 最终资源服务器(Resource server)返回对应信息;
术语解释:
- code(授权码):授权服务器认证成功之后返回的code,这个code有时效性,而且只能使用一次。
通过上面的流程,Authorization Code(授权码)模式其实更适合有后台的客户端,比如MVC程序,接收code和通过code获取Token的过程都在客户端后台进行,用户无感知;再加上code(授权码)的时效和次数限制,相对来说,这种模式是比较安全的。IdentityServer4已经封装好,所以撸码很简单,继续搞起来↓↓↓
1. 授权服务器和资源服务器代码先从上一节中拷贝过来;
对于资源服务器,还是不需要改动;
对于授权服务器,加个客户端完事;

2. 创建一个MVC客户端,引入相关包并配置OpenID Connect;
2.1 创建一个MVC项目,并引入对应的包,项目结构如下:

2.2 在Startup.cs文件中配置增加认证授权相关配置:
ConfigureServices方法中添加如下代码:

注,在访问API的时候,还需要加入:options.Scope.Add("orderApi"); 这个scope在授权服务器已经定义过的,之前的案例也有说到。
Configure方法中添加如下代码:

2.3 将客户端中Controller都增加[Authorize],表示将其保护起来,如果没有通过认证授权,就不能访问;

这样HomeController中的所有Action都保护起来了,如果需要访问,就需要先到授权服务器上进行认证授权。
3. 先跑起来看看效果,如果不出意外,应该没问题;
哦豁!翻车了

当在授权服务器认证授权完成之后,理当正常跳转到客户端(这里用到的是谷歌浏览器,版本为8x),但是偏偏某有,报了一个很莫名其妙的错,如下:

但通过吸取上一节Implicit的经验,初步认为是Cookies没在谷歌浏览器中写入成功,于是就换了360浏览器试了试,没毛病,一切如行云流水一般,正常跳转,原来是如下Cookie没有成功写入,所以找不到,在控制台的时候也有警告提示,没有找到Cookies;

MVC客户端控制台的提示:

解决措施
这是由于新版浏览器对Cookie策略的整改,而谷歌优先进行推广,所以测试总是在谷歌浏览器出问题;和上一节授权处理器的方式一样,如下:
在客户端中新增一个处理类:SameSiteCookiesServiceCollectionExtensions.cs,代码内容就不贴啦(git仓库里有),这是公开代码,大佬写好的解决方案;
写好处理类之后,直接使用即可,如下:

完成以上步骤,问题就解决啦;再去测试一把,果然没有问题;
注: 如果MVC客户端为Https的话就不会出现以上问题;这和SameSite的三种模式有关:Strict,Lax,None.这里留个小伙伴自己去扩充吧。
4. 在客户端中获取Claims信息及调用受保护的API资源;
先在导航菜单中增加获取Claims和调用API的按钮,因为用到的是MVC布局页,直接在_Layout.cshtml中复制粘贴就完事,如下:

4.1 获取Claims信息,代码如下:
根据导航菜单的配置,在HomeController中增加一个UserInfo的Action,并根据Action新增对应的视图文件UserInfo.csthml:

运行(启动授权服务->启动客户端),点击导航菜单UserInfo,如下:

4.2调用API(受保护资源)
在HomeController中增加一个CallAPI的Action,并根据Action新增对应的视图文件CallAPI.csthml,代码如下:

运行(启动授权服务->启动API资源服务->启动客户端),点击CallAPI菜单,如下:

到这Authorization Code(授权码)模式的简单使用就差不多啦,后续的内部业务鉴权在后续的实战项目中会说到; 细节流程留给小伙伴一步一步调试吧。
源码地址:https://github.com/zyq025/IDS4Demo/tree/main/AuthorizationCode。
总结
在编写测试Demo的时候,会出现很多细节的问题,所以建议小伙伴多敲敲代码,不要复制的那种;另外还需要注意新版本浏览器对Cookies的限制,可能导致一些莫名其妙的错误,上文中有已经处理;关于Cookies的规则,大家可以找找资料瞅瞅。目前所有的案例都是基于内存存储数据,在实际项目中肯定是需要将信息持久化的,所以下一篇说说IdentityServer4的持久化。
一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~

IdentityServer4之Authorization Code(授权码)相对更安全的更多相关文章
- [转]OAuth 2.0 - Authorization Code授权方式详解
本文转自:http://www.cnblogs.com/highend/archive/2012/07/06/oautn2_authorization_code.html I:OAuth 2.0 开发 ...
- OAuth 2.0 - Authorization Code授权方式详解
I:OAuth 2.0 开发前期准备 天上不会自然掉馅饼让你轻松地去访问到人家资源服务器里面的用户数据资源,所以你需要做的前期开发准备工作就是把AppKey, AppSecret取到手 新浪获取传送门 ...
- Oauth2.0(五):Authorization Code 授权
Authorization Code 方式适用于有自己的服务器的应用.之所以叫这个名字,是因为流程中引入了一个叫做 authorization code 的东西.这个东西是一个一次性的临时凭证,用来换 ...
- 微信支持的Authorization code授权模式(公众号开发)(开放平台资料中心中的代公众号发起网页授权)
链接:https://blog.csdn.net/ASZJBGD/article/details/82838356 主要流程分为两步: 1.获取code 2.通过code换取accesstoken 流 ...
- OAuth2.0和企业内部统一登录,token验证方式,OAuth2.0的 Authorization code grant 和 Implicit grant区别
统一登录是个很多应用系统都要考虑的问题,多个项目的话最好前期进行统一设计,否则后面改造兼容很麻烦: cas认证的方式:新公司都是老项目,用的是cas认证的方式,比较重而且依赖较多,winform的项目 ...
- OAuth 第三方登录授权码(authorization code)方式的小例子
假如上面的网站A,可以通过GitHub账号登录: 下面以OAuth其中一种方式,授权码(authorization code)方式为例. 一.第三方登录的原理 所谓第三方登录,实质就是 OAuth 授 ...
- IdentityServer4系列 | 授权码模式
一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...
- IdentityServer4实现OAuth2.0四种模式之授权码模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式 授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token ...
- OAuth 2.0 授权码请求
关于OAuth 2.0,请参见下面这两篇文章(墙裂推荐): <OAuth 2.0> <Spring Security OAuth 2.0> 纸上得来终觉浅,绝知此事要躬行.理论 ...
随机推荐
- 2021 年写 JavaScript 代码的 17 个优化技巧
我们经常会写一些 JavaScript 代码,但是如何写出干净又易维护的代码呢?本文将讲解 17 个 JavaScript 代码的技术帮助你提高编程水平,此外,本文可以帮助您为 2021 年的 Jav ...
- 用powershell实现,管理github自动化
用powershell实现,管理github自动化 搜索关键字如下:PowerShellForGitHub powershell 传教士 原创文章.始于 2021-02-04 允许转载,但必须保留名 ...
- Linux下diff的操作详解
总述 Linux diff命令用于比较文件的差异.diff以逐行的方式,比较文本文件的异同处.特别是比较两个版本不同的文件,如果指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子 ...
- jQuery插件Validate
一.导入js库 <script type="text/javascript" src="<%=path %>/validate/jquery-1.6.2 ...
- Berry Jam (前缀和)cf教育场
距离上一篇博客又2个月了 寻思着该除除草了 教育场是真的好难 可能是因为我还是只菜鸡 哭唧唧 先说下题意:有2*n罐果酱,草莓和蓝莓,梯子在中间从梯子那开始往两边吃(可以一会左一会右),问最少吃多少果 ...
- poj3661 Running
Description The cows are trying to become better athletes, so Bessie is running on a track for exact ...
- Splits CodeForces - 964A
题意: 我们定义一个不上升的且和为 n 的正整数序列,叫做 n 的分解. 比如, 下面是8的分解: [4, 4], [3, 3, 2], [2, 2, 1, 1, 1, 1], [5, 2, 1]. ...
- Light Bulb ZOJ - 3203 三分
三分: 和二分非常类似的一个算法,与二分不同的是 二分是单调的,而三分是一个先增后减或者先减后增 三分可以求出峰值. 注意三分一定是严格单调的,不能有相等的情况. 讲个例题: 题目 题意: 一个人发现 ...
- 【转】REST风格框架实战:从MVC到前后端分离(附完整Demo)
版权声明:欢迎转载,注明作者和出处就好!如果不喜欢或文章存在明显的谬误,请留言说明原因再踩哦,谢谢,我也可以知道原因,不断进步! https://blog.csdn.net/justloveyou_/ ...
- SpringCloud @RefreshScope标注的Bean在生命周期中怎么样的?
@RefreshScope 前言 该文章是由上一篇引申而来的,上一篇文章描述了Nacos是怎么触发配置刷新的,接着来写有关@RefreshScope的一些东西,都是由DEBUG而来 上一篇 文章概览 ...