resource mkyong example spring spring-security spring-boot spring-cloud spring-oauth2

resource - spring security oauth2 example mkyong



Solicitar ''OPCIONES/cerrar sesiĆ³n'' no coincide ''POST/logout (1)

Estoy estudiando Spring Cloud y Spring OAuth2 al descomponer las tres aplicaciones interconectadas en esta muestra de GitHub . Cuando abro el punto /oauth/revoke-token en la aplicación authserver y luego lo llamo desde la aplicación ui con http://localhost:9999/uaa/logout , el registro de depuración de la aplicación authserver muestra el siguiente mensaje de error al rechazar la solicitud de cierre de sesión:

Request ''OPTIONS /logout'' doesn''t match ''POST /logout

¿Qué cambios específicos se deben realizar en el código de las aplicaciones GitHub de muestra para permitir que el cierre de sesión global tenga éxito cuando la aplicación ui llama a la función de cierre de sesión de hello.js ?

ESFUERZOS INICIALES:

Los cambios que hice hasta ahora incluyen:

Agregue la siguiente definición de @Bean a AuthserverApplication.java :

@Bean public TokenStore tokenStore() {return new InMemoryTokenStore();}

Agregue la siguiente clase de controlador en el paquete de demo de la aplicación authserver :

@Configuration public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired TokenStore tokenStore; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore); } @RequestMapping(value = "/oauth/revoke-token", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) public void logout(HttpServletRequest request) { String authHeader = request.getHeader("Authorization"); if (authHeader != null) { String tokenValue = authHeader.replace("Bearer", "").trim(); OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue); tokenStore.removeAccessToken(accessToken); } } }

Cambie el método logout() de hello.js en la aplicación ui para convertirse en lo siguiente:

