欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-01-26 22:14:58
5 声明(Claims) 这一节说明客户端如何获取关于终端用户声明和验证事件。它还定义了一组标准的基本声明配置。预定义一组可请求的声明,使用特定的scope值或能用于请求参数中的个人声明。声明可以直接来自OpenID提供者或分布式来源。 5.1 标准声明(Standard Claims) 这个规范定 ......

5 声明(claims)

这一节说明客户端如何获取关于终端用户声明和验证事件。它还定义了一组标准的基本声明配置。预定义一组可请求的声明,使用特定的scope值或能用于请求参数中的个人声明。声明可以直接来自openid提供者或分布式来源。

 

5.1 标准声明(standard claims)

这个规范定义了一组标准的声明。他们可以请求的返回或用户信息的响应,此在 5.3.2节或在第二节中的id token。

sub string

在发行人终端用户的主体标识符。

name  string

终端用户的全名,显示的形式包括所有名称部分,可能包括标题和后缀,根据终端用户的区域设置和偏好排序。

given_name string

名字(s)或终端用户的名字(s)。注意,在一些文化中,人们可以有多个名字; 都可以存在,名字被空格字符分开。

family_name string

姓(s)或终端用户的姓(s)。注意,在一些文化中,人们可以有多个家庭的名字或没有姓; 都可以存在,名字被空格字符分开。

middle_name string

终端用户的中间名(s)。注意,在一些文化中,人们可以有多个中间的名字; 都可以存在,名字被空格字符分开。还要注意,在一些文化中,中间的名字存在。

nickname string

 终端用户的昵称可能是也可能不是与 given_name相同。例如,迈克的昵称可能是迈克尔的 given_name。

preferred_username string

简写名称由终端用户希望在rp中参考,如 janedoe 或 j.doe 。这个值可以是任何有效的json字符串包括等特殊字符 @ ,/或空格。rp不能要求这个值是独一无二的,此在 5.7节 讨论。

profile string

终端用户的概要文件页面的url。这个web页面的内容应该是关于终端用户的。

picture string

终端用户的概要文件的url。这个url必须引用一个图像文件 (例如,一个png、jpeg或gif图像文件),而不是包含图像的web页面。注意,这个url应该具体参考概要文件终端用户的照片,适合显示在终端用户描述中,而不是由用户任意拍照。

website string

url的终端用户的网页或博客。这个网页应该包含终端用户发布的信息 或表示终端用户隶属于一个组织。

email string

终端用户的首选电子邮件地址。其值必须符合 rfc 5322  addr-spec语法。rp不能信任这个值是独一无二的,此在 5.7节讨论。

email_verified boolean

true,如果终端用户的电子邮件地址已经验证,否则为false。当这个声明值为真,这意味着op采取了积极的措施,确保这个电子邮件地址在执行验证时是由用户控制的。验证电子邮件地址的方法是上下文相关的,依赖于信任框架或操作者的合同协议。

gender string

终端用户的性别。值定义为女或男。当两个定义值都不适用时,可以使用其他值。

birthdate string

终端用户的生日,表示为一个 iso 8601:2004 [iso8601 - 2004] yyyy-mm-dd 格式。年可能是 0000年 ,这表明它是省略了。仅呈现年,yyyy 格式是允许的。请注意,根据底层平台的日期相关的功能,仅提供年可能导致不同的月和日,实现者需要考虑这个因素,以正确处理日期。

zoneinfo string

字符串,从zoneinfo (zoneinfo) 时区数据代表终端用户的时区。例如,欧洲/巴黎 或 美国/洛杉矶。

locale string

终端用户的语言环境,表示为 bcp47 [rfc5646]语言标签。通常是一个 iso 639-1 alpha-2 [iso639 - 1] 语言代码的小写字母和一个 iso 3166-1 alpha-2[iso3166 - 1] 的大写国家代码,由一个破折号。例如,en-us 、fr-ca.。兼容性注意:有些使用的是下划线作为分隔符,而不是一个破折号,例如,en_us 依赖方,可以选择接受这种语言的语法。

