gpt4 book ai didi

spring-security - Spring Security 中 Microsoft Graph OAuth2 身份验证的配置 - 错误 AADSTS90014

转载 作者:行者123 更新时间:2023-12-04 07:06:40 24 4
gpt4 key购买 nike

我正在为利用 Spring OAuth2 的 MS Graph API Azure AD v2 端点编写 SSO 提供程序。

我正在实现和不断测试,但我偶然发现了 AAD 返回的错误,这让我感到困惑。毕竟,这应该都是普通的标准 OAuth 2 流程。

我在 MS 开发门户上成功配置了我的应用程序,提供了一个 localhost 重定向 URL(据记录,这是唯一支持 http 方案的。向 MS 致敬)。所以当我调用 http://localhost/myapp/auth/office365 Spring security 成功拦截了调用,正确重定向到我的浏览器,客户端 ID 为 https://login.microsoftonline.com/common/oauth2/v2.0/authorize与预期参数。

Microsoft 向我显示了一个同意屏幕,之后我通过带有预期授权代码参数的 HTTP GET 重定向回我的 Spring Security 应用程序。

问题在于,当应用程序尝试为不记名 token 协商给定的授权代码时,就会开始头痛。 Spring Security 调用 POST 到 https://login.microsoftonline.com/common/oauth2/v2.0/token但以 401 错误结束。

这是堆栈跟踪

error="invalid_request", error_description="AADSTS90014: The request body must contain the following parameter: 'client_id'.
Trace ID: 9acd2a10-1cfb-443f-9c57-78d608c00c00
Correlation ID: bf063914-8926-4e8f-b102-7522d0e3b0af
Timestamp: 2017-10-09 15:51:44Z", correlation_id="bf063914-8926-4e8f-b102-7522d0e3b0af", error_codes="[90014]", timestamp="2017-10-09 15:51:44Z", trace_id="9acd2a10-1cfb-443f-9c57-78d608c00c00"
at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:100)
at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:33)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readInternal(AbstractJackson2HttpMessageConverter.java:215)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:193)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$AccessTokenErrorHandler.handleError(OAuth2AccessTokenSupport.java:235)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:137)
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:209)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:105)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)

我已经调查了 Spring 安全实现以找到原因。

恰好是错误信息 error="invalid_request", error_description="AADSTS90014: The request body must contain the following parameter: 'client_id'.不言自明:MS Graph 需要请求正文中的客户端 ID(仍由基本身份验证 header 提供)。 停一下 .我想使用普通的旧 Spring Security 而不是第三方特定的 jars,以免污染我的类路径。

查看 Spring OAuth 2 的 Java 源代码,问题非常清楚。 Spring 仅在 getParametersForAuthorizeRequest 中使用客户端 ID ,用于生成重定向 URL。说到 getParametersForTokenRequest表单中未指定客户端 ID。

问题:谁在这里?我如何告诉 Spring 那个 MS 想要获得授权码后 token 请求中的客户端 ID?

最佳答案

澄清一下,您实际上并未使用 Microsoft Graph 或针对 Microsoft Graph 进行身份验证。您实际上是针对 Azure Active Directory 进行身份验证。 Microsoft Graph API 接受您最终将获得的不记名 token ,但它本身不颁发访问 token 。

不清楚您为授权代码流使用哪个端点,AAD 有两个端点:v1v2 .主要区别在于 v2 使用中央注册并且可以验证工作/学校和个人帐户。

无论端点如何,您都需要提供 clientid当您请求访问 token 时,在请求正文中。实际上,您需要在正文中提供几个值。另请注意,这些需要提供为 application/x-www-form-urlencoded .

对于您提供的 v1 端点(换行符仅供阅读):

grant_type=authorization_code
&client_id={client-id}
&code={authoization-code}
&redirect_uri={redirect-uri}
&client_secret={client-secret}
&resource={resource-uri}

v2 端点几乎相同,但使用 scope而不是 resource :
grant_type=authorization_code
&client_id={client-id}
&code={authoization-code}
&redirect_uri={redirect-uri}
&client_secret={client-secret}
&scope={scopes}

OP 的编辑

现在,回到 Spring Security。默认情况下,Spring 针对 Azure AD 使用 HTTP 基本身份验证方案。在该方案中,客户端 ID 和密码被编码到 HTTP Authorization 中。 header,那么表单只包含授权码和状态参数,所以这就是为什么我(OP,ndr)对 AAD 拒绝授权的原因感到困惑。

为了将客户端 ID 和 secret 传递到表单中,我们可以告诉 Spring Security 使用不同的受支持的身份验证方案。 form身份验证方案会将客户端 ID 和 secret 推送到表单中。
以下代码有效并检索访问 token 。
<oauth2:resource
id="msAdAuthenticationSource"
client-id="${oauth.appId}"
client-secret="${oauth.appSecret}"
type="authorization_code"
authentication-scheme="form"
client-authentication-scheme="form"
use-current-uri="true"
user-authorization-uri="${oauth.authorizationUri}"
access-token-uri="${oauth.accessTokenUri}"
scope="${oauth.scopes}"
pre-established-redirect-uri="${oauth.redirectUri}" />

请注意这两个
authentication-scheme="form"
client-authentication-scheme="form"

问题解决了,还有很多!

关于spring-security - Spring Security 中 Microsoft Graph OAuth2 身份验证的配置 - 错误 AADSTS90014,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46651090/

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