• OpenID Connect是什么?OpenID Connect(目前版本是1.0)是OAuth 2.0协议(可参考本人此篇:OAuth 2.0 / RCF6749 协议解读)之上的简单身份层,用 API 进行身份交互的框架,允许客户端根据授权服务器的认证结果最终确认用户的身份,以及获取基本的用户信息;它支持包括Web、移动、JavaScript在内的所有客户端类型;它是可扩展的协议,允许你使用某些可选功能,如身份数据加密、OpenID提供商发现、会话管理
  • OpenID Connect vs OpenID 2.0:OpenID Connect完成很多与OpenID 2.0相同的任务,是API-friendly,定义了可选的签名和加密的机制;OAuth 1.0a和OpenID 2.0的集成需要扩展,而OpenID Connect协议本身就建立在OAuth 2.0之上
  • 部分名词解释
    1. Relying Party(RP):依赖方,通常是第三方应用程序(客户端)
    2. OpenID Provider(OP):OpenID 提供方,通常是一个 OpenID 认证服务器,它能为依赖方提供断言以证实用户拥有某个标识
    3. End-User(EU):终端用户,指持有账号的人
  • OpenID Connect协议构成
    1. Core – 定义 OpenID Connect 核心功能: 认证建立在OAuth 2.0之上,使用声明与终端用户进行信息交互
    2. Discovery – (Optional) Defines how Clients dynamically discover information about OpenID Providers
    3. Dynamic Registration – (Optional) Defines how clients dynamically register with OpenID Providers
    4. OAuth 2.0 Multiple Response Types – 定义了几种新的OAuth 2.0响应类型
    5. OAuth 2.0 Form Post Response Mode – (Optional) Defines how to return OAuth 2.0 Authorization Response parameters (including OpenID Connect Authentication Response parameters) using HTML form values that are auto-submitted by the User Agent using HTTP POST
    6. Session Management – (Optional) Defines how to manage OpenID Connect sessions, including postMessage-based logout functionality
    7. Front-Channel Logout – (Optional) Defines a front-channel logout mechanism that does not use an OP iframe on RP pages
    8. Back-Channel Logout – (Optional) Defines a logout mechanism that uses direct back-channel communication between the OP and RPs being logged out

    下边两条是 Web RPs 实现者的独立参考指南:

    1. Basic Client Implementer’s Guide – Simple subset of the Core functionality for a web-based Relying Party using the OAuth code flow
    2. Implicit Client Implementer’s Guide – Simple subset of the Core functionality for a web-based Relying Party using the OAuth implicit flow

    协议迁移规范:

    1. OpenID 2.0 to OpenID Connect Migration 1.0 – Defines how to migrate from OpenID 2.0 to OpenID Connect

    OpenID Connect 工作组已启动新的工作计划:

    1. OpenID Connect Profile for SCIM Services – (Optional) Defines how to use SCIM with OpenID Connect
    2. OpenID Connect Federation – (Optional) Defines how sets of OPs and RPs can establish trust by utilizing a Federation Operator

  • OpenID Connect的工作流程:下以EU获取UserInfo为例来说明,
    1. RP(客户端)发送一个认证请求给OP;
    2. OP对EU进行身份认证并获得授权;
    3. OP发送ID Token给RP,通常也同时发送Access Token(为兼容OAuth 2.0。ID Token其实可以取代Access Token用来完成授权);
    4. RP使用Access Token发送一个请求UserInfo EndPoint;
    5. UserInfo EndPoint返回EU的Claims。

    下边是关于“ID Token 与 Access Token”的描述来自 User Authentication with OAuth 2.0 [UserInfo Endpoint]:

    It should be noted that clients are not required to use the access token, since the ID Token contains all the necessary information for processing the authentication event. However, in order to provide compatibility with OAuth and match the general tendency for authorizing identity and other API access in parallel, OpenID Connect always issues the ID token along side an OAuth access token.
  • ID Token:它是一种JWT(JSON Web Token)格式数据,主要由以下几部分构成:
    1. iss:必须。Issuer Identifier,OP的唯一标识,一个区分大小写的https URL,不包含query和fragment组件
    2. sub:必须。Subject Identifier,iss提供的EU的标识,在iss范围内唯一,最长为255个ASCII个字符,区分大小写
    3. aud:必须。Audience(s),标识ID Token的受众,必须包含OAuth2的client_id,分大小写的字符串数组
    4. exp:必须。Expiration time,超过此时间的ID Token会作废
    5. iat:必须。Issued At Time,JWT的构建的时间
    6. auth_time:AuthenticationTime,EU完成认证的时间。如果RP发送AuthN请求的时候携带max_age的参数,则此Claim是必须的
    7. nonce:RP发送认证请求的时候提供的随机字符串,用来减缓重放攻击,也可以用来关联客户端Session。如果nonce存在,客户端必须验证nonce
    8. acr:可选。Authentication Context Class Reference,表示一个认证上下文引用值,可以用来标识认证上下文类
    9. amr:可选。Authentication Methods References,表示一组认证方法
    10. 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"
    }

    关于协议定义Claims的更多信息参考:http://openid.net/specs/openid-connect-core-1_0.html#Claims。ID Token必须使用JWS进行签名,如果要用JWE加密也必须先进行JWS签名

  • JSON Web Signature (JWS):JSON数据进行数字签名或MACed后再经base64url编码。

    JWS Compact Serialization如下连接序列:Header.Payload.Signature

    BASE64URL(UTF8(JWS Protected Header)) || '.' ||
    BASE64URL(JWS Payload) || '.' ||
    BASE64URL(JWS Signature)
    1. JWS Protected Header
    {"typ":"JWT",
    "alg":"HS256"}
    编码后:
    eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
    2. JWS Payload
    {"iss":"joe",
    "exp":1300819380,
    "http://example.com/is_root":true}
    编码后:
    eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
    3. JWS Signature
    Signing Input value:
    eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
    .
    eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
    HMAC SHA-256 key:
    {"kty":"oct",
    "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
    }
    JWS Signature:
    dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
    4. JWS Compact Serialization
    eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
    .
    eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt
    cGxlLmNvbS9pc19yb290Ijp0cnVlfQ
    .
    dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

    JWS JSON Serialization包含如下几个部分

    1. "protected", with the value BASE64URL(UTF8(JWS Protected Header))
    2. "header", with the value JWS Unprotected Header
    3. "payload", with the value BASE64URL(JWS Payload)
    4. "signature", with the value BASE64URL(JWS Signature)

    General JWS JSON Serialization:

    {
    "payload":"<payload contents>",
    "signatures":[
    {"protected":"<integrity-protected header 1 contents>",
    "header":<non-integrity-protected header 1 contents>,
    "signature":"<signature 1 contents>"},
    ...
    {"protected":"<integrity-protected header N contents>",
    "header":<non-integrity-protected header N contents>,
    "signature":"<signature N contents>"}]
    }

    Flattened JWS JSON Serialization:

    {
    "payload": "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
    "protected":"eyJhbGciOiJFUzI1NiJ9",
    "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},
    "signature": "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"
    }
  • JSON Web Encryption (JWE)

    JWE Compact Serialization如下连接序列

          BASE64URL(UTF8(JWE Protected Header)) || '.' ||
    BASE64URL(JWE Encrypted Key) || '.' ||
    BASE64URL(JWE Initialization Vector) || '.' ||
    BASE64URL(JWE Ciphertext) || '.' ||
    BASE64URL(JWE Authentication Tag)

    JWE JSON Serialization包含如下几个部分

          1. "protected", with the value BASE64URL(UTF8(JWE Protected Header))
    2. "unprotected", with the value JWE Shared Unprotected Header
    3. "header", with the value JWE Per-Recipient Unprotected Header
    4. "encrypted_key", with the value BASE64URL(JWE Encrypted Key)
    5. "iv", with the value BASE64URL(JWE Initialization Vector)
    6. "ciphertext", with the value BASE64URL(JWE Ciphertext)
    7. "tag", with the value BASE64URL(JWE Authentication Tag)
    8. "aad", with the value BASE64URL(JWE AAD)

    General JWE JSON Serialization:

    {
    "protected":"<integrity-protected shared header contents>",
    "unprotected":<non-integrity-protected shared header contents>,
    "recipients":[
    {"header":<per-recipient unprotected header 1 contents>,
    "encrypted_key":"<encrypted key 1 contents>"},
    ...
    {"header":<per-recipient unprotected header N contents>,
    "encrypted_key":"<encrypted key N contents>"}],
    "aad":"<additional authenticated data contents>",
    "iv":"<initialization vector contents>",
    "ciphertext":"<ciphertext contents>",
    "tag":"<authentication tag contents>"
    }

    Flattened JWE JSON Serialization:

    {
    "protected":"<integrity-protected header contents>",
    "unprotected":<non-integrity-protected header contents>,
    "header":<more non-integrity-protected header contents>,
    "encrypted_key":"<encrypted key contents>",
    "aad":"<additional authenticated data contents>",
    "iv":"<initialization vector contents>",
    "ciphertext":"<ciphertext contents>",
    "tag":"<authentication tag contents>"
    }
  • JSON Web Key (JWK):JWK用于JWS和JWE中,也是一种JSON数据结构,其包含了如下几项:

    1. "kty" (Key Type) Parameter
    2. "use" (Public Key Use) Parameter
    3. "key_ops" (Key Operations) Parameter
    4. "alg" (Algorithm) Parameter
    5. "kid" (Key ID) Parameter
    6. "x5u" (X.509 URL) Parameter
    7. "x5c" (X.509 Certificate Chain) Parameter
    8. "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter
    9. "x5t#S256" (X.509 Certificate SHA-256 Thumbprint)

    形如:

         {"kty":"EC",
    "crv":"P-256",
    "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
    "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
    "kid":"Public key used in JWS spec Appendix A.3 example"
    }
  • Base64编码:Base64是基于64个可打印字母表(Table 1: The Base64 Alphabet)来表示数据的方法,可用于二进制数据如图片、视频、音频数据的转换表示,可查看RFC2045~RFC2049,上面有MIME(Multipurpose Internet Mail Extensions)的详细规范:
    1. 每3个字节一组,再按6bits(2 ^ 6 = 64)为一组分成4组,即3 * 8bits = 4 * 6bits;
    2. 以6bits的值为索引查找字母表中对应的字符。最后3字节变成4字节,长度增加33%;
    3. 对于不足3字节的情况用\x00字节补足,最后用尾部加“=”的个数来表示缺少的字节数,即Base64编码的尾部最多有1~2个“=”。

    在RFC 2045中还规定,输出每行不超过76字符(CRLF结尾):

    The encoded output stream must be represented in lines of no more than 76 characters each. All line breaks or other characters not found in Table 1 must be ignored by decoding software.

    由于+和/字符在URL中传递是不安全的,因此又出现了以-和_来替换+和/的Base64URL编码:

    由于“=”字符也可能出现在Base64编码中,但“=”用在URL、Cookie里面会造成歧义,所以很多Base64编码把“=”去掉。至于去掉“=”后如何解码呢?正常Base64编码后的序列字符数一定是4的倍数,如果结果不是,则可反推去掉了多少个“=”

  • 相关参考

    1. OIDC(OpenId Connect)身份认证授权(核心部分)

    2. RFC 7515 - JSON Web Signature (JWS)
    3. RFC 7516 - JSON Web Encryption (JWE)

    4. RFC 7517 - JSON Web Key (JWK)

