UAA 的高级功能

    精彩文章,何不与朋友分享

[译注]本文翻译自Cloud Foundry英文博客站点,原文题为“High Level Features of the UAA”,文章发表时间是 2012 年 07 月 24 日。

Cloud Foundry 中的用户帐户和身份验证服务 (UAA) 负责保护平台服务的安全及对 Web 应用程序进行单点登录。上一篇文章介绍了 UAA 并将其放在平台环境中,在本文中,我们将对其进行更深入的阐述,并分别介绍 UAA 的各项功能:

集中式身份管理

要代表用户执行操作(例如查看应用程序或将应用程序推送到用户的 Cloud Foundry 帐户)的应用程序需要验证用户在平台的身份。由于 Cloud Foundry 的安全通常是通过用户名(电子邮件)和密码来保护,提供这种保护的一个方法是要求用户提供凭据并将凭据转发给云控制器。由于以下两个原因,这种做法并不可取:

  1. 带来安全威胁。如果用户总是一成不变地被引导在任何声称能提供平台相关服务的旧应用程序中输入密码,则没有任何方法能够阻止此类应用程序窃取凭据并擅自使用。
  2. 这种方法将平台限制为始终并且仅支持以用户名和密码的方式进行身份验证。这是体系结构性的弱点,而且许多 Cloud Foundry 用户可能并非希望如此,尤其是企业安装的用户。

集中式身份管理是一种先进的方法。应该有一个位置,用户知道在此可以进行身份验证,并且没有将密码泄露给欺诈应用程序的风险。应以集中方式确定身份验证机制,而不依赖于使用该机制的任何应用程序。这就是 UAA 的作用。

单点登录

由于采用集中方式,UAA 可以为 Cloud Foundry 平台中的应用程序提供单点登录 (SSO) 服务。cloudfoundry.com 平台有若干个 UI 组件,这些组件需要安全保护,委派给 UAA 进行身份验证。例如支持站点Micro Cloud Foundry 站点。(核心 Cloud Foundry 开源平台中没有其他组件具有 UI,因此除非平台超出核心使用范围,否则并不真正需要具有 SSO 功能。)

需要 SSO 的 UI 组件使用 UAA 中的 /userinfo 端点,该端点只是受 OAuth2 保护的常规资源(充当资源服务器的 UAA 示例)。以下是 devuaa 实例的示例输出,其中 TOKEN 已设置为有效的 OAuth2 访问令牌:

$ curl -H "Authorization:Bearer $TOKEN" http://devuaa.cloudfoundry.com/userinfo { "user_id":"fb180054-9cbb-441d-96e7-5c3d65861e9c", "user_name":"marissa", "given_name":"Marissa", "family_name":"Bloggs", "name":"Marissa Bloggs", "email":"marissa@test.org" }

如果调用方尝试在没有有效访问令牌的情况下访问 /userinfo,只会收到一个错误响应,因此调用方认为用户已经过身份验证,但却不知道有关用户身份的任何信息。端点所执行的操作是为调用方(例如 Web 应用程序)提供有关当前用户的充足信息以识别该用户,并能够自定义响应。例如,当您登录支持站点时,您会看到“我未解决的故障记录”(My unsolved tickets) 链接。

平台所包含的应用程序(已在 cloudfoundry.com 中)可以在 UAA 中配置为自动批准(即,不需要用户明确批准授予访问令牌)。这可以提供更好的用户体验,让用户感觉是在使用一个逻辑平台,从而隐藏了一组单独组件形式的实现。

部署在 Cloud Foundry 甚至其他地方的应用程序没有理由也无法使用 UAA 作为 SSO 服务。另一篇计划撰写的博文将为您介绍如何在您自己的应用程序中利用这一点。

委派服务访问

单点登录对客户端应用程序具有巨大好处,但 UAA 的主要作用是充当 OAuth2 身份验证服务器。(顺便说一下,SSO 功能的实现是作为对 userinfo 服务的委派访问,因而只是更常规功能的一个特例。)

基本委派模型在 OAuth2 规范中介绍。简言之,身份验证服务器为客户端应用程序授予访问令牌,但仅在资源所有者(用户)批准访问权限时才授予。云控制器便是 Cloud Foundry 中资源服务器的一个示例,它负责管理用户的应用程序和服务。UAA 支持所有核心 OAuth2 令牌授予类型,但与委派访问最相关的是 authorization_code(我们已在前文简单讨论过)和 implicit(与之相似但安全性低,适用于浏览器内的脚本客户端而非 Web 应用程序客户端)。