phone_number string

终端用户首选的电话号码。e.164 (e.164) 建议格式的声明,例如,+ 1(425)555-1212 或 +56 (2) 687 2400。如果电话号码包含一个扩展,建议使用表示 rfc 3966 [rfc3966]扩展语法,例如,+1 (604) 555-1234;ext=5678。

phone_number_verified  boolean

true,如果终端用户的电话号码被验证;否则false。当这个值为真时,意味着op采取了积极的措施确保这个电话号码是由用户控制的执行验证。验证电话号码方式是上下文相关的,依赖于信任框架或操作者的合同协议。当为真时,phone_number 声明必须在e.164格式和任何扩展必须在rfc 3966格式表示。

address json object

终端用户的首选邮政编码。地址一个json (rfc4627) 结构,包含部分或全部5.1.1节中定义的成员 。

updated_at  number

最后一次终端用户更新时间的信息。它的值是一个json的数字代表的秒数 1970 - 01 - 01 t0:0:0z utc,以来的日期/时间来衡量。

 

5.1.1 地址声明(address claim)

地址声明代表一个实际邮寄地址。其实现时,可能只返回的一个子集,一个地址部分信息 ,这取决于信息可用性和终端用户的隐私偏好。例如,可能不会返回更细粒度的国家和地区地址信息。

实现可能仅返回一个单独字格式化字串的完整的地址,或者他们可能会返回单个组件,使用其他的子字段,字段 或者他们可能返回的。如果两个变体都返回,他们应该描述的是相同的地址,格式化指示如何处理组件字段组合。

formatted

完整的邮寄地址,格式化显示或使用邮件标签。这个字段可能包含多个行,以换行隔开。换行可以表示为一对回车/换行(“\ r \ n”)或一个换行字符(“\ n”)。

street_address

完整的街道地址的组件,其中可能包括门牌号、街道名称、 邮政信箱,多行扩展的街道地址信息。这个字段可能包含多个行,以换行隔开。换行可以表示为一对回车/换行(“\ r \ n”)或一个换行字符(“\ n”)。

locality

本地化:城市或本地组件。

region

区域:国家,省,县或地区组件。

postal_code

邮政编码或邮政编码组件。

country

国家名称组件。

 

5.1.2 附加声明(additional claims)

虽然本规范仅将一小部分声明定义为标准声明,其他声明可以与标准声明一起使用。当使用这样的声明,建议 collision-resistant名称用于声明的名字,如json web token(jwt) jwt规范中描述的那样。另外, 在jwt规范中所描述的命名不太可能出现冲突时,私有的声明可以安全地使用。或者,如果特定的附加声明将有广泛和普遍适用性,则可以根据jwt规范以注册声明那样进行注册。

 

5.2声明语言和脚本(claims languages and scripts)

 

人类可读的声明值和参照人类可读声明值,可能出现在多种语言和脚本中。对于特定语言和脚本,bcp47 [rfc5646]语言被添加到成员的名字标签,由一个分隔开的 # 的风格。例如,family_name # ja-kana-jp 表达了日本的姓名中片假名,常用的索引并代表相同的汉字的语音表示,表示为 family_name # ja-hani-jp 。另外一个可能会返回值例子: website and website#de声明,表明为一个未指明的语言网站和一个德国网站。

因为名称区分大小写,强烈推荐,语言中使用的标记值名称拼写使用要求风格与他们注册的iana语言标记注册表 [iana.language]一致。特别的,通常语言名称用小写字母拼写,地区名称以大写字符拼写,脚本是拼写和大小写混合字符。然而,由于bcp47语言标签值区分大小写,实现应该解释语言以区分大小写的方式提供的标签值。