OpenID Connect:OAuth 2.0协议之上的简单身份层的更多相关文章

  1. 一个功能完备的.NET开源OpenID Connect/OAuth 2.0框架——IdentityServer3

    今天推荐的是我一直以来都在关注的一个开源的OpenID Connect/OAuth 2.0服务框架--IdentityServer3.其支持完整的OpenID Connect/OAuth 2.0标准, ...

  2. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  3. OpenID Connect Core 1.0(一)介绍

    IdentityServer4是基于OpenID Connect and OAuth 2.0框架,OpenID Connect Core 1.0是IdentityServer4最重要的文档 By 道法 ...

  4. OpenID Connect Core 1.0(九)声明(Claims)

    5 声明(Claims) 这一节说明客户端如何获取关于终端用户声明和验证事件.它还定义了一组标准的基本声明配置.预定义一组可请求的声明,使用特定的scope值或能用于请求参数中的个人声明.声明可以直接 ...

  5. OpenID Connect Core 1.0(六)使用隐式验证流

    3.2 使用隐式验证流(Authentication using the Implicit Flow) 本节描述如何使用隐式流程执行验证.使用隐式流程时,所有令牌从授权终结点返回:不使用令牌终结点返回 ...

  6. OpenID Connect Core 1.0(五)使用授权码流验证(下)

    3.1.2.6 验证错误响应(Authentication Error Response) 验证错误响应是一个OAuth 2.0授权错误响应消息,是RP发送授权请求的消息,由OP授权终结点的响应返回. ...

  7. OpenID Connect Core 1.0(四)使用授权码流验证(上)

    3.1 使用授权码流验证(Authentication using the Authorization Code Flow) 本节描述如何使用授权码流执行验证.当使用授权码流时,会从令牌终结点返回的所 ...

  8. OpenID Connect Core 1.0(三)验证

    OpenID Connect执行终端用户登录或确定终端用户已经登录的验证工作.OpenID Connect 使服务器以一种安全的方式返回验证结果.所以客户可以依靠它.出于这个原因,在这种情况下客户被称 ...

  9. OpenID Connect Core 1.0(二)ID Token

    2.ID Token(ID Token) OpenID Connect主要是对OAuth 2.0 能够使得终端用户通过ID Token的数据结构进行验证.当客户端和潜在的其他请求声明,ID Token ...

