SAML2 vs JWT:理解OpenID连接第2部分

ttps://medium.com/@robert.broeckelmann/saml2-vs-jwt-understanding-openid-connect-part-2-f361ca867baa

这篇文章继续我们对OpenID连接(OIDC)的讨论。我们来看看OIDC规范定义的三个身份验证流之一——授权代码授权流。

1、OIDC身份验证流

OAuth2定义了授权授权和扩展授权(Authorization Grants and Extension Grants),OIDC规范定义了认证流。概念是相似的。该规范定义了三个认证流;这些流的不同之处包括传递给OP的参数、响应的内容以及如何处理响应。对授权端点的请求(以及身份验证流详细信息)之间的区别是return_type参数。该参数有几个有效值,定义在OAuth2规范和OAuth2多响应类型规范之间:

Authorization Code Flow: code

Implicit Flow: id_token

Implicit Flow: id_token token

Hybrid Flow: code id_token

Hybrid Flow: code token

Hybrid Flow: code id_token token

那么,这一切意味着什么呢?当您在response_type参数中看到“code”值时,授权端点响应将返回授权代码。只要在response_type参数中包含了“id_token”,就会在响应中包含一个id_token。当response_type参数中包含“token”时,来自授权端点的响应中将包含一个access_token。这些细节会影响响应的结构,依赖方(RP、客户)(Relying Party (RP, Client))下一步采取什么处理步骤,以及可以处理什么用例,如下所示。请注意,

OIDC授权码流直接扩展了OAuth2授权码授权。OIDC隐式流和OIDC混合流是对OIDC授权码流的扩展。

OIDC定义的授权码response_type与OAuth2规范定义的同名response_type不同。

本文中使用的所有示例请求和响应都是OIDC规范中给出的示例的变体。

授权码流(OIDC v1.0规范,章节3.1):这是OAuth2授权码授权的OIDC版本。此流的response_type设置为“code”。这里给出的示例利用授权代码Grant中的所有可用功能来完成:

终端用户认证

中继方(客户端、应用程序)Relaying Party (Client, application)的身份验证(可选)。

中继方(RP) Relaying Party (RP)看不到最终用户的凭据(密码)

用户代理User Agent 看不到访问令牌或ID令牌Access Token or ID Token

SSO RP

获取多个访问令牌或多个范围访问令牌。

使用访问令牌对API提供者(资源服务器,Resource Server)进行API(资源)调用。



下面将遍历上图中的步骤。最终用户通过在web浏览器中输入网站地址或类似的操作(图中没有显示)来启动应用程序登录过程。然后浏览器(用户代理)向RP发送一个请求,RP拦截该请求并发现它不是经过身份验证的会话的一部分——同样,在图中也没有显示(规范没有涵盖这一部分)。

(1)身份验证请求

RP将用户代理重定向到OpenID提供者(OP)——步骤(A)。结果请求看起来像这样:

GET /oidc/authorize?

response_type=code

&scope=openid%20profile%20email

&client_id=s6BhdRkqt3

&state=af0ifjsldkj

&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1

Host: server.example.com

identity provider (OP) 将重定向用户代理登录工作流是由OP -步骤(B)。身份验证是如何工作的详细信息不在OIDC规范的范围。我们称之为OIDC身份验证协议,但它没有定义如何验证用户的详细信息。这与SAML2 Web Browser SSO Profile的工作方式没有什么不同——用户的实际身份验证可以是各种各样的机制,这些机制依赖于身份提供者(OP)功能。身份验证工作流还可以包含一个检查,允许最终用户同意RP对其拥有的资源的访问(授权访问被授予Resource上的RP)。

(2)成功的身份验证响应

成功的身份验证后,OP将用户重定向回授权端点authorization endpoint ,使用会话跟踪信息集(可能是会话cookie的形式,依赖于实现)。授权端点将返回一个HTTP重定向(带有授权码)到RP URL,它看起来类似于以下步骤(C):

HTTP/1.1 302 Found

Location: https://client.example.org/cb?

code=SplxlOBeZQQYbYS6WxSbIA

&state=af0ifjsldkj

因此,用户代理向RP发送如下请求:

GET https://client.example.org/cb?

code=SplxlOBeZQQYbYS6WxSbIA

&state=af0ifjsldkj

(3)身份验证错误

如果在身份验证和同意阶段(或返回授权代码之前的任何其他阶段)发生错误,授权端点将返回类似如下的错误:

HTTP/1.1 302 Found

  Location: https://client.example.org/cb?

    error=invalid_request

    &error_description=

      Unsupported%20response_type%20value

    &state=af0ifjsldkj

(4)令牌的请求

此时,RP已经收到了授权代码,但还没有看到最终用户的密码(或其他凭据)。现在,RP需要从令牌端点获取访问令牌、ID令牌Access Token, ID Token和其他信息。因此,RP向令牌端点 token endpoint发送类似如下的请求——步骤(D):

POST /oidc/token HTTP/1.1

Host: server.example.com

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&

code=SplxlOBeZQQYbYS6WxSbIA&

redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&

client_id=s6BhdRkqt3&

client_secret=blah_blah_blah_1234

client_secret参数只需要在RP是一个机密客户端时存在(就像一般的OAuth2授权码授予一样)。在OIDC规范第9节中描述了验证RP到令牌端点的替代方法;OAuth2规范也支持基本身份验证(它是首选的方法)。

(5)令牌响应

来自授权代码流的令牌端点 token endpoint 的响应类似于以下步骤(E)。

HTTP/1.1 200 OK

Content-Type: application/json

Cache-Control: no-store

Pragma: no-cache

{

“access_token”: “SlAV32hkKG”,

“token_type”: “Bearer”,

“refresh_token”: “8xLOxBtZp8”,

“expires_in”: 3600,

“id_token”: “eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc

yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5

NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ

fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz

AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q

Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ

NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd

QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS

K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4

XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg”

}

(6)验证令牌

现在,ID Token(上面的id_token属性)必须根据OIDC规范的3.1.3.7节进行验证——步骤(F)——不要跳过这一部分,这会影响安全性。对于这个认证流,ID令牌 ID Token将包含一个at_hash(访问令牌散列) (Access Token hash) 属性,可以用来验证访问令牌;这是可选的,但推荐的步骤(G)。

在OIDC场景下,RP上使用ID Token进行认证,使用Access Token进行认证:

调用资源服务器(在我们的例子中是API提供者)

userinfo 端点处获取信息(可选)

这与oauth2工作方式不一样。

(7)访问令牌的范围

现在,如果访问令牌有一个受众概念(不透明令牌可能不是这样),那么RP可能需要唯一的访问令牌来访问UserInfo端点和访问资源服务器。如果是这种情况,那么可以使用相同的授权代码对令牌端点进行第二次调用,请求资源服务器的受众提供第二个访问令牌——假设OP已配置为允许这样的访问。另一个潜在的方法是利用一个作用域的访问令牌,支持多个观众——JWT允许这个——但是,OP必须支持和有潜在的安全问题,演员的数量可以做一些有趣的事情和你的身份令牌增加(因此,增加风险)。

接下来,如果RP需要额外的要求,它可以联系OP的端点用户信息获取如前所述,步骤(H) & (I)。有趣的是,RP的 ID Token ,它可以包含任何声称,可能是用户信息返回的端点。但是,OP供应商倾向于对这个特性的灵活性施加一些限制。

(8)呼叫资源服务器

接下来,RP可以访问资源的资源服务器(让我们称之为一个API在一个API提供者)通过调用API的访问令牌授权头我们以前探索——一步(J)。在理解OAuth2帖子,假设访问令牌是一个JWT令牌;JWT规范定义了如何在资源服务器(API提供者)上验证访问令牌。如果Access令牌是不透明的令牌,则资源服务器必须使用规范之外定义的机制(可能依赖于实现)与OP通信。2015年10月,发布了OAuth 2.0 Token Introspection (RFC 7662),它“定义了一种方法,让受保护的资源可以查询OAuth 2.0授权服务器,以确定OAuth 2.0令牌的活动状态,并确定有关该令牌的元信息。”基本上,它定义了一个授权服务器端点,该端点可以验证一个令牌并检索有关令牌的信息(令牌内省端点)。OIDC UserInfo端点和这个新端点之间有一些重叠,但是OAuth2令牌内省端点提供了验证不透明访问令牌的能力(尽管这不是它的主要目的)。但是访问令牌被验证了,这个步骤必须在请求处理可以在资源服务器(API提供者)-步骤(K)上进行之前完成。

最后,资源服务器可以将收到的访问令牌传递到用户信息端点获取ID标记与相关(允许)申请最终用户——步骤(L) & (M)。处理才能进行API请求和响应可以回到RP(作为API的消费者在这种情况下)。

下面的序列图中描述了我们刚刚走过的相同场景。


你可能感兴趣的:(SAML2 vs JWT:理解OpenID连接第2部分)