按照bcp47的建议,主张语言标签值只应根据具体需要。例如,使用 fr 可能就足够了,在许多情况下,而不是 fr-ca或 fr-fr。在可能的情况下,ops应该尽量匹配要求声明地区声明。例如,如果客户要求声明一个de (德国)语言标签和op有一个值标记 de-ch (瑞士德语)不是一般意义上的德国,它将适合op 瑞士德语值返回给客户机。(这有意移动标记语言的复杂性,op尽可能匹配,简化客户。)

 

openid connect定义了以下授权请求参数,通过返回的声明激活特定的首选语言和脚本:

claims_locales

可选的。终端用户的首选语言和脚本返回,表示为一个空格分隔的列表 bcp47 rfc5646语言标记值,按偏好排序。如果openid提供者不支持一些或所有的请求的区域设置应该返回错误。

当op决定通过 claims_locales 参数,或通过其他方式,终端用户和客户 请求声明只有一组语言和脚本,建议当他们使用这个语言和脚本,ops回报没有语言标签声明。也建议以客户书面的方式说明他们可以处理和利用声明使用语言标记。

 

5.3 用户信息终结点(userinfo endpoint)

用户信息的终结点是返回关于验证用户的oauth 2.0受保护资源。获得关于终端用户的请求,客户端发出请求的用户信息通过openid connect验证的access token至终结点。这些声明通常是一个json对象,其中包含表示声明的名称和值对集合。

用户信息终结点通信必须使用tls。参看 16.17节关于使用tls的更多信息。

用户信息的终结点必须支持的使用rfc 2616 [rfc2616]中定义的http get 和 http post 方法。

用户信息的终结点必须接受使用如oauth 2.0无记名令牌的access token [rfc6750]。

userinfo终结点应该支持使用跨源资源共享(cors)和或其他方法使java脚本客户能访问终结点。

 

5.3.1 用户信息请求(userinfo request)

客户端使用 http get 或http post发送用户信息请求。openid connect 验证的请求获得的access token必须被作为持票人令牌发送(oauth 2.0无记名令牌用法 [rfc6750])。

建议请求使用 http get 方法和使用授权头字段发送access token。

下面是一个非规范化用户信息请求的例子:

  get /userinfo http/1.1

  host: server.example.com

  authorization: bearer slav32hkkg

 

5.3.2 成功的用户信息的响应(successful userinfo response)

userinfo声明必须返回一个json对象的成员,除非在客户机注册期间请求签名或加密响应。定义在5.1节声明可以返回,并可以有没有指定的额外声明。

出于隐私原因,openid提供者可能选择不返回某些请求声明。

如果不返回声明,声明的名字应当省略其在json对象中代表的声明,不应出现一个null或空字符串。

sub(subject)声明包含在用户信息的响应中,必须始终返回。

注意:由于令牌替换攻击的可能性 (见 16.11节 ),用户信息的响应是没有保证的,终端用户确定的 sub(subject) 元素的id token。在用户信息响应的sub必须验证,并完全匹配于id token的sub; 如果它们不匹配,就不能使用用户信息的响应值。

在收到用户信息请求,用户信息终结点必须返回13.3节中http响应body,并json序列化响应的用户信息,除非在注册过程中指定不同的格式 (openid.registration) 。用户信息的终结点必须返回一个内容类型头来表示返回格式。http响应必须的内容类型 application/json 如果body的响应是一个文本json对象; body应该使用utf-8编码的响应。

如果用户信息的响应 签名和/或加密,那么声明jwt和返回内容类型必须是application/jwt。响应可能加密也没有被签名。如果两个签名和加密请求,响应必须签名然后加密,结果是一个嵌套jwt 。

如果签名,用户信息的响应应该包含声明 iss (发行人) 和 aud (消费者)成员。iss 值应该是op的发布者标识符的url。aud 值应该是或包括rp的客户机id值。

