gpt4 book ai didi

spring-security - Spring Security 和 Google OpenID Connect 迁移

转载 作者:行者123 更新时间:2023-12-03 22:41:18 25 4
gpt4 key购买 nike

问题:

1) 将 OpenID Connect 身份验证集成到使用 Spring Security 进行身份验证的 web 应用程序中的最佳方法是什么?

2) 有什么办法 - 来自 MITREid事物的一面或 Google 帐户的一面 - 让 MITREid OpenID Connect 身份验证过滤器与 Google 的 OpenID Connect 服务一起使用?

我确信这些问题的答案对于任何使用 Spring Security OpenID 模块向 Google 进行身份验证的开发人员都会很有用。

细节:

我的 webapp 使用 Spring Security 的 OpenID 模块 ( <openid-login .../> ) 以 Google 帐户作为身份提供者进行身份验证。即,用户使用他们的 Google Apps 或 GMail 电子邮件地址进行身份验证。

最近,每当用户进行身份验证时,他们都会从 Google 帐户收到以下警告消息:

Important notice: OpenID2 for Google accounts is going away on April 20, 2015.



因此,Google 正在放弃对 OpenID 的支持,并将在 2015 年 4 月将其完全关闭,并声明如果您想使用 Google 帐户进行身份验证,则必须切换到 OpenID Connect 协议(protocol)。

我希望 Spring Security 能够内置对 OpenID Connect 的支持,就像它内置对 OpenID 的支持一样。例如类似于 <openid-connect-login .../>元素。但我的搜索没有出现这样的支持。

到目前为止,我发现的最好的候选人是 MITREid Connect 。它包括一个名为 OIDCAuthenticationFilter 的 Spring Security 身份验证过滤器。用于 OpenID 连接。问题是,它不能与 Google 的 OpenID Connect 实现互操作。

我尝试克隆 MITREid simple-web-app 并将其配置为使用 Google 帐户进行身份验证(使用 OpenID Connect)。但它不起作用,因为它依赖于 随机数 Google 的 OpenID Connect 实现不支持。来自 Google 帐户的错误消息是:

Parameter not allowed for this message type: nonce



接下来我尝试插入我自己实现的 MITREid 的 AuthRequestUrlBuilder接口(interface)到 MITREid 配置。我的实现和 MITREid 的实现之间的唯一区别是我没有发送随机数。

不发送 nonce 让 Google 的 OpenID Connect 实现很开心,但 MITREid 在 Google 身份验证响应中找不到 nonce 时抛出了异常。错误消息是:

Authentication Failed: ID token did not contain a nonce claim



我在 MITREID 的 OIDCAuthenticationFilter 中将 MITREid 异常跟踪到这些行。 :
// compare the nonce to our stored claim
String nonce = idClaims.getStringClaim("nonce");
if (Strings.isNullOrEmpty(nonce)) {

logger.error("ID token did not contain a nonce claim.");

throw new AuthenticationServiceException("ID token did not contain a nonce claim.");
}

但是我没有办法扩展 MITREid 的实现来忽略随机数。如此接近,却又如此遥远!如果 Google 帐户接受 nonce 或 MITREid 可以配置为忽略 nonce,那么我们就有了解决方案。

在 github 上的 MITREid Connect 问题列表中,我发现其他人也遇到了这些类似的问题:

1) #726 - 关于将客户端与 Google 一起用作身份验证提供程序的文档

2) #704 - 在 ServerConfiguration 中添加一个 useNonce 属性,以指示 IdP 是否在其请求中接受 nonce 值。

所以我被困住了。到 2015 年 4 月,Google 将关闭 Open ID 身份验证。

一些相关链接:

1) https://support.google.com/accounts/answer/6135882
2) https://www.tbray.org/ongoing/When/201x/2014/03/01/OpenID-Connect
3) https://github.com/mitreid-connect
4) https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/blob/master/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java
5) https://github.com/mitreid-connect/simple-web-app
6) https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/blob/master/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/PlainAuthRequestUrlBuilder.java
7) https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/issues/726
8) https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/pull/704
2015-02-18 更新

