IdentityServer4笔记整理(更新中)

原文: IdentityServer4笔记整理(更新中)

  • 1 OAuth 2.0
  • 1.1 OAuth 2.0协议流程图
  • 1.2 授权码模式
  • 1.3 简化模式
  • 2 OpenID Connect(OIDC)
  • 2.1 OIDC协议流程图
  • 2.2 OIDC在OAuth 2.0之上的扩展内容
  • 3 JSON Web Token
  • 3.1 JWT数据构成
  • 4 Identityserver4
  • 4.1 客户端凭证模式
  • 4.2 资源所有者密码模式
  • 4.3 简化模式
  • 4.4 授权码模式

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

OAuth 2.0

定义:OAuth 2.0是一个开放授权标准:允许资源所有者(用户)授权第三方应用访问该用户在某服务上的特定私有资源,但不提供账号密码给第三方应用。
安全提示:授权码和所有令牌必须通过Tsl加密传输。进入OAuth 2.0官网

OAuth 2.0协议流程图

1+--------+ +---------------+ 2 | |--(A)- Authorization Request ->| Resource | 3 | | | Owner | 4 | |<-(B)-- Authorization Grant ---| | 5 | | +---------------+ 6 | | 7 | | +---------------+ 8 | |--(C)-- Authorization Grant -->| Authorization | 9 | Client | | Server | 10 | |<-(D)----- Access Token -------| | 11 | | +---------------+ 12 | | 13 | | +---------------+ 14 | |--(E)----- Access Token ------>| Resource | 15 | | | Server | 16 | |<-(F)--- Protected Resource ---| | 17 +--------+ +---------------+ 18 (OAuth 2.0协议流程) 19 (A)客户端发起授权请求,客户端可以向资源所有者直接发起授权请求,建议的做法是将授权服务器作为中间人,客户端向授权服务器发起授权请求 20 (B)客户端收到授权凭证(和具体的授权类型有关) 21 (C)客户端通过授权凭证向授权服务器请求访问令牌 22 (D)授权服务器验证授权凭证和客户端,如果通过验证,返回给客户端访问令牌 23 (E)客户端通过访问令牌向资源服务器发出访问请求 24 (F)资源服务器验证访问令牌有效后,返回请求的资源

授权码模式

授权码模式:code的生命周期必须短暂、或者只能单次使用,如果code被多次使用,授权服务器必须使该code生成的所有令牌失效。访问令牌由client后端保存。

1+----------+ 2 | Resource | 3 | Owner | 4 | | 5 +----------+ 6 ^ 7 | 8 (B) 9 +----|-----+ Client Identifier +---------------+ 10 | -+----(A)-- & Redirection URI ---->| | 11 | User- | | Authorization | 12 | Agent -+----(B)-- User authenticates --->| Server | 13 | | | | 14 | -+----(C)-- Authorization Code ---<| | 15 +-|----|---+ +---------------+ 16 | | ^ v 17 (A) (C) | | 18 | | | | 19 ^ v | | 20 +---------+ | | 21 | |>---(D)-- Authorization Code ---------' | 22 | Client | & Redirection URI | 23 | | | 24 | |<---(E)----- Access Token -------------------' 25 +---------+ (w/ Optional Refresh Token) 26 (A)客户端引导用户代理(浏览器)到达授权终结点,并携带参数:response_type(code)、client_id、redirect_uri、scope、state 27 (B)授权服务器通过用户代理(浏览器)验证资源所有者,并确定资源所有者是否给予客户端授权 28 (C)验证资源所有者成功,并且允许授权,授权服务器将用户代理(浏览器)重定向到redirect_uri,并返回code和授权请求的state 29 (D)客户端向授权服务器令牌终结点请求令牌,携带参数:grant_type、code、redirect_uri、client_id、secret(可选) 30 (E)授权服务器验证code、client_id、secret是否有效,并验证redirect_uri是否与步骤C中一致,如果验证成功,携带Access Token将用户代理(浏览器)重定向到redirect_uri

简化模式

要点:不支持刷新令牌,访问令牌编码在Url中,所以会有暴露的风险(在Oauth2.0官网中已经不推荐使用)