下面是一个非规范化用户信息的响应的例子:

  http/1.1 200 ok

  content-type: application/json

  {

   "sub": "248289761001",

   "name": "jane doe",

   "given_name": "jane",

   "family_name": "doe",

   "preferred_username": "j.doe",

   "email": "janedoe@example.com",

   "picture": "http://example.com/janedoe/me.jpg"

  }

 

5.3.3 用户信息错误响应(userinfo error response)

当发生一个错误条件时,用户信息终结点的返回错误响应在oauth 2.0 bearer token usage [rfc6750]第三节中定义。和rfc 6750(http错误返回给用户代理使用适当的http状态码。)

下面是一个非规范化用户信息错误的响应的例子:

  http/1.1 401 unauthorized

  www-authenticate: error="invalid_token",

    error_description="the access token expired"

 

5.3.4 用户信息响应确认(userinfo response validation)

客户端必须验证用户信息的响应如下:

1、验证op响应是op 通过tls服务器证书检查,遵循rfc 6125 [rfc6125]。

2、如果客户在注册期间提供了 userinfo_encrypted_response_alg 参数,用指定的在注册过程中的键对用户信息进行解密的响应。

3、如果响应签名,客户端应该根据签名验证jws。

 

5.4 请求声明使用的scope值(requesting claims using scope values)

openid connect客户端使用范围值,在oauth 2.0 (rfc6749) 3.3节中定义,指定正在请求具有什么访问权限的access token。相关的范围指定access token确定哪些用于访问oauth 2.0保护终结点可用的资源。使用请求access token,受保护的资源终结点可能执行不同的动作和基于scope值和其他参数时返回不同的信息。

openid connect,scopes可用于要求特定的可用声明信息集。

授权服务器声明请求的以下scopes声明。

openid connect定义如下请求声明范围:

profile

可选的。scope值请求访问终端用户的默认的配置,他们是:name,family_name,given_name,middle_name,nickname,preferred_username,profile,picture,website,gender,birthdate,zoneinfo,locale,and updated_at。

email

可选的。scope值访问请求的电子邮件和email_verified声明。

address

可选的。scope值访问请求的地址声明。

phone

可选的。scope的 phone_number 和 phone_number_verified 声明。

 

多个scope值可以通过空隔符分隔,并且是大小敏感的ascii scope值。

 

用于声明请请求的profile, email, address, and phone,用户信息的终结点返回的scope,在 5.3.2节中描述 ,当使用一个发布的access token结果中的 response_type 值。然而,当没有access token (这种情况 response_type 值是id_token ),声明结果将从id token中返回。

在某些情况下,终端用户将选择婉拒openid提供者提供部分或全部rps请求信息。以最少量信息公开给终端用户请求,rp只能选择从用户终结点请求可用信息的子集。

下面是一个非规范化未编码scope请求的例子:

  scope=openid profile email phone

 

5.5 使用“声明”请求参数的请求声明(requesting claims using the "claims" request parameter)

openid connect定义了以下可用的独立声明的授权请求参数,并指定适用于请求声明参数:

claims

可选的。这个参数是用来返回特定请求声明。其值是一个请求声明的json对象列表。

声明验证请求参数要求特定被用户信息返回的终结点和/或id token。它表示为json对象,包含从这些位置的声明请求列表,请求的声明属性也可以指定。

对声明参数的支持是可选的。如果op不支持这个参数,并且rp使用它,op应该向rp返回一组声明,它认为这些声明对rp和最终用户有用,并使用它认为合适的启发式方法。 claims_parameter_supported发现结果指示op是否支持此参数。

声明参数值,表示为oauth 2.0请求的utf-8编码加密的json (最终被form-urlencoded当作为一个oauth参数传递)。请求对象中使用值,是在 定义在6.1节,json用作声明成员的值。。

*声明请求json对象的成员有:

userinfo

