单点登陆(SSO)协议简介:OpenID、OAuth2、SAML

1 OpenID

1.1 OpenID Connect(OIDC)

  OpenID是Authentication,即认证,对用户的身份进行认证,判断其身份是否有效,也就是让网站知道“你是你所声称的那个用户”;   OAuth是Authorization,即授权,在已知用户身份合法的情况下,经用户授权来允许某些操作,也就是让网站知道“你能被允许做那些事情”。   只有在确定用户身份之后才能进行授权。 即 身份验证+QAuth 2.0 = OpenID Connect

1.2 OIDC流程

  OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;相似的,OIDC在这个基础上提供了ID Token来解决第三方客户端标识用户身份认证的问题。   其核心在于OAuth 2.0流程中,一并提供用户的身份认证信息(ID-Token)给到第三方客户端,ID-Token使用JWT格式来包装。JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID-Token可以安全的传递给第三方客户端程序并且容易被验证。

1.3 授权模式流程

  按照以上的例子,流程如下:

  1. Process On使用Access-Token发送一个请求到UserInfo EndPoint; UserInfo EndPoint返回用户的Claims

1.3.1 认证请求

  应用使用OAuth2的Authorization-Code的方式来完成用户身份认证,构建一个OIDC的Authentication Request需要提供如下的参数:scope,response_type,client_id,redirect_uri,state。

1.3.2 请求响应

1.3.3 获取ID Token

  Process On使用上面获取的code来请求token接口(Token EndPoint),之后接口返回响应的Token,其中除了OAuth2规定的部分数据外,还会附加一个id_token的字段。 例如:

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"
  }

上面的乱码就是JWT格式的id_token 在RP拿到这些信息之后,需要对id_token以及access_token进行验证。到此基本完成了认证。

1.3.4 id_token的构成

iss = Issuer Identifier:必须。提供认证信息者的唯一标识。一般是Url的host+path部分; sub = Subject Identifier:必须。iss提供的EU的唯一标识;最长为255个ASCII个字符; aud = Audience(s):必须。标识ID-Token的受众。必须包含OAuth2的client_id; exp = Expiration time:必须。ID-Token的过期时间; iat = Issued At Time:必须。JWT的构建的时间。 auth_time = AuthenticationTime:EU完成认证的时间。如果RP发送认证请求的时候携带max_age的参数,则此Claim是必须的。 nonce:RP发送请求的时候提供的随机字符串,用来减缓重放攻击,也可以来关联ID-Token和RP本身的Session信息。 acr = Authentication Context Class Reference:可选。表示一个认证上下文引用值,可以用来标识认证上下文类。 amr = Authentication Methods References:可选。表示一组认证方法。 azp = Authorized party:可选。结合aud使用。只有在被认证的一方和受众(aud)不一致时才使用此值,一般情况下很少使用。

{
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "auth_time": 1311280969,
   "acr": "urn:mace:incommon:iap:silver"
  }

2 OAuth 2.0

3 SAML

经验分享 程序员 微信小程序 职场和发展