最近在 mitreid-connect 的开发分支中添加了用于禁用 nonce 的功能 - 因此使 Google 的 OIDC 服务器很高兴。值得庆幸的是,mitreid-connect 还提供了一些 guidance on interoperating with Google .
不幸的是,“nonceEnabled”更改在 Maven 中心尚不可用,但希望很快就会改变。

最佳答案

AFAIK,没有从 OpenID 到 OpenID Connect 身份验证的干净简单的 Spring Security 迁移。使用有据可查的 <openid-login/> 使用 Spring Security 实现 OpenID 身份验证非常简单。但 OpenID Connect 没有类似物。

MITREid alternative仍在开发分支上,在 Maven 中心不可用,因此不是候选人。

在评论中,Chuck Mah 指向 How to implement Openid connect and Spring Security其中 Romain F. 提供 sample code .

Romain 的示例代码为我指明了正确的方向。鉴于时间不多了,我采用了 romain 的方法,即编写一个自定义 Spring Security AuthenticationFilter,使用 spring-security-oauth2 来查询 oauth2 api userinfo endpoint (对于 Google 来说是 https://www.googleapis.com/oauth2/v2/userinfo )。假设是,如果我们能够成功查询 userinfo 端点,那么用户已经成功通过身份验证,因此我们可以信任返回的信息 - 例如用户的电子邮件地址。

当我第一次开始学习 OpenID Connect 时,“id token ”似乎是中心概念。但是,浏览 spring-security-oauth2 源代码,它似乎被忽略了。这就引出了一个问题,如果我们可以在没有它的情况下进行身份验证(通过简单地查询 oauth2 userinfo 端点),那么 ID token 的意义何在?

一个极简主义的解决方案——我更喜欢——会简单地返回一个经过验证的 ID token 。无需查询 userinfo 端点。但是没有这样的解决方案以 Spring Security 身份验证过滤器的形式存在。

我的 webapp 不是 romain 的 spring-boot 应用程序。 spring-boot 在幕后做了很多配置。以下是我在此过程中遇到的一些问题/解决方案:

  • 问题:HTTP 状态 403 - 未找到预期的 CSRF token 。你的 session 过期了吗?
  • 解决方案:java配置:httpSecurity.csrf().disable()
  • 问题:HTTP 状态 500 - 创建名称为“scopedTarget.googleOAuth2RestTemplate”的 bean 时出错:范围“ session ”对于当前线程无效;
  • 解决方案:java config:OAuth2RestTemplate 不需要是 session 范围(OAuth2ClientContext 已经是 session 范围,这就是所有必要的)
  • 问题:HTTP 状态 500 - 创建名称为“scopedTarget.oauth2ClientContext”的 bean 时出错:范围“ session ”对于当前线程无效;
  • 解决方案:web.xml:添加RequestContextListener
  • 解释:因为 oauth2ClientContext session 范围的 bean 是在 Spring MVC DispatcherServlet 范围之外访问的(它是从 OpenIdConnectAuthenticationFilter 访问的,它是 Spring Security 过滤器链的一部分)。

  • <听众>
    org.springframework.web.context.request.RequestContextListener

  • 问题:org.springframework.security.oauth2.client.resource.UserRedirectRequiredException:需要重定向才能获得用户的批准。
  • 解决方案:web.xml:在 springSecurityFilterChain
  • 之前立即添加过滤器定义

    <过滤器>
    oauth2ClientContextFilter
    org.springframework.web.filter.DelegatingFilterProxy

    <过滤器映射>
    oauth2ClientContextFilter
    /*


    不幸的是,OpenID Connect 不允许我们仅请求 email范围。
    当我们的用户使用 OpenID 进行身份验证时,他们会看到一个同意屏幕,例如“webapp 希望查看您的电子邮件地址”,他们对此感到满意。现在我们必须请求范围 openid email导致同意屏幕要求用户与我们分享他们的整个公共(public)个人资料......我们真的不需要或不想要......并且用户对这个同意屏幕不太满意。

    关于spring-security - Spring Security 和 Google OpenID Connect 迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27408599/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com