可选的。要求列出从用户信息的终结点返回的个人声明。如果存在,声明列表被要求添加任何声明被使用scope值请求。如果不存在,则声明从用户信息请求的终结点,只有那些要求使用的scope值。

当使用用户信息成员,请求必须使用 response_type 值,结果在一个被使用用户信息的终结点发布到客户机的access token。

id_token

可选的。要求列出返回id token的个人声明。如果存在,声明列表被请求添加至默认id token默认声明。如果不存在,则默认id token声明请求,根据第二节id token定义和每个附加流程中3.1.3.6、3.2.2.10、3.3.2.11 、3.3.3.6的id token要求。

可能存在其他成员。必须忽略使用任何不理解的成员。

声明请求一个例子如下:

  {

   "userinfo":

    {

     "given_name": {"essential": true},

     "nickname": null,

     "email": {"essential": true},

     "email_verified": {"essential": true},

     "picture": null,

     "http://example.info/claims/groups": null

    },

   "id_token":

    {

     "auth_time": {"essential": true},

     "acr": {"values": ["urn:mace:incommon:iap:silver"] }

    }

  }

请注意,声明不是标准中定义的设置 (5.1节 (例子)) http://example.info/claims/groups 声明,被请求。使用声明参数仅令是请求声明以外的标准设置的方法。也是请求标准声明不能使用范围指定值的特定组合的唯一途径。

 

5.5.1 个人声明请求(individual claims requests)

用户信息和id_token声明成员,都是json对象请求,个人声明的名字被请求作为成员的名字。成员的值必须是下列之一:

null

表明,这种声明被要求以默认方式。特别是,这是一个自愿协议声明。例如,声明请求:

  "given_name": null

以默认的方式请求 given_name 声明。

json object

用于提供关于附加信息请求的声明。本规范定义了以下成员:

essential

可选的。指示是否被请求声明是一个重要的声明。如果该值为真 ,表明声明是一个重要的声明。例如,声明请求:

  "auth_time": {"essential": true}

特指返回auth_time 声明是很重要的。

如果该值为false ,表明这是一个自动的声明。默认值是false 。

通过请求声明作为必要的声明,rp指示终端用户,允许发表这些声明,确保终端用户要求的特定任务顺利授权。注意,即使没有因为终端用户中没有授权发布或不存在,当声明无返回,授权服务器不能产生一个错误,如果他们是必要或自动的,除非另有说明对于特定要求的描述。

value

可选的。请求声明返回特定值。例如声明请求:

  "sub": {"value": "248289761001"}

可用于指定请求适用于终端用户附加subject标识符 248289761001 。

value成员值必须是一个有效的声明请求。个人声明的定义,可以包含要求如何以及是否 value 限定符是用于声明请求。

values

可选的。请求声明返回一组值中的一个,values以优先顺序排列出现。例如声明请求:

  "acr": {"essential": true,

          "values": ["urn:mace:incommon:iap:silver",

                     "urn:mace:incommon:iap:bronze"]}

指定是十分必要的。acr声明返回 "urn:mace:incommon:iap:silver",  "urn:mace:incommon:iap:bronze"之一。

values 数组成员,必须是有效的声明请求值。个人声明的定义可以包含要求如何以及是否values限定符是用于当要求声明。

其他成员可能会提供额的关于请求声明的信息。必须忽略使用任何不能理解的成员。

注意,当声明请求参数支持,请求声明scope值,定义在 5.4节 有效地简化个人请求的方式。例如,使用scope值 openid的email 和response_type 返回一个access token,相当于使用scope值 openid 和如下个人声明请求。

相当于使用 email的 scope值:

  {

   "userinfo":

    {

     "email": null,

     "email_verified": null

    }

  }

 

5.5.1.1 “acr”请求声明(requesting the "acr" claim)

