7

Я изучаю Spring Cloud и Spring OAuth2, разлагая the three interconnected apps in this GitHub sample. Когда я открываю /oauth/revoke-token конечную точку в authserver app, а затем вызвать его из ui app с http://localhost:9999/uaa/logout, журнал отладки для authserver app выдает следующее сообщение об ошибке при отклонении запроса выхода из системы:Запрос 'OPTIONS/logout' не соответствует 'POST/logout

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

Что нужно конкретные изменения чтобы сделать код в the sample GitHub apps, чтобы глобальный выход из системы завершился успешно, когда ui app вызывает функцию выхода из hello.js?


ПЕРВЫЕ ПОПЫТКИ:


Изменения, которые я сделал до сих пор включают в себя:

Добавьте следующий @Bean определение AuthserverApplication.java:

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

Добавьте следующий contro Класс Мюллером в demo package of the authserver app:

@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); 
     } 
    } 
} 

Изменение logout() метод hello.js in the ui app стать следующее:

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

Но когда пользователь нажимает на кнопку выхода из системы в браузере и запускает вызов http://localhost:9999/uaa/logout, журнал отладки для authserver приложение дает следующий вывод:

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.se[email protected]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.sprin[email protected]9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]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.sprin[email protected]9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]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.sp[email protected]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 

Какие еще конкретные изменения кода необходимо изменить в the GitHub sample apps, чтобы включить приложение ui для запуска глобального выхода пользователя из всех приложений?

Примечание: Очевидно, что /uaa/logout - это другой URL-адрес, чем /oauth/revoke-token. Однако внутренняя работа Spring Security и OAuth в этой ситуации не ясна без ответа на этот OP.


@ Stuxnet-х Предложения:


Содержание Developer Tools Firefox Tab Network для запроса:

Запрос на http : // localhost:9999/uaa/login методом OPTIONS был отклонен с 403 ошибка.

Необработанные request заголовками:

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 

Необработанные response заголовками:

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 

Далее, я изменил метод конфигурации (HTTP) от LoginConfig следующим образом:

@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 
} 

Это привело к следующим новым печатным изданиям ут в журналах Spring Загрузочный DEBUG:

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] 

А следующий request заголовок в 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 

Наряду со следующим response заголовком в 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 

Затем я попытался изменить configure(http) способ LoginConfig стать:

@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"); 
} 

Но результатом является следующая весна загрузки журнала DEBUG для 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] 

ВОСПРОИЗВЕДЕНИЯ ПРОБЛЕМУ НА ВАШЕЙ МАШИНЫ:


Чтобы воспроизвести проблема на вашей собственной машине, вы можете:

1.) мерзавец клонировать исходный пример приложения на ссылке в верхней части ОП, а затем сделать изменения показано выше, или

2.) Скачать the zipped version of the app as it exists on my devbox including all the changes from the OP at this file sharing link, а затем:

2.a.) Untar приложение.

2.b.) Перейдите в окно терминала до oauth2/resource и mvn spring-boot:run. Затем перейдите во второе окно терминала до oauth2/authserver и введите mvn spring-boot:run. Затем перейдите в третье окно терминала до oauth2/ui и введите mvn spring-boot:run.

2.c.) Перейдите на веб-браузер http : // localhost:8080, затем нажмите login, затем введите user для username и password для password. После того, как вы прошли проверку подлинности, нажмите кнопку logout, чтобы воспроизвести ошибку 403. Используйте вкладку «Сеть» инструментов разработчика вашего браузера для проверки активности браузера. Просмотрите журналы Spring Boot в терминале, на котором запущено приложение authserver, чтобы увидеть активность Spring.

3.) Импортируйте три папки в eclipse (или другую IDE) в качестве существующих проектов maven или откройте файлы кода с помощью текстового редактора для редактирования, прежде чем повторять перезапуск и повторный тест на шаге 2.

Что еще я могу предоставить, чтобы помочь изолировать решение?

+1

@stuXnet Я только что добавил выход из вкладки «Инструменты разработчика Firefox». Помогает ли это вам изолировать решение? – CodeMed

+0

@stuXnet Я только что добавил результаты попытки вашего запроса до конца моего OP. Кажется, только что переустановили фильтры безопасности, не устраняя проблему. – CodeMed

+0

@stuXnet Спасибо. Пожалуйста, смотрите конец OP, где я добавил результат попытки вашего предложения. – CodeMed

ответ

1

Оставляя в стороне вопрос о том, почему вы, возможно, захотите это сделать, и является ли это хорошей идеей: ваш JS-клиент отправляет POST на конечную точку на другом сервере, поэтому вы сталкиваетесь с двумя проблемами: совместное использование ресурсов Cross-Origin (CORS) и Cross-Site Request Forgery (CSRF), оба из которых заблокированы по умолчанию на вашем сервере Auth, поскольку использует Spring MVC и Spring Security.

Проблема CORS может быть обработана различными способами, включая подход, который вы использовали, чтобы пробить дыру через конфигурацию безопасности с помощью совпадения запроса: permitAll(). Существует гораздо лучшая интеграция между Spring MVC и Spring Security с использованием HttpSecurity.cors(). Ссылка на руководство пользователя: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors. Простой пример из учебника (сервера ресурсов ванильного):

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

Что это делает переключение на интеграцию с MVC объявил конечные точки с @CrossOrigin. Фактически конечная точка, которую вы пытаетесь выполнить POST, не такая, которую вы написали, и это не конечная точка Spring MVC, поэтому вам, возможно, придется использовать cors().configurationSource(...).

Проблема CSRF также легко решить различными способами. В учебном пособии, в котором вы начали, содержатся явные примеры, показывающие, как это сделать для Angular JS (но не в приложении, которое вы используете, потому что учебник не связан с выходом из поставщика единого входа). В этом случае мы используем функции HttpSecurity.csrf(). Ссылка на руководство пользователя: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf. Простой пример из учебника в приложении пользовательского интерфейса:

@Override 
public void configure(HttpSecurity http) throws Exception { 
    http 
     ... 
     .csrf() 
      .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); 
} 
Смежные вопросы