无法获取 Spring 安全 OAuth2 登录以触发
Can't get Spring Security OAuth2 login to trigger
我正在编写一个 RESTful
网络服务(Jersey
运行 on Tomcat
),它需要验证用户的电子邮件地址,并可能访问他们的 Google 日历。
计划是用户将被重定向到通过 OAuth2
.
登录 Google
我的网络服务已经受到 Spring Security
的保护。它适用于基本身份验证(即用户和密码的硬连线列表。)如果我尝试访问任何受保护的资源,系统会提示我登录。
现在我正在尝试接入 Spring Security OAuth2
。我的理解是,如果我尝试访问受保护的资源,我将重定向到 Google。
但是,无论我如何尝试,似乎都无法启动 OAuth。没有记录控制台错误,并且资源受到保护(我收到错误 "Full authentication is required to access this resource")。
出了点问题;可能是我的配置,我的理解,或两者兼而有之。将不胜感激。
web.xml
(部分):
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/V1/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-security.xml</param-value>
</context-param>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-security.xml
(隐藏 google 个键):
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
<debug />
<oauth:client id="oauth2ClientFilter" />
<oauth:resource id="googleOauth2Resource"
type="authorization_code"
client-id="hidden"
client-secret="hidden"
access-token-uri="https://accounts.google.com/o/oauth2/v3/token"
user-authorization-uri="https://accounts.google.com/o/oauth2/auth"
scope="email" />
<http xmlns="http://www.springframework.org/schema/security" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
<intercept-url pattern="/V1/**" access="IS_AUTHENTICATED_FULLY" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<oauth:rest-template id="googleOauthRestTemplate"
resource="googleOauth2Resource" />
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</beans:bean>
<authentication-manager>
</authentication-manager>
</beans:beans>
更新: 我确实找到了一个 working demo(名称具有误导性——它使用的是 OAuth2,而不是 OpenID。)访问受保护的资源会触发重定向到Google 符合预期。我没有任何运气将他注释的 类 翻译成 XML,而且我不是 Spring Boot 或 Spring MVC 下的 运行 所以它会我很难切换到使用注释。
** 更新 2:** 通过调试器,我可以看到 OAuth2ClientContextFilter.doFilter 正在被调用,但它决定不重定向,因为过滤器链没有抛出 UserRedirectRequiredException。 (过滤器链抛出的异常是 AccessDeniedException。)
您收到响应的原因:"Full authentication is required to access this resource"
是因为 OAuth2AuthenticationEntryPoint
需要访问令牌。
如果您是 资源服务器 接受带有访问令牌的请求,则使用 OAuth2AuthenticationEntryPoint
。不过,在您的情况下,您的意图似乎是成为 依赖方 依赖 Google 返回访问令牌这样您就可以代表他访问 Google 上的用户数据。
因此,您必须按照与在 GitHub:
上找到的演示应用程序相同的流程进行操作
- 用户访问安全端点
/test
- 用户尚未通过身份验证,因此他被重定向到
/login
,如 LoginUrlAuthenticationEntryPoint
中所配置
- 对
/login
的请求再次通过过滤器链,并在 OpenIDConnectAuthenticationFilter
中被拦截,其配置的 OAuth2RestTemplate
尝试检索用户信息。这会抛出 UserRedirectRequiredException
,因为 OAuth2ClientContext 还没有访问令牌来检索用户的信息。
OAuth2ClientContextFilter
捕获抛出的 UserRedirectRequiredException
并将用户重定向到 google 的授权页面。
这是向您展示流程的 DEBUG 日志:
2016-09-11 02:32:34.361 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-11 02:32:34.366 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-11 02:32:34.367 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-09-11 02:32:34.367 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-09-11 02:32:34.375 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-11 02:32:34.378 DEBUG 41435 --- [nio-8080-exec-1] 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@38511637
2016-09-11 02:32:34.379 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-11 02:32:34.381 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /test' doesn't match 'POST /logout
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 6 of 13 in additional filter chain; firing Filter: 'OAuth2ClientContextFilter'
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 7 of 13 in additional filter chain; firing Filter: 'OpenIDConnectAuthenticationFilter'
2016-09-11 02:32:34.383 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-09-11 02:32:34.383 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-09-11 02:32:34.385 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-09-11 02:32:34.396 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-09-11 02:32:34.396 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-09-11 02:32:34.405 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.session.SessionManagementFilter : Requested session ID D2C2005BFB0AD21F3380BC0BE8326094 is invalid.
2016-09-11 02:32:34.405 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-09-11 02:32:34.406 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-09-11 02:32:34.407 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/'
2016-09-11 02:32:34.415 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/test'
2016-09-11 02:32:34.421 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /test; Attributes: [authenticated]
2016-09-11 02:32:34.422 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-09-11 02:32:34.650 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3f726a43, returned: -1
2016-09-11 02:32:34.676 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:57)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
2016-09-11 02:32:34.678 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET]
2016-09-11 02:32:34.678 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/test' matched by universal pattern '/**'
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/**/favicon.ico'
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@7f127599, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing text/html
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith text/html = false
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xhtml+xml
2016-09-11 02:32:34.691 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xhtml+xml = false
2016-09-11 02:32:34.692 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/webp
2016-09-11 02:32:34.692 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/webp = false
2016-09-11 02:32:34.697 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xml;q=0.9
2016-09-11 02:32:34.699 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xml;q=0.9 = false
2016-09-11 02:32:34.703 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing */*;q=0.8
2016-09-11 02:32:34.705 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Ignoring
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Did not match any media types
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2016-09-11 02:32:34.708 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.709 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
2016-09-11 02:32:34.759 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/test]
2016-09-11 02:32:34.759 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2016-09-11 02:32:34.760 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://localhost:8080/login'
2016-09-11 02:32:34.761 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-11 02:32:34.761 DEBUG 41435 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@7ff7af51. A new one will be created.
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] 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@38511637
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-11 02:32:35.061 DEBUG 41435 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-09-11 02:32:35.061 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 6 of 13 in additional filter chain; firing Filter: 'OAuth2ClientContextFilter'
2016-09-11 02:32:35.062 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 7 of 13 in additional filter chain; firing Filter: 'OpenIDConnectAuthenticationFilter'
2016-09-11 02:32:35.187 DEBUG 41435 --- [nio-8080-exec-2] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'https://accounts.google.com/o/oauth2/auth?client_id=%3Cclient_id%3E&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&response_type=code&scope=openid&state=19P08W'
2016-09-11 02:32:35.187 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-11 02:32:35.188 DEBUG 41435 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
此外,在示例代码中,注意 @EnableOAuth2Client
导入 OAuth2ClientConfiguration
.
我正在编写一个 RESTful
网络服务(Jersey
运行 on Tomcat
),它需要验证用户的电子邮件地址,并可能访问他们的 Google 日历。
计划是用户将被重定向到通过 OAuth2
.
我的网络服务已经受到 Spring Security
的保护。它适用于基本身份验证(即用户和密码的硬连线列表。)如果我尝试访问任何受保护的资源,系统会提示我登录。
现在我正在尝试接入 Spring Security OAuth2
。我的理解是,如果我尝试访问受保护的资源,我将重定向到 Google。
但是,无论我如何尝试,似乎都无法启动 OAuth。没有记录控制台错误,并且资源受到保护(我收到错误 "Full authentication is required to access this resource")。
出了点问题;可能是我的配置,我的理解,或两者兼而有之。将不胜感激。
web.xml
(部分):
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/V1/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-security.xml</param-value>
</context-param>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-security.xml
(隐藏 google 个键):
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
<debug />
<oauth:client id="oauth2ClientFilter" />
<oauth:resource id="googleOauth2Resource"
type="authorization_code"
client-id="hidden"
client-secret="hidden"
access-token-uri="https://accounts.google.com/o/oauth2/v3/token"
user-authorization-uri="https://accounts.google.com/o/oauth2/auth"
scope="email" />
<http xmlns="http://www.springframework.org/schema/security" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
<intercept-url pattern="/V1/**" access="IS_AUTHENTICATED_FULLY" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<oauth:rest-template id="googleOauthRestTemplate"
resource="googleOauth2Resource" />
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</beans:bean>
<authentication-manager>
</authentication-manager>
</beans:beans>
更新: 我确实找到了一个 working demo(名称具有误导性——它使用的是 OAuth2,而不是 OpenID。)访问受保护的资源会触发重定向到Google 符合预期。我没有任何运气将他注释的 类 翻译成 XML,而且我不是 Spring Boot 或 Spring MVC 下的 运行 所以它会我很难切换到使用注释。
** 更新 2:** 通过调试器,我可以看到 OAuth2ClientContextFilter.doFilter 正在被调用,但它决定不重定向,因为过滤器链没有抛出 UserRedirectRequiredException。 (过滤器链抛出的异常是 AccessDeniedException。)
您收到响应的原因:"Full authentication is required to access this resource"
是因为 OAuth2AuthenticationEntryPoint
需要访问令牌。
如果您是 资源服务器 接受带有访问令牌的请求,则使用 OAuth2AuthenticationEntryPoint
。不过,在您的情况下,您的意图似乎是成为 依赖方 依赖 Google 返回访问令牌这样您就可以代表他访问 Google 上的用户数据。
因此,您必须按照与在 GitHub:
上找到的演示应用程序相同的流程进行操作- 用户访问安全端点
/test
- 用户尚未通过身份验证,因此他被重定向到
/login
,如LoginUrlAuthenticationEntryPoint
中所配置
- 对
/login
的请求再次通过过滤器链,并在OpenIDConnectAuthenticationFilter
中被拦截,其配置的OAuth2RestTemplate
尝试检索用户信息。这会抛出UserRedirectRequiredException
,因为 OAuth2ClientContext 还没有访问令牌来检索用户的信息。 OAuth2ClientContextFilter
捕获抛出的UserRedirectRequiredException
并将用户重定向到 google 的授权页面。
这是向您展示流程的 DEBUG 日志:
2016-09-11 02:32:34.361 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-11 02:32:34.366 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-11 02:32:34.367 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-09-11 02:32:34.367 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-09-11 02:32:34.375 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-11 02:32:34.378 DEBUG 41435 --- [nio-8080-exec-1] 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@38511637
2016-09-11 02:32:34.379 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-11 02:32:34.381 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /test' doesn't match 'POST /logout
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 6 of 13 in additional filter chain; firing Filter: 'OAuth2ClientContextFilter'
2016-09-11 02:32:34.382 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 7 of 13 in additional filter chain; firing Filter: 'OpenIDConnectAuthenticationFilter'
2016-09-11 02:32:34.383 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-09-11 02:32:34.383 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-09-11 02:32:34.385 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-09-11 02:32:34.396 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-09-11 02:32:34.396 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-09-11 02:32:34.405 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.session.SessionManagementFilter : Requested session ID D2C2005BFB0AD21F3380BC0BE8326094 is invalid.
2016-09-11 02:32:34.405 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-09-11 02:32:34.406 DEBUG 41435 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : /test at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-09-11 02:32:34.407 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/'
2016-09-11 02:32:34.415 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/test'
2016-09-11 02:32:34.421 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /test; Attributes: [authenticated]
2016-09-11 02:32:34.422 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-09-11 02:32:34.650 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3f726a43, returned: -1
2016-09-11 02:32:34.676 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:57)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
2016-09-11 02:32:34.678 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET]
2016-09-11 02:32:34.678 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/test' matched by universal pattern '/**'
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/test'; against '/**/favicon.ico'
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.679 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@7f127599, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing text/html
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith text/html = false
2016-09-11 02:32:34.689 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xhtml+xml
2016-09-11 02:32:34.691 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xhtml+xml = false
2016-09-11 02:32:34.692 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/webp
2016-09-11 02:32:34.692 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/webp = false
2016-09-11 02:32:34.697 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xml;q=0.9
2016-09-11 02:32:34.699 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xml;q=0.9 = false
2016-09-11 02:32:34.703 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing */*;q=0.8
2016-09-11 02:32:34.705 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Ignoring
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Did not match any media types
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.707 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2016-09-11 02:32:34.708 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2016-09-11 02:32:34.709 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
2016-09-11 02:32:34.759 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/test]
2016-09-11 02:32:34.759 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2016-09-11 02:32:34.760 DEBUG 41435 --- [nio-8080-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://localhost:8080/login'
2016-09-11 02:32:34.761 DEBUG 41435 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-11 02:32:34.761 DEBUG 41435 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-09-11 02:32:35.059 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@7ff7af51. A new one will be created.
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] 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@38511637
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-11 02:32:35.060 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-11 02:32:35.061 DEBUG 41435 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-09-11 02:32:35.061 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 6 of 13 in additional filter chain; firing Filter: 'OAuth2ClientContextFilter'
2016-09-11 02:32:35.062 DEBUG 41435 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /login at position 7 of 13 in additional filter chain; firing Filter: 'OpenIDConnectAuthenticationFilter'
2016-09-11 02:32:35.187 DEBUG 41435 --- [nio-8080-exec-2] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'https://accounts.google.com/o/oauth2/auth?client_id=%3Cclient_id%3E&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&response_type=code&scope=openid&state=19P08W'
2016-09-11 02:32:35.187 DEBUG 41435 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-11 02:32:35.188 DEBUG 41435 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
此外,在示例代码中,注意 @EnableOAuth2Client
导入 OAuth2ClientConfiguration
.