如果 acr 声明请求作为id token基本声明,此令牌有values参数,并要求特定的验证上下文类值和引用实现支持声明参数,授权服务器必须返回一个 acr 声明值中相匹配请求的值中的一个。授权服务器可以要求终端用户使能满足需求的附加条件重新认证。如果这是一个重要的声明和需求无法满足,则授权服务器必须以验证未遂不成功来对待。

注意,rp请求 acr 声明作为一个自愿的声明,以使用 acr_values 请求参数或不包括“essential”:在一个独立的个体 acr 声明请求。如果声明是非基本的和不能提供请求值,授权服务器应该返回当前会话的 acr 作为acr声明值。如果声明不是必须的,授权服务器不需要提供这一声明响应。

如果客户机同时使用 acr_values 请求参数和一个个人acr声明(id token清单中特定请求值),请求 acr 声明,产生的行为是不确定的。

 

5.5.2  个人声明的语言和脚本(languages and scripts for individual claims)

如5.2节中描述的, 可读的声明值和声明值引用可读的值,可以用多种语言和脚本。在个人声明请求,要求特定的声明可能包括声明请求的名称语言和脚本,包含 #-separated bcp47 [rfc5646]语言的声明请求标签 ,使用5.2节声明中指定名称的语法 。例如,可以使用name声明 family_name#ja- jp 请求日语片假名中的姓,也可以使用name声明 family_name#ja-hani-jp请求日语中该姓的汉字表示。可以使用name声明website#de请求德语网站。

如果op接收到它没有的可读的声明请求的语言和脚本,则返回的那些声明的任何版本,如果不使用所请求的语言和脚本,则应该在声明名称中使用语言标记。

 

5.6 声明类型(claim types)

该规范定义的三种声明表象值是:

normal claims(标准声明)

openid提供者直接定义的声明。

aggregated claims(聚合的声明)

openid提供者以外的声明提供值者定义,但由openid提供者返回的。

distributed claims(分布式声明)

openid提供者以外的声明提供值者定义,但由openid提供者参照返回的。

标准声明必须支持。聚合声明和分布式声明的支持是可选的。

 

5.6.1标准声明(normal claims)

标准声明表示为json对象的成员。声明的名字是成员名和值是成员的值。

下面是一个非规范化包含标准声明响应:

  {

   "name": "jane doe",

   "given_name": "jane",

   "family_name": "doe",

   "email": "janedoe@example.com",

   "picture": "http://example.com/janedoe/me.jpg"

  }

 

5.6.2 聚合和分布式声明(aggregated and distributed claims)

聚合和分布式声明使用特殊的 _claim_names 和 _claim_sources 成员包含声明的json对象表示。

_claim_names

json对象的成员名字是声明聚合的名称和分布声明。_claim_sources 的成员值引用成员名字,实际可以检索的声明值。

_claim_sources

json对象的_claim_names 成员名称引用的成员的值。成员的值包含组聚合声明或参考本地化分布式声明。成员可以有一个以下格式的值,取决于是否提供聚合或分布式声明:

aggregated claims

json对象必须包含 jwt成员,此成员必须包含所有的在 _claim_names 对象引用和相应的 _claim_sources 成员的声明。也可能存在其他成员。必须忽略使用的任何不理解的成员。

jwt

必需的。jwt包含值。

jwt不应该包含一个 sub(subject) 声明,除非它的值是一个标识符为终端用户声明提供者(而不是为openid提供者或另一方);这通常意味着不应该被提供一个sub声明。

distributed claims

json对象,包含以下成员和值:

endpoint

必需的。oauth 2.0资源关联的声明可以检索的终结点。终结点url必须以jwt声明返回。

access_token

可选的。access token可以通过使用 oauth 2.0无记名令牌用法 (rfc6750) 协议从终结点url检索的声明。声明应该要求使用授权请求头字段和声明供应者必须支持的方法。如果access token不可用, rps可能需要检索access token之外的或使用一个提供者和rp之间预先商谈好的access token,或声明提供者可能重认证的 终端用户和/或rp重新授权。

