Spring Boot 2.0.0.M4 OAuth2 令牌端点抛出 org.springframework.web.HttpRequestMethodNotSupportedException

Posted

技术标签:

【中文标题】Spring Boot 2.0.0.M4 OAuth2 令牌端点抛出 org.springframework.web.HttpRequestMethodNotSupportedException【英文标题】:Spring Boot 2.0.0.M4 OAuth2 token endpoint throws org.springframework.web.HttpRequestMethodNotSupportedException 【发布时间】:2018-03-15 11:55:05 【问题描述】:

我正在尝试从 Spring Boot 1.5.7 迁移到 2.0.0.M4

现在我无法在 Spring Boot 2.0.0.M4 上正确重新配置我的 OAuth2 + JWT 配置

在启动过程中,我注意到日志中/oauth/token 端点 (throws org.springframework.web.HttpRequestMethodNotSupportedException) 出现以下错误:

2017-10-04 09:52:46.841  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/authorize],methods=[POST],params=[user_oauth_approval]" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
2017-10-04 09:52:46.842  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/authorize]" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
2017-10-04 09:52:46.843  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/token],methods=[GET]" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
2017-10-04 09:52:46.844  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/token],methods=[POST]" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
2017-10-04 09:52:46.845  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/check_token]" onto public java.util.Map<java.lang.String, ?> org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(java.lang.String)
2017-10-04 09:52:46.845  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/confirm_access]" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
2017-10-04 09:52:46.846  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/error]" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint.handleError(javax.servlet.http.HttpServletRequest)
2017-10-04 09:52:46.848  INFO 11780 --- [           main] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "[/oauth/token_key],methods=[GET]" onto public java.util.Map<java.lang.String, java.lang.String> org.springframework.security.oauth2.provider.endpoint.TokenKeyEndpoint.getKey(java.security.Principal)

为了重现这个问题,我创建了 GitHub 项目 - https://github.com/Artgit/spring-boot-2.0.0.M4-oauth2-token-issue/tree/master/api

我为了产生这个问题请尝试执行com.decisionwanted.domain.api.decision.DecisionControllerIT.testCreateDecision()测试

对于代码和 pom.xml 中的混乱,我深表歉意。我已经从多模块 Maven 应用程序中编译了这个测试项目,用于测试目的。

请帮助我修复我的配置,以便能够使用 Spring Boot 2.0.0.M4

更新

调试的时候发现server.contextPath: /api from application.properties 没有考虑进去。现在我需要使用/oauth/token(而不是像我在 Spring Boot 1.5.7 中使用的/api/oauth/token)来获取令牌。这可能是什么原因以及如何解决?

【问题讨论】:

不幸的是,您的应用程序太大而无法在合理的时间内理解,因此我无法准确诊断问题。但是,我可以在为 org.springframework.security 启用调试日志记录的情况下运行它,并观察到 ​​/api/oauth/token 的请求由于无效的 CSRF 令牌而被拒绝。也许这有助于为您指明正确的方向? @AndyWilkinson,感谢您的回答。调试时发现application.properties中的server.contextPath: /api没有考虑到。现在我需要使用/oauth/token(而不是像我在Spring Boot 1.5.7 中使用的/api/oauth/token)来获取令牌。这可能是什么原因? 【参考方案1】:

我找到了问题的原因 - 根据 Spring Boot 2* 的以下文档 https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/,应使用以下属性来定义应用程序的上下文路径:

server.servlet.context-path= /api

请注意 Spring Boot 1.5.* 属性

server.contextPath: /api

没有更多考虑

【讨论】:

以上是关于Spring Boot 2.0.0.M4 OAuth2 令牌端点抛出 org.springframework.web.HttpRequestMethodNotSupportedException的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot + oauth2:访问此资源需要完全身份验证

企业快速开发平台Spring Cloud+Spring Boot+Mybatis+ElementUI 实现前后端分离

Spring Boot + OAuth2.0 实现微信扫码登录,这才叫优雅!!

Oaut2RestTemplate 与 client_credentials 错误(不允许匿名)

Spring Authorization Server:使用重定向测试 OAuth 流

Spring Security - 用于多租户应用程序的 OAuth、LDAP 集成