1+----------+ 2 | Resource | 3 | Owner | 4 | | 5 +----------+ 6 ^ 7 | 8 (B) 9 +----|-----+ Client Identifier +---------------+ 10 | -+----(A)-- & Redirection URI --->| | 11 | User- | | Authorization | 12 | Agent -|----(B)-- User authenticates -->| Server | 13 | | | | 14 | |<---(C)--- Redirection URI ----<| | 15 | | with Access Token +---------------+ 16 | | in Fragment 17 | | +---------------+ 18 | |----(D)--- Redirection URI ---->| Web-Hosted | 19 | | without Fragment | Client | 20 | | | Resource | 21 | (F) |<---(E)------- Script ---------<| | 22 | | +---------------+ 23 +-|--------+ 24 | | 25 (A) (G) Access Token 26 | | 27 ^ v 28 +---------+ 29 | | 30 | Client | 31 | | 32 +---------+ 33 (A)客户端引导用户代理(浏览器)到达授权终结点,并携带参数:response_type(token)、client_id、redirect_uri、scope、state 34 (B)授权服务器通过用户代理(浏览器)验证资源所有者,并确定资源所有者是否给予客户端授权 35 (C)验证资源所有者成功,并且允许授权,授权服务器将用户代理(浏览器)重定向到redirect_uri,redirect_uri的URL 锚点(fragment)部分包括了响应参数(以#hash值的方式追加):access_token、token_type、expires_in、scope、state 36 (D)用户代理(浏览器)向redirect_uri发出请求,但不包括URL 锚点,用户代理在本地保存了fragment。 37 (E)redirect_uri的服务器返回页面给浏览器,该页面需要包含解码fragment的脚本。 38 (F)浏览器接收到页面后,执行脚本,将C中的响应参数解码出来 39 (G)用户代理(浏览器)将响应参数传递给客户端

OpenID Connect(OIDC)

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

image

OIDC协议流程图

1+--------+ +--------+ 2| | | | 3| |---------(1) AuthN Request-------->| | 4| | | | 5| | +--------+ | | 6| | | | | | 7| | | End- |<--(2) AuthN & AuthZ-->| | 8| | | User | | | 9| RP | | | | OP | 10| | +--------+ | | 11| | | | 12| |<--------(3) AuthN Response--------| | 13| | | | 14| |---------(4) UserInfo Request----->| | 15| | | | 16| |<--------(5) UserInfo Response-----| | 17| | | | 18+--------+ +--------+ 19EU:End User:一个人类用户。 20RP:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方; 21OP:OpenID Provider,有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息; 22ID Token:JWT格式的数据,包含EU身份认证的信息。 23UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS 24 (1).RP发送一个认证请求给OP 25 (2).OPEU进行身份认证,然后提供授权; 26 (3).OPID Token和Access Token(需要的话)返回给RP 27 (4).RP使用Access Token发送一个请求到UserInfo EndPoint; 28 (5).UserInfo EndPoint返回EU的Claims。

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格式

1JWT3部分构成:header.payload.signature 2在IdSrv中,payload中的键值对根据token类型和授权流程的不同有所区别 3header: 4{ 5 "alg": "RS256",//签名算法 6 "kid": "9dcf733a1192a6da053e64c6ee22ff87", 7 "typ": "JWT"//token类型 8} 9payload://需要传递的数据 10{ 11 "nbf": 1556591630,//该jwt在此之前无效 12 "exp": 1556595230,//该jwt在此之后无效 13 "iss": "http://localhost:7102",//jwt颁发者 14 "iat": 1516239022,//jwt颁发时间 15 "aud": "http://localhost:7102/resources",//jwt接收者 16 "client_id": "jsImplicit", 17 "sub": "SubjectId",//用户唯一id 18 "auth_time": 1556591629,//授权时间 19 "idp": "local",//identityProvider 20 "name": "Username", 21 "scope": [ 22 "openid", 23 "profile" 24 ], 25 "amr": [ 26 "pwd"//authenticationMethod 27 ] 28} 29signature://token生成方使用私匙生成token,token消费方使用用公匙验证token是否被修改过 30RSASHA256( 31 base64UrlEncode(header) + "." +base64UrlEncode(payload),Public Key,Private Key 32 ) 33expires_in="exp"-"nbf"

IdentityServer4

客户端凭证模式

不支持刷新令牌、无法访问用户资源scope(openid、profile、email等)

1Request: 2 POST /connect/token HTTP/1.1 #请求方式只能为post 3 Host: idsrv-server.com 4 Content-type: application/x-www-form-urlencoded #参数只能放在body里面 5 body: 6 { 7 grant_type:client_credentials 8 client_id:ClientCredentials 9 client_secret:iwiaXNzIjoibnVsbCIsImF1ZCI6WyJudWxsL3Jlc291cmNlcyIsIm9yZGVycyJdLCJjbGllbnRfaWQiOiJDb 10 scope:orders openid(可选,默认请求所有scope) 11 } 12Response: 13 HTTP/1.1 200 OK 14 Content-Type: application/json 15 Cache-Control: no-store 16 Pragma: no-cache 17 18 { 19 "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", 20 "token_type":"bearer", 21 "expires_in":3600 22 }

资源所有者密码模式

用于同一组织下授权

1#请求token 2Request: 3 POST /connect/token HTTP/1.1 4 Host: idsrv-server.com 5 Content-type: application/x-www-form-urlencoded 6 body: 7 { 8 grant_type:password 9 username:dd 10 password:dd 11 client_id:eshopOnVue 12 scope:orders(可选参数) 13 } 14 15#请求刷新令牌:原刷新令牌失效、之前颁发的access_token不受影响(需要实现手动失效) 16Request: 17 POST /connect/token HTTP/1.1 18 Host: idsrv-server.com 19 Content-type: application/x-www-form-urlencoded 20 body: 21 { 22 grant_type:refresh_token 23 refresh_token:e4364377ec69c8d5c06a49d7b74efbd2a29015ac37e9ede8e17597d348931d32 24 client_id:eshopOnVue 25 } 26Respose: 27{ 28 "id_token": "eyJhbGciO.iJSUzI1NiI.sImtpZCw", 29 "access_token": "eyJhb.GciOiJSUz.I1NiIsIm", 30 "expires_in": 3600, 31 "token_type": "Bearer", 32 "refresh_token": "60e7dda6e30473ce6dc0a1656b38c174a74ef73310d" 33} 34#通过access_token请求用户终结点(需要scope:profile):/connect/userinfo

简化模式

第三方向授权终结点请求授权,授权成功后,通过Url锚点(#)将access_token、id_token传给redirecturl

授权码模式

流程分析

1 IdentityServer服务端启用服务
2 MVC项目配置OIDC保护控制器,并设置clent_id等
3 webApi项目配置Bearer认证保护Api

1.访问受IdentityServer OIDC保护的MVC控制器
2.自动重定向到IdentityServer的/connect/authorize,并附带clint信息

1IdSrv授权码模式: 2Js客户端mgr.signinRedirect() 31.向IdSrv服务器请求/.well-known/openid-configuration 获取IdSrv数据 42./connect/authorize发起授权请求,携带以下参数 5client_id: js 6redirect_uri:登录成功后跳转的地址 7response_type: code 8scope:请求的资源权限 9state: 2dd196cd7a68402199534d6123791e64 10code_challenge: 23kG8msCLc2oHDnTALRTGElqmNAaTADOwUmLMnENFTE 11code_challenge_method: S256 123.1.如果验证client信息正确,且携带了idsrv.session和idsrv两个cookie,并已经授权,则跳转到redirect_uri,并携带以下参数给前端页面: 13code:授权码 14scope:请求的资源权限 15state: a656e5bb62024ee48d8267127e46fa68 16session_state: YjwA6dW7trE2II5E0ao6h0y2ty4PoiFrV4qZN0XVjvI.46fe4aa153c9d5480e0f61406e35e5ff 173.1.1、在redirect_uri页面,通过Oidc.UserManager({ response_mode: "query" }).signinRedirectCallback(),通过授权码向/connect/token请求token,携带以下参数 18client_id: js 19code: 725ca140eb5afdbc8f37cda96eeb53550aa4502de462c77d0618eed2353422d4 20redirect_uri: http://localhost:5003/callback.html 21code_verifier: a6ff87be469a4171bf1bfd43e5310468bf1d196d337244e2a829b0e94fe476bb9fdad37d300048e692c2fe58c734b0b6 22grant_type: authorization_code 233.1.2将code、token写入cookie保存,否则下次通过idsrv.session和idsrv两个cookie申请新的授权码,同时再次跳转到初始请求页面 243.2.如果验证client信息,但未授权,则跳转到/Account/Login并携带一个ReturnUrl参数 25该参数为/connect/authorize/callback并附带步骤2的所有参数。该参数需要保存并在登录成功后,跳转到该页面 263.3输入账号密码,进入自定义验证Api中 273.4验证成功,通过HttpContext.SignInAsync方法为用户颁发加密的用户凭证,将idsrv.session和idsrv两个cookie写入请求头 283.5.在自定义Api中跳转到ReturnUrl 293.6.1如果未配置授权页面,IdSrv服务端将/connect/authorize/callback重定向到redirect_uri,并携带授权码等参数,重复3.1.1 303.6.2如果配置了授权页面,IdSrv服务端将/connect/authorize/callback重定向到授权页面 31 32登出操作: 33Js客户端mgr.signoutRedirect() 341.向IdSrv请求/connect/endsession 并携带以下两个参数 35id_token_hint: 36post_logout_redirect_uri: 登出回调地址 372.重定向到/Account/Logout 并携带生成的logoutId参数 383.在Logout里清除await HttpContext.SignOutAsync() 并跳转到post_logout_redirect_uri
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

IdentityServer4笔记整理(更新中) - HelloWorld