一个 sub(subject)声明不应该从提供者返回,除非它的值是一个标识符为终端用户声明提供者(而不是为openid提供者或另一方); 这通常意味着不应该被提供一个sub声明。

一般来说,当op时适当使用聚合声明和分布式声明。在某些情况下,使用的声明信息类型可能是rps 和ops另外协商好的。

 

5.6.2.1 聚合声明例子(example of aggregated claims)

在这个非规范化的例子中,声明从声明供应者a结合其他声明持有的openid提供者, 声明从声明供应者a作为聚合声明返回。

在这个例子中,这些关于jane doe已签发声明提供者a:

  {

   "address": {

     "street_address": "1234 hollywood blvd.",

     "locality": "los angeles",

     "region": "ca",

     "postal_code": "90210",

     "country": "us"},

   "phone_number": "+1 (310) 123-4567"

  }

声明提供a签名了json声明,代表他们签名了jwt: jwt_header.jwt_part2.jwt_part3。这正是openid提供者使用的jwt。

在这个例子中,这个jwt包含jane doe的从声明供应商a结合其他标准声明的聚合声明,并返回以下的声明设置:

  {

   "name": "jane doe",

   "given_name": "jane",

   "family_name": "doe",

   "birthdate": "0000-03-22",

   "eye_color": "blue",

   "email": "janedoe@example.com",

   "_claim_names": {

     "address": "src1",

     "phone_number": "src1"

   },

   "_claim_sources": {

     "src1": {"jwt": "jwt_header.jwt_part2.jwt_part3"}

   }

  }

 

5.6.2.2分布式声明的例子(example of distributed claims)

在这个非规范化的例子中,openid提供者结合它拥有对引用的声明来自两个不同的声明供应商,b和c的标准声明,将来自于b和c的声明合并引用为分布声明。

在这个例子中, 由提供者b持有的关于jane doe持有的声明(jane doe的银行):

  {

   "shipping_address": {

     "street_address": "1234 hollywood blvd.",

     "locality": "los angeles",

     "region": "ca",

     "postal_code": "90210",

     "country": "us"},

   "payment_info": "some_card 1234 5678 9012 3456",

   "phone_number": "+1 (310) 123-4567"

  }

同样在这个例子中, 由提供者c持有的关于jane doe(信贷机构):

  {

   "credit_score": 650

  }

openid提供者返回jane doe的随着引用了提供者b和c两个声明提供者的声明,通过发送的access token及分布式声明可以检索的urls位置:

  {

   "name": "jane doe",

   "given_name": "jane",

   "family_name": "doe",

   "email": "janedoe@example.com",

   "birthdate": "0000-03-22",

   "eye_color": "blue",

   "_claim_names": {

     "payment_info": "src1",

     "shipping_address": "src1",

     "credit_score": "src2"

    },

   "_claim_sources": {

     "src1": {"endpoint":

                "https://bank.example.com/claim_source"},

     "src2": {"endpoint":

                "https://creditagency.example.com/claims_here",

              "access_token": "ksj3n283dke"}

   }

  }

 

 

5.7 声明的稳定性和唯一性(claim stability and uniqueness)

sub(主题)和iss (发行人)声明,一起使用, 成为唯一声明,是rp可以依靠稳定的终端用户标识符,因此sub声明必须是本地独特而从未在发行人为特定的用户重新分配,如第二节中描述。因此,只有sub(主题)和iss (发行人)声明保证给组合定用户的惟一标识符。

其他所有的声明对于不同的发行人而言,在用户稳定时间和独特性,并允许发布者应用局部限制和策略上没有此类担保。例如,一个发行人可能重用一个 电子邮件声明值给不同终端用户,在不同的时间点,随着时间的推移,电子邮件对于一个给定的用户可能会改变地址。因此,诸如其他像电子邮件的声明,phone_number ,preferred_username ,也不能作为终端用户的惟一标识符。