self.logout = function() { $http.post(''http://localhost:9999/uaa/logout'', {}).finally(function() { $rootScope.authenticated = false; $location.path("/"); }); }

Pero cuando el usuario hace clic en el botón de cerrar sesión en el navegador y activa la llamada a http://localhost:9999/uaa/logout , el registro de depuración de la aplicación authserver da el siguiente resultado:

2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/css/**''] 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/css/**'' 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/js/**''] 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/js/**'' 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/images/**''] 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/images/**'' 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/**/favicon.ico''] 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/**/favicon.ico'' 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/error''] 2016-04-18 15:34:07.142 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/error'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/login''] 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/login'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/oauth/authorize''] 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/oauth/authorize'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/oauth/confirm_access''] 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/oauth/confirm_access'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/logout''] 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/logout'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : matched 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 1 of 12 in additional filter chain; firing Filter: ''WebAsyncManagerIntegrationFilter'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 2 of 12 in additional filter chain; firing Filter: ''SecurityContextPersistenceFilter'' 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created. 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 3 of 12 in additional filter chain; firing Filter: ''HeaderWriterFilter'' 2016-04-18 15:34:07.143 DEBUG 313 --- [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@5790c1b4 2016-04-18 15:34:07.143 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 4 of 12 in additional filter chain; firing Filter: ''CsrfFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 5 of 12 in additional filter chain; firing Filter: ''LogoutFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request ''OPTIONS /logout'' doesn''t match ''POST /logout 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 6 of 12 in additional filter chain; firing Filter: ''UsernamePasswordAuthenticationFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request ''OPTIONS /logout'' doesn''t match ''POST /login 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 7 of 12 in additional filter chain; firing Filter: ''RequestCacheAwareFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 8 of 12 in additional filter chain; firing Filter: ''SecurityContextHolderAwareRequestFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 9 of 12 in additional filter chain; firing Filter: ''AnonymousAuthenticationFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: ''org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 10 of 12 in additional filter chain; firing Filter: ''SessionManagementFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 11 of 12 in additional filter chain; firing Filter: ''ExceptionTranslationFilter'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout at position 12 of 12 in additional filter chain; firing Filter: ''FilterSecurityInterceptor'' 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /logout; Attributes: [authenticated] 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 2016-04-18 15:34:07.144 DEBUG 313 --- [io-9999-exec-10] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@539015a, returned: -1 2016-04-18 15:34:07.145 DEBUG 313 --- [io-9999-exec-10] 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) ~[spring-security-core-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232) ~[spring-security-core-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE] ... at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern=''/**'', GET] 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request ''OPTIONS /logout'' doesn''t match ''GET /** 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Did not match 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point. 2016-04-18 15:34:07.146 DEBUG 313 --- [io-9999-exec-10] o.s.s.web.DefaultRedirectStrategy : Redirecting to ''http://localhost:9999/uaa/login'' 2016-04-18 15:34:07.147 DEBUG 313 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 2016-04-18 15:34:07.147 DEBUG 313 --- [io-9999-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

¿Qué otros cambios de código específicos deben cambiarse en las aplicaciones de muestra de GitHub para permitir que la aplicación de la interfaz de usuario desencadene un cierre de sesión global del usuario desde todas las aplicaciones?

Nota: Obviamente, /uaa/logout es una URL diferente de /oauth/revoke-token . Sin embargo, el funcionamiento interno de Spring Security y OAuth en esta situación no está claro sin una respuesta a este OP.

Sugerencias de @ StuXnet:

El contenido de la pestaña de la red de Firefox Developer Tools para la solicitud es:

La solicitud a http : // localhost:9999/uaa/login con el método OPTIONS fue rechazada con un error 403 .

Los encabezados de request formato fueron:

Host: localhost:9999 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://localhost:8080 Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type,x-requested-with Connection: keep-alive Pragma: no-cache Cache-Control: no-cache

Los encabezados de response formato fueron:

Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH Content-Length: 20 Date: Mon, 18 Apr 2016 23:45:46 GMT Server: Apache-Coyote/1.1 X-Application-Context: application:9999

Luego, cambié el método config (http) de LoginConfig para que se lea de la siguiente manera:

@Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http .formLogin().loginPage("/login").permitAll() .and() .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/logout", "/oauth/revoke-token") .and() .authorizeRequests() .antMatchers(HttpMethod.OPTIONS,"/logout").permitAll() .anyRequest().authenticated(); // @formatter:on }

Esto dio como resultado la siguiente nueva impresión en los registros de DEBUG de Spring Boot:

2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/css/**''] 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/css/**'' 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/js/**''] 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/js/**'' 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/images/**''] 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/images/**'' 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/**/favicon.ico''] 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/**/favicon.ico'' 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/error''] 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/error'' 2016-04-18 19:22:06.202 DEBUG 5319 --- [io-9999-exec-10] o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2016-04-18 19:22:06.203 DEBUG 5319 --- [io-9999-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request ''/logout'' matched by universal pattern ''/**'' 2016-04-18 19:22:06.203 DEBUG 5319 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /logout has an empty filter list 2016-04-18 19:22:06.204 DEBUG 5319 --- [io-9999-exec-10] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /logout 2016-04-18 19:22:06.205 DEBUG 5319 --- [io-9999-exec-10] .s.o.p.e.FrameworkEndpointHandlerMapping : Did not find handler method for [/logout]

Y el siguiente encabezado de request en Firefox:

Host: localhost:9999 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://localhost:8080 Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type,x-requested-with Connection: keep-alive Pragma: no-cache Cache-Control: no-cache

Junto con el siguiente encabezado de response en Firefox:

Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH Content-Length: 20 Date: Tue, 19 Apr 2016 02:22:06 GMT Server: Apache-Coyote/1.1 X-Application-Context: application:9999

Luego intenté cambiar el método de configure(http) de LoginConfig para convertirme en:

@Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http .formLogin().loginPage("/login").permitAll() .and() .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/logout", "/oauth/revoke-token") .and() .authorizeRequests() .anyRequest().authenticated() // @formatter:on .and() .csrf() .ignoringAntMatchers("/logout"); }

Pero el resultado es el siguiente registro DEBUG de Spring Boot para la aplicación authserver :

2016-04-19 10:12:13.545 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/css/**''] 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/css/**'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/js/**''] 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/js/**'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/images/**''] 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/images/**'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/**/favicon.ico''] 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/**/favicon.ico'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern=''/error''] 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : ''/logout''; against ''/error'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request ''/logout'' matched by universal pattern ''/**'' 2016-04-19 10:12:13.546 DEBUG 4593 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /logout has an empty filter list 2016-04-19 10:12:13.547 DEBUG 4593 --- [nio-9999-exec-2] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /logout 2016-04-19 10:12:13.548 DEBUG 4593 --- [nio-9999-exec-2] .s.o.p.e.FrameworkEndpointHandlerMapping : Did not find handler method for [/logout]

REPRODUCCIÓN DEL PROBLEMA EN SU MÁQUINA:

Para reproducir el problema en su propia máquina, puede:

1.) git clone la aplicación de muestra original en el enlace en la parte superior de la OP y luego realice los cambios que se muestran arriba, o

2.) Descargue la versión comprimida de la aplicación tal como existe en mi devbox, incluidos todos los cambios desde el OP en este enlace para compartir archivos , y luego:

2.a.) Descomprima la aplicación.

2.b.) Navegue por una ventana de terminal a oauth2/resource y mvn spring-boot:run . Luego navegue por una segunda ventana de terminal a oauth2/authserver y escriba mvn spring-boot:run . Luego navegue por una tercera ventana de terminal a oauth2/ui y escriba mvn spring-boot:run .

2.c.) Navegue por el navegador web a http : // localhost:8080 , luego haga clic en login , luego ingrese user para username de username y password para password . Después de que haya sido autenticado, haga clic en el botón de logout para reproducir el error 403. Use la pestaña Red de las herramientas de desarrollo de su navegador para examinar la actividad del navegador. Vea los registros de Spring Boot en la terminal que ejecuta la aplicación authserver para ver la actividad de Spring.

3.) Importar las tres carpetas en eclipse (u otro IDE) como proyectos maven existentes, o abrir los archivos de código con un editor de texto para editar antes de repetir el relanzamiento y volver a probar en el paso 2.

¿Qué más puedo proporcionar para ayudar a aislar la solución?


Dejando de lado la pregunta de por qué es posible que desee hacer esto y si es una buena idea o no: su cliente JS está realizando una transferencia a un punto final en otro servidor, por lo que enfrentará dos problemas: Compartir recursos cruzados (CORS) y Cruzar Falsificación de solicitud de sitio (CSRF), ambas están bloqueadas de forma predeterminada en su servidor de autenticación porque está utilizando Spring MVC y Spring Security.

El problema de CORS se puede solucionar de varias maneras, incluido el enfoque que se tomó, que consistía en perforar la configuración de seguridad mediante el uso de una coincidencia de solicitud permitAll() . Hay una mejor integración entre Spring MVC y Spring Security usando HttpSecurity.cors() . Enlace de la guía del usuario: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors . Ejemplo simple del tutorial (servidor de recursos de vanilla):

@Override protected void configure(HttpSecurity http) throws Exception { http.cors() ...; }

Lo que hace es activar la integración con los puntos finales declarados MVC con @CrossOrigin . En realidad, el punto final al que está tratando de PUBLICAR no es uno que haya escrito, y no es un punto final de Spring MVC, por lo que podría tener que usar cors().configurationSource(...) lugar.

El problema de CSRF también es fácil de resolver de diferentes maneras. El tutorial donde comenzó tiene ejemplos explícitos que muestran cómo hacerlo para Angular JS (pero no en la aplicación que está utilizando porque el tutorial no trata de cerrar la sesión del proveedor de SSO). En ese caso, usamos las características HttpSecurity.csrf() . Enlace de la guía del usuario: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf . Ejemplo simple del tutorial en la aplicación de interfaz de usuario:

@Override public void configure(HttpSecurity http) throws Exception { http ... .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); }