一、OIDC简介
OIDC是OpenID Connect的简称,OIDC=(Identity, Authentication) + OAuth 2.0。它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。OAuth2是一个授权协议,它无法提供完善的身份认证功能,OIDC使用OAuth2的授权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端(比如服务端应用,移动APP,JS应用),且完全兼容OAuth2,也就是说你搭建了一个OIDC的服务后,也可以当作一个OAuth2的服务来用。
二、OIDC的核心概念
OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID Token)给到第三方客户端,ID Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。此外还提供了UserInfo的接口,用于获取用户的更完整的信息。
三、OIDC的认证流程

主要角色:
EU(End User):一个人类用户。
RP(Relying Party ): 用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
OP(OpenID Provider):有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
ID Token:JWT格式的数据,包含EU身份认证的信息。
UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS。
流程简述:
四、ID_Token概念
4.1)ID Token的主要构成部分(使用OAuth2流程的OIDC):
| 字段 | 释义 |
|---|---|
| iss (Issuer Identifier) | 必须。提供认证信息者的唯一标识。一般是一个https的url(不包含querystring和fragment部分)。 |
| sub (Subject Identifier) | 必须。iss提供的EU的标识,在iss范围内唯一。它会被RP用来标识唯一的用户。最长为255个ASCII个字符。 |
| aud (Audience) | 必须。标识ID Token的受众。必须包含OAuth2的client_id。 |
| exp (Expiration time) | 必须。过期时间,超过此时间的ID Token会作废不再被验证通过。 |
| iat (Issued At Time) | 必须。JWT的构建的时间。 |
| auth_time (AuthenticationTime) | EU完成认证的时间。如果RP发送AuthN请求的时候携带max_age的参数,则此Claim是必须的。 |
| nonce | RP发送请求的时候提供的随机字符串,用来减缓重放攻击,也可以来关联ID Token和RP本身的Session信息。 |
| acr (Authentication Context Class Reference) | 可选。表示一个认证上下文引用值,可以用来标识认证上下文类。 |
| amr (Authentication Methods References) | 可选。表示一组认证方法。 |
| azp (Authorized party) | 可选。结合aud使用。只有在被认证的一方和受众(aud)不一致时才使用此值,一般情况下很少使用。 |
| ID Token通常情况下还会包含其他的Claims(毕竟上述claim中只有sub是和EU相关的,这在一般情况下是不够的,必须还需要EU的用户名,头像等其他的资料,OIDC提供了一组公共的cliams)。另外ID Token必须使用JWS进行签名和JWE加密,从而提供认证的完整性、不可否认性以及可选的保密性。 | |
| 一个ID Token的例子如下: |
{
"iss": "https://example.com", "sub": "111", "aud": "s6BbKhgqt7", "nonce": "n-0S6_WzA2Mj", "exp": , "iat": , "auth_time": , "acr": "urn:mace:incommon:iap:silver" }
五、OIDC的认证模式
OIDC如何获取到ID Token?
因为OIDC基于OAuth2,所以OIDC的认证流程主要是由OAuth2的几种授权流程延伸而来的:
OAuth2中还有基于Resource Owner Password Credentials Grant(密码模式)和Client Credentials Grant(客户端模式)的方式来获取Access Token,为什么OIDC没有扩展这些方式呢?
5.1)基于Authorization Code(授权码模式)的认证
5.1.1)基于Authorization Code(授权码模式)的认证请求
- scope:必须。OIDC的请求必须包含值为“openid”的scope的参数。
- response_type:必选。同OAuth2。
- client_id:必选。同OAuth2。
- redirect_uri:必选。同OAuth2。
- state:推荐。同OAuth2。防止CSRF, XSRF。
以上这5个参数是和OAuth2相同的。除此之外,还定义了如下的参数:
- response_mode:可选。OIDC新定义的参数(OAuth 2.0 Form Post Response
Mode),用来指定Authorization Endpoint以何种方式返回数据。 - nonce:可选。ID Token中的出现的nonce就是来源于此。
- display :
可选。指示授权服务器呈现怎样的界面给EU。有效值有(page,popup,touch,wap),其中默认是page。page=普通的页面,popup=弹出框,touch=支持触控的页面,wap=移动端页面。 - prompt:可选。这个参数允许传递多个值,使用空格分隔。用来指示授权服务器是否引导EU重新认证和同意授权(consent,就是EU完成身份认证后的确认同意授权的页面)。有效值有(none,login,consent,select_account)。none=不实现现任何认证和确认同意授权的页面,如果没有认证授权过,则返回错误login_required或interaction_required。login=重新引导EU进行身份认证,即使已经登录。consent=重新引导EU确认同意授权。select_account=假如EU在授权服务器有多个账号的话,允许EU选择一个账号进行认证。
- max_age:可选。代表EU认证信息的有效时间,对应ID
Token中auth_time的claim。比如设定是20分钟,则超过了时间,则需要引导EU重新认证。 - ui_locales:可选。用户界面的本地化语言设置项。
- id_token_hint:可选。之前发放的ID Token,如果ID
Token经过验证且是有效的,则需要返回一个正常的响应;如果有误,则返回对应的错误提示。 - login_hint:可选。向授权服务器提示登录标识符,EU可能会使用它登录(如果需要的话)。比如指定使用用户使用blackheart账号登录,当然EU也可以使用其他账号登录,这只是类似html中input元素的placeholder。
- acr_values:可选。Authentication Context Class Reference values,对应ID
Token中的acr的Claim。此参数允许多个值出现,使用空格分割。
以上是基于Authorization Code方式的OIDC的认证请求所需的参数。在OIDC的其他认证流程中也会有其他的参数或不同的参数值(稍有差异)。
示例请求串:
5.1.2)基于Authorization Code(授权码模式)的认证请求的响应
5.1.3)ID_Token的获取
RP使用上一步获得的code来请求Token EndPoint,这一步同OAuth2,就不再展开细说了。然后Token EndPoint会返回响应的Token,其中除了OAuth2规定的部分数据外,还会附加一个id_token的字段。id_token字段就是上面提到的ID Token。例如:
在RP拿到这些信息之后,需要对id_token以及access_token进行验证(具体的规则参见http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation和http://openid.net/specs/openid-connect-core-1_0.html#ImplicitTokenValidation)。
5.2)Implicit (简化模式)和Hybrid(混合模式)
Implicit (简化模式)的工作方式是在OAuth2 Implicit上附加提供id_token,认证请求的参数和基于Authorization Code(授权码模式)的流程稍有不同,具体的差异参考http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest。
Hybrid(混合模式)则相当于Authorization Code(授权码模式)+Implicit (简化模式)。
六、UserInfo Endpoint
响应:
其中sub代表EU(End User)的唯一标识,这个claim是必须的,其他的都是可选的。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177355.html原文链接:https://javaforall.net