访问令牌对客户端应用程序不透明,但它们携带着与资源服务器相关的信息。如果使用 UAA,则令牌携带一些有关用户的基本信息以及可由资源服务器用于限制访问的一些其他详细信息。默认情况下,UAA 根据 JSON Web 令牌 (JWT) 规范发出 base64 编码的 JSON 令牌。以下是解码后令牌的示例:

{ "exp":1341079110, "user_id":"65dddc5d-d566-42ee-88f7-9f0098ee7f45", "user_name":"vcap_tester@vmware.com", "email":"vcap_tester@vmware.com", "scope":[ "uaa.user", "cloud_controller.read", "cloud_controller.write", "password.write", "openid" ], "aud":["openid","cloud_controller","password"], "client_id":"vmc" }

提示:由于令牌的构建方式,如果您要仔细查看令牌的内容,可以将整个内容采用 base64 解码,这种做法快速但不正规。结果不可解析,但可以看到内容。属于已注册客户端的资源服务器也可以在 /check_token 端点将令牌解码(使用 HTTP 基本身份验证)。如果不首选使用 JWT 或者需要更新的信息,则将执行上述解码(访问令牌可以长期存在,用户帐户数据可能发生变化)。

令牌内容如下所示:

  • ‘exp’:到期时间(自 epoch 启动以来所经过的秒数)
  • ‘user_id’:用户的永久唯一标识符
  • ‘user_name’:用户用来进行身份验证的用户名
  • ‘email’:用户的主要电子邮件地址(对于传统的 Cloud Foundry 帐户,电子邮件和用户名相同)
  • ‘scope’:用户授予此令牌的访问级别。
  • ‘aud’:令牌的受众。此令牌专用于云控制器以及由 UAA 自身所管理的其他两个资源:“password”和“openid”。
  • ‘client_id’:获得令牌的客户端的唯一标识符。

如果满足以下任何条件,则令牌的安全功能依赖于拒绝访问资源的资源服务器:

  • 令牌已到期
  • 受众不包括资源服务器
  • 作用域不充足

有效的作用域值由资源服务器决定,可以采用所需的任何方式来任意解释。UAA 对其使用的作用域值有一些约定,可帮助资源服务器从作用域中提取有用信息。客户端获取令牌时允许客户端请求提供特定作用域,但 UAA 限制各个客户端可以使用的值。例如,不允许获得上述令牌的“vmc”客户端获取作用域超出所示值的令牌(即,无法创建新的用户帐户)。

OAuth2 中的作用域值是任意字符串,但在 UAA 中,它们通常有一个资源 ID(在“aud”字段中)和一些用点号分隔的访问级别(例如“read”、“write”和“admin)。在标准规范中定义的作用域值除外,例如上述的“openid”值,它在 OpenID 连接规范中定义,为客户端应用程序赋予访问用户的档案数据的权限(只读)。

令牌中的作用域是来自不同来源的值的组合;客户端要求提供的内容、允许客户端要求提供的内容以及从用户帐户追加的附加组分配信息(上例中的“uaa.user”,表明 UAA 已知道用户,但未指定任何特殊状态)。

用户帐户管理

UAA 的主要功能之一是存储用户帐户数据并提供端点用来置备和检查用户帐户。为实现这些目标,UAA 实施标准的简单云身份管理 (SCIM) API,从而向位于 /Users 的授权客户端公开端点,并使用 OAuth2 访问令牌对这些客户端进行身份验证。例如:

$ curl -H "Authorization:Bearer $TOKEN" https://devuaa.cloudfoundry.com/Users { [ { "id":"4df2ddcb-6314-495b-b077-e1693f54f6a4"}, { "id":"1ce62b22-ea56-4d62-b300-c7a6c1fd9106"}, { "id":"de3ca343-fe9e-4b61-90b0-0eb97810028a"}, { "id":"a41afc1c-3006-41c9-9d3b-5ebb88f37153"}, { "id":"639d9baa-aaf9-488c-a693-d45c11c39594"}, ...] } $ curl -H "Authorization:Bearer $TOKEN" https://devuaa.cloudfoundry.com/User/4df2ddcb-6314-495b-b077-e1693f54f6a4 { { "id":"4df2ddcb-6314-495b-b077-e1693f54f6a4", "userName":"marissa", "givenName":"Marissa", "familyName":"Bloggs", "emails":[ { "value":"marissa@test.org"} ], "groups":[ { "externalId":"uaa.user"} ] } }

