下面给出了快速重现问题的完整代码和说明。
问题:
的自定义实现
HttpSession将当前替换为已保存的. nullDefaultOAuth2RequestFactoryAuthorizationRequestAuthorizationRequest 这会导致后续请求失败,因为/oauth/token端点之前的 Spring Security 过滤器链中的CsrfFilter无法在/oauth/token中找到 a与's进行比较。 session Csrf tokennull sessionrequestCsrf token
错误期间的控制流程:
以下流程图说明了步骤 14和步骤 15以某种方式null将HttpSession. (或者可能与 a 不匹配JSESSIONID。)第 14 步SYSO开头的CustomOAuth2RequestFactory.javaA表明确实存在 a实际上包含正确的。然而,不知何故,当第 15 步触发客户端在url 上返回到端点 的调用时,它已经变成了。HttpSessionCsrfTokenHttpSessionnulllocalhost:8080/loginlocalhost:9999/oauth/token
HttpSessionSecurityContextRepository在下面的调试日志中提到的每一行都添加了断点。(它位于 eclipse 项目的Maven Dependencies文件夹中authserver。)这些断点确认了在下面的流程图中发出HttpSession最终null请求的时间。/oauth/token(流程图的左下角。) 这null HttpSession可能是由于自定义代码运行JSESSIONID后保留在浏览器中的内容已过时。DefaultOAuth2RequestFactory
如何解决此问题,以便在流程图中的第 15 步结束后,在对端点HttpSession的最终呼叫期间保持不变?/oauth/token

相关代码和日志:
的完整代码CustomOAuth2RequestFactory.java 可以通过单击此链接在文件共享站点上查看。 我们可以猜测这null session是由于 1.)JSESSIONID中的代码没有在浏览器中更新CustomOAuth2RequestFactory,或者 2.)HttpSession实际被null-ified。
步骤 15/oauth/token之后调用的 Spring Boot 调试日志清楚地表明此时没有,可以读取如下: HttpSession
2016-05-30 15:33:42.630 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2fe29f4b
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:9999/uaa/oauth/token
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
在您的计算机上重现问题:
按照以下简单步骤,您只需几分钟即可在任何计算机上重现问题:
2.) 通过键入以下内容解压缩应用程序:tar -zxvf oauth2.tar(4).gz
authserver3.)通过导航到oauth2/authserver然后键入来启动应用程序mvn spring-boot:run。
resource4.)通过导航到oauth2/resource然后键入来启动应用程序mvn spring-boot:run
ui5.)通过导航到oauth2/ui然后键入来启动应用程序mvn spring-boot:run
6.) 打开网络浏览器并导航到http : // localhost : 8080
7.) 点击Login然后输入Frodo用户名和MyRing密码,点击提交。
8.) 输入5309,Pin Code然后单击提交。 这将触发上面显示的错误。
Spring Boot 调试日志将显示 A LOT of ,其中给出了流程图中显示的每个步骤SYSO的变量值,例如XSRF-TOKEN和HttpSession。这SYSO有助于对调试日志进行分段,以便它们更易于解释。所有这些SYSO都是由其他类调用的一个类完成的,因此您可以操纵SYSO-generating 类来更改控制流中各处的报告。SYSO生成类的名称是TestHTTP,它的源代码可以在同一个demo包中找到。
使用调试器:
1.) 选择正在运行authserver应用程序的终端窗口并键入Ctrl-C以停止authserver应用程序。
2.) 将三个应用程序(authserver、、resource和)作为现有的 maven 项目ui导入到 eclipse 中。
3.) 在authserver应用程序的 eclipse Project Explorer 中,单击展开Maven Dependencies文件夹,然后在其中向下滚动以单击展开Spring-Security-web...jar,如下图橙色圆圈所示。然后滚动查找并展开org.springframework.security.web.context包。然后双击打开HttpSessionSecurityContextRepository下面屏幕截图中以蓝色突出显示的类。向此类中的每一行添加断点。您可能希望对SecurityContextPersistenceFilter同一包中的类执行相同的操作。 这些断点将使您能够查看 的值,该值HttpSession当前在控制流结束之前变为null,但需要具有可以映射到的有效值XSRF-TOKEN才能解析此 OP。
4.) 在应用程序的demo包中,在CustomOAuth2RequestFactory.java. 然后Debug As... Spring Boot App启动调试器。
5.) 然后重复上面的步骤 6 到 8。您可能希望在每次新尝试之前清除浏览器的缓存。您可能希望打开浏览器开发工具的“网络”选项卡。