我可以使用 AWS Cognito 来提供一个 OpenID Connect 终端吗?

41

我想使用AWS Cognito作为OpenId连接提供者。我的AWS Cognito IDP将会调用我的另一个OpenId提供者来验证用户。然后,它将创建自己的新令牌并将其交给调用者。

AWS Cognito池内部使用的OpenID提供程序对用户透明。用户只需将AWS Cognito配置为其IDP提供程序即可。

用户案例

  • 用户使用我的AWS IDP提供程序进行身份验证
  • 我的IDP提供程序针对Google的IDP提供程序再次验证用户
  • 我的IDP解码Google IDP返回的令牌。
  • 我的IDP创建新令牌并添加其他声明。
  • 我的IDP将我的JWT交给用户。

问题

  • AWS Cognito是否支持此功能?
  • AWS用户池是否公开OpenID连接端点?
3个回答

35
Cognito提供了一个OpenId连接端点,详见@Badri博客文章
权限的公式为:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}

而您可以通过检查元数据URL来验证是否存在{{某些内容}}。

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration

然后,在客户端池设置期间,您可以与其他OIDC提供程序建立联合,并在应用程序客户端设置中启用OIDC提供程序。这应该启用您的场景,听起来非常类似于我想要做的事情。然而,博客文章遗漏了一个至关重要的配置,即为应用程序集成设置域名。如果您没有配置此域名,则会显示此StackOverflow问题中的错误,并在答案中链接到解决方案。一旦我设置了域名,Badri的代码就对我起作用了。

22

为了更详细地解答有关Cognito的OpenID Connect支持的问题。

Discovery Endpoint

Cognito按照https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest所描述的方式公开了一个OpenID Connect Discovery端点,其位置如下:

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration

响应类型

上述终端返回以下三种响应类型:

"response_types_supported":["code","token","token id_token"]
  • code: 在https://www.rfc-editor.org/rfc/rfc6749#section-11.3.2中定义-这对我们有效,但仅在指定域名时才有效。

  • token: OpenID Connect在https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest中禁止使用此值-“注意:虽然OAuth 2.0还为隐式流定义了令牌响应类型值,但OpenID Connect不使用此响应类型,因为不会返回任何ID令牌。”-OpenID Connect库将忽略此响应。

  • token id_token: 此值会触发重定向到一个错误页面,并显示代码“invalid_request”。没有给出请求无效的指示。AWS技术支持声称authorize端点仅支持“code”和“token”,但如果不支持,则不清楚为什么会广告此response_type。

域名

Cognito提供了指定域名的选项,该域名将作为Cognito端点主机名的前缀。

如果未指定域,则Cognito将在OpenID Connect发现端点上广告通用URL,例如https://cognito-idp.eu-west-2.amazonaws.com/{userPoolId}/authorize,但是在这些URL尝试登录时,都会返回错误消息:

{"code":"BadRequest","message":"The server did not understand the operation that was requested.","type":"client"}

错误消息未指示请求有何问题,因此这似乎是Cognito中的一个bug。

在指定域的情况下,Cognito将广告包含域前缀的URL,而response_type“code”将按预期返回登录页面。

注销

https://openid.net/specs/openid-connect-session-1_0.html#RPLogout上的OpenID Connect会话管理描述了必须如何启动OpenID Connect注销,并根据https://openid.net/specs/openid-connect-session-1_0.html#OPMetadata要求在发现元数据中包括end_session_endpoint参数。

在Cognito的情况下,metadata中省略了end_session_endpoint。

https://openid.net/specs/openid-connect-session-1_0.html#RPLogout上的RP-Initiated Logout描述了注销端点的工作方式。如果尝试手动将注销端点传递给OpenID Connect客户端实现,则注销失败,原因如下:

{"code":"BadRequest","message":"The server did not understand the operation that was requested.","type":"client"}

错误信息没有指示错误原因,但是在https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html描述的登出端点不支持OpenID Connect。

虽然可以使用OpenID Connect登录Cognito,但无法注销。

Cloudformation

Cognito Cloudformation支持不完整,对OpenID Connect的影响如下:

  • 没有办法使用Cloudformation指定域名,而域名是OpenID Connect必须的。
  • OpenID Connect需要回调URL,但不能使用Cloudformation设置。

概要

要使用OpenID Connect访问Cognito,请确保指定域名,并仅使用response_type "code"。 OpenID Connect注销不可行。其他选项会违反OpenID Connect规范或发行时已损坏。


请注意,AWS CloudFormation已经支持用户池域。https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooldomain.html - Jayesh Lalwani
谢谢,这解释了为什么AWS不是认证IDP列表的一部分。(https://openid.net/certification/) - Sprite

4
我有点难以理解您的用例,但我会解释一些可能有所帮助的要点。
您可以使用Cognito用户池通过Google对用户进行身份验证,然后从Cognito用户池发出JWT令牌。请参阅开发人员指南
Cognito用户池目前不是完整的OpenID身份提供者,但这在我们的路线图上。用户池支持OAuth2.0流程,并提供OpenID标准的JWT令牌。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接