权限充足的客户端应用程序可以凭借自己的权限管理用户帐户。云控制器(以及规则中的新服务)具有此功能以支持 Cloud Foundry 将来的改进

客户端应用程序注册

UAA 保留客户端应用程序的注册以及允许其执行的操作,因此其可以完成发放令牌的过程(尤其是在客户端无效或者要求提供不允许的作用域时,将拒绝授予令牌)。执行方式是在 /oauth/clients/** 公开服务端点并使用 OAuth2 令牌身份验证对这些端点进行保护。例如:

$ curl -v -H "Authorization:Bearer $TOKEN" 'https://devuaa.cloudfoundry.com/oauth/clients' { "admin":{ "scope":["uaa.none"], "client_id":"admin", "authorized_grant_types":[ "client_credentials" ], "authorities":["clients.secret", "clients.read", "clients.write"] }, "app":{ "scope":["openid","cloud_controller.read","cloud_controller.write"], "client_id":"app", "authorized_grant_types":["authorization_code","password","refresh_token"], "redirect_uri":["http://localhost"], "authorities":["uaa.none"] }, ... }

客户端注册中的字段包括:

  • ‘client_id’:唯一标识符。
  • ‘client_secret’:只有首次创建注册或者要更改密码时提供。另外,如果授权的授予类型中包含“implicit”,则不允许使用密码(隐式客户端不受信任)。
  • ‘scope’:UAA 允许在发给代表用户执行操作的此客户端的令牌中使用的有效作用域值(客户端凭据授权则不是这样)。
  • ‘authorized_grant_types’:允许此客户端使用的授予类型,在 OAuth2 规范中列出。
  • ‘authorities’:客户端要求授予“client_credentials”令牌时,客户端可以请求的作用域值。上例中的“app”客户端未获准请求授予“client_credentials”,因此在此字段中默认值为“uaa.none”。
  • ‘redirect_uri’:允许该客户端请求的回调 URI 列表。需要授予 implicit 或 authorization code 的任何客户端都必须提供至少一个回调 URI。UAA 允许其请求以注册中提供的值开头的回调,以便重定向到同一应用程序中的多个位置,但只注册一个回调。
  • 还将存储其他字段(基元或 JSON 对象)。UAA 使用 ‘client_name’ 字段在令牌授予批准页面上为客户端提供用户友好的名称。

目前,如果在 cloudfoundry.com 中有应用程序要注册为客户端应用程序,应通过支持站点联系产品管理团队。如果要提供可接受由 UAA 授予的 OAuth2 令牌的资源服务器,还应将此服务器注册为客户端应用程序。我们正在提供一些面向用户的功能,以便您使用一些包括客户端注册在内的 UAA 服务,完成后将在 cloudfoundry.com 博客站点中宣布相关信息。

其他 UAA 资源

除了已经介绍的服务外,UAA 还提供一些其他服务。以下是所有 UAA 端点的简要列表(如果是 OAuth2 资源,还包括有效作用域):

  • OAuth2 授权服务器:oauth/authorize/oauth/token 端点。
  • 用户信息端点(用于 SSO):/userinfo,作用域 openid
  • 令牌解码端点:/check_token
  • 登录信息端点(对所有人公开):/login
  • SCIM 用户帐户管理:/Users 端点,作用域 [scim.read, scim.write]
  • 密码更改:/Users/{id}/password 端点,作用域 password.write
  • 令牌管理,例如取消批准:/oauth/users/{id}/tokens/oauth/clients/{id}/tokens,作用域 [tokens.read, tokens.write]
  • 客户端注册:/oauth/clients,作用域 [clients.read, clients.write, clients.secret]
  • 密码强度指示器:/password
  • Cloud Foundry 平台内部使用的管理端点:/health/varz

API 文档中有关于 UAA 提供的上述服务和其他服务的更多详细信息。

注意:UAA 作用域值说明以及客户端注册的精准详细信息属于 1.1.0 版(正在进行)的功能。您可以在 GitHub 的“scopes”分支中找到此版本的代码(发布 1.1.0 版后在 master 中)。在撰写本文之时,devuaa.cloudfoundry.com 服务器的这些功能为最新功能,但 uaa.cloudfoundry.com 不是最新功能。

    精彩文章,何不与朋友分享

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">