随机推荐

  1. session的用法

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  2. 初学Python(五)——元组

    初学Python(五)——元组 初学Python,主要整理一些学习到的知识点,这次是元组. #-*- coding:utf-8 -*- #定义元素 t = (1,2,3) #添加元素 #删除元素 #更 ...

  3. windows本地提权对照表(转载)

    2003     systeminfo>C:\Windows\Temp\temp.txt&(for %i in (KB3057191 KB2840221 KB3000061 KB2850 ...

  4. git远程仓库之添加远程库

    现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举 ...

  5. 7种方法解决移动端Retina屏幕1px边框问题

    在Reina(视网膜)屏幕的手机上,使用CSS设置的1px的边框实际会比视觉稿粗很多.在之前的项目中,UI告诉我说我们移动项目中的边框全部都变粗了,UI把他的设计稿跟我的屏幕截图跟我看,居然真的不一样 ...

  6. CSS基础学习笔记

    一. CSS介绍 1. CSS概述:CSS(Cascading Style Sheets)指层叠样式表,极大提高了工作效率. 2. 基础语法: 属性大于1个之后,属性之间用分号隔开 如果大于1个单词, ...

  7. shiro

    1 权限管理 1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己 ...

  8. Windows开发笔记-错误处理

    Windows函数为开发者提供了错误代码,这样当调用Windows函数失败后,可以通过查看错误代码了解错误信息.相应的错误与主调线程关联在一起,这种机制使得不同的线程能够独立运行而不会相互干扰.调用G ...

  9. DB2的日志理解难点

    在DB2中最早的recovery时间点,是由minBuffLsn 和 lowTranLsn 的最小值决定的. minBuffLsn: represents the oldest change to a ...

  10. 统计s="hello alex alex hello haiyan cc haiyan com"中每个单词的个数

    这个题可以有好几种解题方法. 一.索引值获取 s="hello alex alex hello haiyan cc haiyan com" l=s.split() dic={} f ...