博客与笔记无法实时同步, 笔记最新链接

OAuth 2.0

定义:OAuth 2.0是一个开放授权标准:允许资源所有者(用户)授权第三方应用访问该用户在某服务上的特定私有资源,但不提供账号密码给第三方应用。

安全提示:授权码和所有令牌必须通过Tsl加密传输。进入OAuth 2.0官网

OAuth 2.0协议流程图

     +--------+                               +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| || Authorization |
| Client | | Server |
| || Resource |
| | | Server |
| |

授权码模式

授权码模式:code的生命周期必须短暂、或者只能单次使用,如果code被多次使用,授权服务器必须使该code生成的所有令牌失效。访问令牌由client后端保存。
     +----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ------(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |

简化模式

要点:不支持刷新令牌,访问令牌编码在Url中,所以会有暴露的风险(在Oauth2.0官网中已经不推荐使用)
     +----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| || Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |

资源所有者密码模式

用户将用户名及密码提供给可信任的第三方应用,第三方应用向令牌终结点请求令牌。常用于第一方应用进行登陆. 优点:应用不需要存储用户账号、密码,通过刷新令牌保持持久登陆,降低密码泄露的风险。

     +----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |
#请求token
Request:
POST /connect/token HTTP/1.1
Host: idsrv-server.com
Content-type: application/x-www-form-urlencoded
body:
{
grant_type:password
username:dd
password:dd
client_id:eshopOnVue
scope:orders(可选参数)
} #请求刷新令牌:原刷新令牌失效、之前颁发的access_token不受影响(需要实现手动失效)
Request:
POST /connect/token HTTP/1.1
Host: idsrv-server.com
Content-type: application/x-www-form-urlencoded
body:
{
grant_type:refresh_token
refresh_token:e4364377ec69c8d5c06a49d7b74efbd2a29015ac37e9ede8e17597d348931d32
client_id:eshopOnVue
}
Respose:
{
"id_token": "eyJhbGciO.iJSUzI1NiI.sImtpZCw",
"access_token": "eyJhb.GciOiJSUz.I1NiIsIm",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "60e7dda6e30473ce6dc0a1656b38c174a74ef73310d"
}
#通过access_token请求用户终结点(需要scope:profile):/connect/userinfo

客户端凭证模式

客户端直接使用自身的凭证向授权服务器终结点请求访问令牌。只能用于可信的客户端。不支持刷新令牌、无法访问用户资源scope(openid、profile、email等)


     +---------+                                  +---------------+
| | | |
| |>--(A)- Client Authentication --->| Authorization |
| Client | | Server |
| |
Request:
POST /connect/token HTTP/1.1 #请求方式只能为post
Host: idsrv-server.com
Content-type: application/x-www-form-urlencoded #参数只能放在body里面
body:
{
grant_type:client_credentials
client_id:ClientCredentials
client_secret:iwiaXNzIjoibnVsbCIsImF1ZCI6WyJudWxsL3Jlc291cmNlcyIsIm9yZGVycyJdLCJjbGllbnRfaWQiOiJDb
scope:orders openid(可选,默认请求所有scope)
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache {
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"token_type":"bearer",
"expires_in":3600
}

OpenID Connect(OIDC)

定义:它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议

OIDC协议流程图

+--------+                                   +--------+
| | | |
| |---------(1) AuthN Request-------->| |
| | | |
| | +--------+ | |
| | | | | |
| | | End- || |
| | | User | | |
| RP | | | | OP |
| | +--------+ | |
| | | |
| || |
| | | |
| |

OIDC在OAuth之上的扩展

  • [ ] Scope:openid(用来区分这是一个OIDC的Authentication请求,而不是OAuth2的Authorization请求)
  • [ ] response_type:id_token,在implicit模式下请求id_token
  • [ ] id_token:身份令牌,是一个授权服务器提供的包含用户信息(由一组Cliams构成以及其他辅助的Cliams)的JWT格式的数据结构
  • [ ] UserInfo Endpoint:通过id_token从用户信息终结点获得一组EU相关的Claims,比如可以将Claims从token移除,避免token过大,只保留sub,通过UserInfo Endpoint查询Claims
"response_type"参数值 OIDC授权类型
code Authorization Code Flow
id_token token Implicit Flow
code id_token Hybrid Flow
  • Authorization Code Flow:从授权终结点返回code,从令牌终结点返回token
  • Implicit Flow:从授权终结点返回所有token
  • Hybrid Flow:id_token返回给前端,access_token在后端保存(access_token的安全性要求比id_token)高

JSON Web Token

定义:JWT是一个定义一种紧凑的,自包含的并且提供防篡改机制的传递数据的方式的标准协议

JWT格式组成

JWT由3部分构成:header.payload.signature
在IdSrv中,payload中的键值对根据token类型和授权流程的不同有所区别
header:
{
"alg": "RS256",//签名算法
"kid": "9dcf733a1192a6da053e64c6ee22ff87",
"typ": "JWT"//token类型
}
payload://需要传递的数据
{
"nbf": 1556591630,//该jwt在此之前无效
"exp": 1556595230,//该jwt在此之后无效
"iss": "http://localhost:7102",//jwt颁发者
"iat": 1516239022,//jwt颁发时间
"aud": "http://localhost:7102/resources",//jwt接收者
"client_id": "jsImplicit",
"sub": "SubjectId",//用户唯一id
"auth_time": 1556591629,//授权时间
"idp": "local",//identityProvider
"name": "Username",
"scope": [
"openid",
"profile"
],
"amr": [
"pwd"//authenticationMethod
]
}
signature://token生成方使用私匙生成token,token消费方使用用公匙验证token是否被修改过
RSASHA256(
base64UrlEncode(header) + "." +base64UrlEncode(payload),Public Key,Private Key
)
#RSA签名过程
#1.将消息内容进行base64编码:base64UrlEncode(header) + "." +base64UrlEncode(payload)
#2.对编码后的内容进行SHA256哈希计算(不可逆)
#3.对hash值使用privateKey加密,加密后内容作为签名
#4.token接收方通过publicKey对签名进行解密得到hash值,并将内容进行hash计算,比较两个hash值,确保消息未被篡改
expires_in="exp"-"nbf"

RSA非对称加密算法

1 RSA算法特点:
1.1 公钥私钥对等,可以互换
1.2 私钥需要保存在可靠方
1.3 无法从公钥计算出私钥(理论上从私钥也无法计算出公钥,例外:openssl的公钥e固定为65537,且私钥文件中含有额外的参数,可以从私钥计算出公钥)
2 RSA应用
2.1 加密:消息发送方:公钥加密=>消息接收方:私钥解密(用于加密传递消息)
##缺点:无法防止伪造消息
2.2 签名:消息发送方:私钥加密=>消息接收方:公钥解密(用于消息签名,防止消息被篡改)
##缺点:消息明文传输

HTTPS简单流程

1.服务器通过非对称算法生成私钥公钥
2.服务方将公钥提供给相关机构(CA)
3.CA生成证书并颁发给服务器:
{
证书发布机构CA
证书有效期
公钥
证书所有者
签名(签名方法与JWT类似,私钥属于CA)
...
}
4.服务器将证书发送给客户端:
{
1.TCP三次握手
2.建立tunnel
3.client hello(包括SessionId,可以避免重新握手,并重新使用已有对话密钥)
4.server hello
5.发送Certificate给客户端
}
5.客户端通过系统中内置的CA公钥验证证书的合法性
6.客户端通过服务方公钥与服务器协商对称加密算法与密钥
7.进行对称加密通信

参考:https://zhuanlan.zhihu.com/p/22142170 https://zhuanlan.zhihu.com/p/27395037

IdentityServer4

授权码模式

PKCE(Proof Key for Code Exchange)

利用不可逆算法,确保在被窃取了授权码或其他密匙的情况下,也无法向授权服务器换取访问令牌

PKCE流程:
1.客户端随机生成一串字符:
{
code_verifier=base64url(RandomString),
code_challenge=base64url(sha256(code_verifier))
}
2.客户端携带code_challenge向授权服务器发起授权请求
3.授权服务器对客户端进行认证成功后返回授权码,并保存code_challenge
4.客户端获取到授权码之后,携带code_verifier向令牌终结点发起请求,换取Access Token
5.授权服务器验证授权码,将code_verifier进行sha256计算并url编码后与code_challenge对比,如果一致,颁发访问令牌

参考:https://tonyxu.io/zh/posts/2018/oauth2-pkce-flow/

授权码模式流程

#Step 1 客户端向授权服务器授权终结点发起请求:
GET /connect/authorize HTTP/1.1
Host: Idsrv.com,
Query String Parameters:
{
client_id: Swagger_UI
redirect_uri: http://localhost:9528/Callback
response_type: code
scope: openid profile orders
state: 668ae852a74f4923ad140d79d2f10fee
code_challenge: i2CnOeIHTBZZrAsgzEZV3-KpMTb_OCvl05ydETjrqIc
code_challenge_method: S256
}
state:客户端随机生成的字符串,授权服务器在重定向到redirect_uri时会原样返回,客户端检查state是否相同,来防止CSRFF攻击
#step 2 授权服务器对客户端进行认证,认证成功,授权服务器返回302重定向并携带ReturnUrl参数:
Response:
{
Status Code: 302 Found,
Location: http://localhost:6102/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DSwagger_UI%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A9528%252FCallback%26response_type%3Dcode%26scope%3Dopenid%2520profile%2520orders%26state%3D668ae852a74f4923ad140d79d2f10fee%26code_challenge%3Di2CnOeIHTBZZrAsgzEZV3-KpMTb_OCvl05ydETjrqIc%26code_challenge_method%3DS256
}
#step 3 /Account/Login请求返回登陆页面,并将ReturnUrl写入登陆页面
#step 4 用户在登陆页面发起登陆请求:
参数:
{
1.用户名
2.密码
3.ReturnUrl
}
#step 4 授权服务器验证用户名、密码成功,且ReturnUrl有效:
{
1.通过HttpContext.SignInAsync为当前请求上下文颁发登陆凭证:
Set-Cookie:
{
idsrv.session:'8c9e9e80f92da2551c77dc6ab03c69ca,path=/'
idsrv:'CfDJ8IOXoUULE4dDgZ02v48m533Xg,expires=Mon,08 Jul 2019 08:38:26 GMT, path=/,httponly'
}
2.发起重定向到ReturnUrl
}
#step 5 在 /connect/authorize/callback 终结点:
{
授权服务器更新Cookie:idsrv,并重定向到redirect_uri,携带以下参数:
{
code: 21a9deaac4457e29f669a91bb36795c048aae5680b49ae3a1ffafa50aff0d169
scope: openid profile orders
state: 668ae852a74f4923ad140d79d2f10fee
session_state: ZcDaWfAmzNGLsXS3-1ofTvNGryU-KxeurTpPLxP6oF0.89cd4e2083165f0701dbd2181ede5b7b(会话状态)
}
}
#step 6 在redirect_uri向令牌终结点请求访问令牌:
POST /connect/token HTTP/1.1
Host: Idsrv.com,
Content-type: application/x-www-form-urlencoded
body:
{
client_id: Swagger_UI
code: 21a9deaac4457e29f669a91bb36795c048aae5680b49ae3a1ffafa50aff0d169
redirect_uri: http://localhost:9528/Callback
code_verifier: dde8c25afc8d42728225154fea0aa098556671d3344c423f9007f1895b47dbf2be2116c7c5f34720842383ec9a7e0a66
grant_type: authorization_code
}
#step 7 授权服务器验证code和code_verifier,并颁发访问令牌

刷新访问令牌

配置new Oidc.UserManager()时 设置scope=offline_access,直接通过刷新令牌请求访问令牌。offline_access优先于silent_redirect_uri

通过Iframe页面进行静默刷新:
#step 1 通过Iframe页面向授权终结点发起请求:
GET /connect/authorize HTTP/1.1
Host: Idsrv.com,
Cookie:
{
idsrv.session=8c9e9e80f92da2551c77dc6ab03c69ca;
idsrv=CfDJ8IOXoUULE4dDgZ02v48m53JzoKhJcuEwwXcdvHRYodIZ2nTuD
}
Query String Parameters:
{
client_id: Swagger_UI
redirect_uri: http://localhost:9528/SilentCallback
response_type: code
scope: openid profile orders
state: 54207b37bb644f90800d0993d5a5c210
code_challenge: 8bOHunvRggEM9m3Hwb-8m24KIiRV9rPSbz0OOvTP7D0
code_challenge_method: S256
prompt: none
id_token_hint: eyJhbGciOiJSUzI1NiIsImtp2UFyLw
}
id_token_hint://为之前获取的id_token
prompt:none//用来指示授权服务器是否引导用户重新认证和同意授权
#step 2 重定向到redirect_uri,携带以下参数:
{
code: a956650cd653debe11989d225c2caa2619521b9176b444fbcc83d3a1663bf1ed
scope: openid profile orders
state: 54207b37bb644f90800d0993d5a5c210
session_state: SGmLH8gIy6VAPtdlT6_zQtix_VM229bPkpY0OpwQ6fc.229a9d1e0be856145c035db0aa6033cc
}
#step 3 在redirect_uri页面执行new Oidc.UserManager().signinSilentCallback()
#step 4 向令牌终结点请求访问令牌
登出操作:
Js客户端mgr.signoutRedirect()
1.向IdSrv请求/connect/endsession 并携带以下两个参数
id_token_hint:
post_logout_redirect_uri: 登出回调地址
2.重定向到/Account/Logout 并携带生成的logoutId参数
3.在Logout里清除await HttpContext.SignOutAsync() 并跳转到post_logout_redirect_uri

资源所有者密码模式

IdentityServer4笔记整理(更新中)的更多相关文章

  1. 微信小程序练习笔记(更新中。。。)

    微信小程序练习笔记 微信小程序的练习笔记,用来整理思路的,文档持续更新中... 案例一:实现行的删除和增加操作  test.js // 当我们在特定方法中创建对象或者定义变量给与初始值的时候,它是局部 ...

  2. vue-学习笔记(更新中...)

    vue学习笔记 2017-08-23  11:10:28 Vue实例: var vm = new Vue({ // 选项 }) 实例化Vue.Vue实例,构造函数Vue.创建一个Vue的根实例,Vue ...

  3. 保姆级尚硅谷SpringCloud学习笔记(更新中)

    目录 前言 正文内容 001_课程说明 002_零基础微服务架构理论入门 微服务优缺点[^1] SpringCloud与微服务的关系 SpringCloud技术栈 003_第二季Boot和Cloud版 ...

  4. 《Java并发编程实战》读书笔记(更新中)

    一.简介 1.多线程编程要注意的几点: 安全性:永远不发生糟糕的事情 活跃性:某件正确的事情最终会发生(不会发生无限循环或者死锁) 性能:正确的事尽快发生(上下文切换消耗之类的) 二.线程安全 1.为 ...

  5. 《深入理解Java虚拟机:JVM高级属性与最佳实践》读书笔记(更新中)

    第一章:走进Java 概述 Java技术体系 Java发展史 Java虚拟机发展史 1996年 JDK1.0,出现Sun Classic VM HotSpot VM, 它是 Sun JDK 和 Ope ...

  6. react-navigation 使用笔记 持续更新中

    目录 基本使用(此处基本使用仅针对导航头部而言,不包含tabbar等) header怎么和app中通信呢? React-Navigation是目前React-Native官方推荐的导航组件,代替了原用 ...

  7. Python面试题整理-更新中

    几个链接: 编程零基础应当如何开始学习 Python ? - 路人甲的回答 网易云课堂上有哪些值得推荐的 Python 教程? - 路人甲的回答 怎么用最短时间高效而踏实地学习 Python? - 路 ...

  8. JS-JavaScript类库整理 [更新中...]

    老大.jQuery插件库 ——收集最全最新最好的jQuery插件 http://www.jq22.com/ 一.Moment.js ——JavaScript 日期处理类库 http://momentj ...

  9. css:使用笔记(不断更新中...)

    1,inline-block Inline :1是不支持宽高的 2 在一行内显示 span 啥的~ Block:1,占一行 2支持宽高 但是img因为在一行并排显示,我们归为行(内嵌)元素,但支持设置 ...

随机推荐

  1. (一)C#编程基础复习——开启编程之旅

    回想当年学习编程,刚开始学习是非常艰苦的,可能是因为文科生原因,刚开始接触工科类的知识不是很擅长,上去大学第一年基本没有好好学习编程,入门C#编程基础一窍不通,也许那时年少无知,第二学期开始奋发图强, ...

  2. 我竟然不再抗拒 Java 的类加载机制了

    很长一段时间里,我对 Java 的类加载机制都非常的抗拒,因为我觉得太难理解了.但为了成为一名优秀的 Java 工程师,我决定硬着头皮研究一下. 01.字节码 在聊 Java 类加载机制之前,需要先了 ...

  3. HDU 2298:Toxophily(推公式)

    http://acm.hdu.edu.cn/showproblem.php?pid=2298 题意:给出一个x,y,v,问从(0,0)以v为初速度射箭,能否射到(x,y)这个点,如果能,输出最小的射出 ...

  4. ElasticStack学习(四):ElasticSearch文档使用与操作

    一.文档的CRUD介绍 ElasticSearch中存在五种操作,分别如下: 1.Index 该操作表示:如果文档的ID不存在,则创建新的文档.若有相同的ID,先删除现有文档,然后再创建新的文档,同时 ...

  5. .NET Core 学习资料精选:入门

    开源跨平台的.NET Core,还没上车的赶紧的,来不及解释了-- 本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料.我进行了知识点归类,让大家可以更清晰的学习.NET Co ...

  6. http接口测试和使用,首先要了解什么是http请求

    http接口测试和使用,首先要了解什么是http请求: http请求通俗讲就是把客户端的东西通过http协议发送到服务端,服务端根据http协议的定义解析客户端发过 来的东西! http请求中常用到的 ...

  7. Bzoj 1079 着色方案 题解

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2237  Solved: 1361[Submit][Stat ...

  8. C#类型详解

    一.类型成员 类成员定义有(public.private.internal.protected). Public--对任何类和成员都是公开的,无限制 Private--是私有的,仅能由类内部代码访问, ...

  9. request 中url拼接排序参数与签名算法

    一.参数要求: { appId:应用在后台创建应用时分配的应用编号,与应用密钥一一对应 sign:按照当前请求参数名的字母序进行升序排列(排序时区分大小写,除sign外,其它值不为空的参数都参与签名) ...

  10. 网页内嵌html遇到的问题

    在项目中遇到个问题 充值功能是点击一个按钮这个按钮会弹出模态框,输入充值金额会执行一段脚本自动提交数据到https://openapi.alipay.com/gateway.do上 结果:本网页跳转到 ...