Recently I tried the new built-in CORS-Support in Spring 4. This feature is great and I want to implement this in my Spring Boot / AngularJS application.
最近,我在Spring 4中尝试了新的内置的cors支持。这个特性非常好,我想在Spring Boot / AngularJS应用程序中实现它。
All request works fine but I can't logout my user because the
OPTIONS
-Request to/logout
is handled by Spring Security.所有请求都可以正常工作,但我不能注销我的用户,因为options -请求/注销是由Spring Security处理的。
Is it possible to handle the OPTIONS
-Request before Spring Security or should I attach CORS-Headers in LogoutSuccessHandler
?
是否有可能在Spring Security之前处理options请求,或者在logoutshandesshandler中附加cors - header ?
2 个解决方案
#1
7
When working with Spring Security, it is recommended to use CorsFilter. You will want to ensure that you order the CorsFilter
before Spring Security's FilterChainProxy
.
在使用Spring Security时,建议使用CorsFilter。您将希望确保在Spring Security的FilterChainProxy之前命令CorsFilter。
You can refer to Spring Data Rest and Cors for details on using CorsFilter
. For this issue, the difference is likely that you want to register only for the logout URL. For example:
您可以参考Spring数据Rest和Cors,了解使用CorsFilter的详细信息。对于这个问题,可能只需要注册logout URL。例如:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
// likely you should limit this to specific origins
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/logout", config);
return new CorsFilter(source);
}
#2
-1
I know this is a bit late. I was having the same problem with /logout being rejected by my Angular2 browser app because of the CORS header Access-Control-Allow-Origin not being returned in the /logout response. The /logout seems to be processed before the CORS filter is reached so doesn't get the header. I tried the solution above but it didn't work for me. So, i tried this next solution and it works great:
我知道这有点晚了。我的Angular2浏览器应用程序拒绝了相同的问题,因为CORS头的访问控制允许源不在/注销响应中返回。在到达CORS过滤器之前,/注销似乎要进行处理,所以没有得到消息头。我试过上面的方法,但对我没用。所以,我尝试了下一个解决方案,效果很好:
- Create a LogoutHandler implementation class and implement logout()
- 创建一个LogoutHandler实现类并实现logout()
- Create a LogoutSuccessHandler implementation class and implement onLogoutSuccess()
- 创建一个登录成功的实现类并实现onLogoutSuccess()
- Wire the two classes to the Spring security configuration
- 将两个类连接到Spring安全配置。
Turns out I didn't need the LogoutSuccessHandler class, just the LogoutHandler. The LogoutSuccessHandler (not shown) is just an empty implementation with a logging statement in it. The LogoutHandler is below. This is a snippet of a Spring-boot REST app coded in Groovy (very similar to java)
结果是我不需要logoutrelesshandler类,只是LogoutHandler。logoutrelesshandler(未显示)只是一个空实现,其中有一个日志语句。LogoutHandler下面。这是用Groovy编写的Spring-boot REST应用程序的一个片段(非常类似于java)
@Slf4j
class TodosLogoutHandler implements LogoutHandler {
/**
* For some reason the spring-session logout gets processed before the request
* reaches the CORS filter so the response doesn't get the allow-origin header
* which then causes the browser to reject the logout response. I tried a bunch
* of other methods of trying to include /logout to the CORS filter but they
* didn't work so figured a logout handler would be a place I could manually
* set the header to persuade the browser to accept the response - it worked!!
* @param request
* @param response
* @param authentication
*/
@Override
void logout(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {
response.setHeader("Access-Control-Allow-Origin", "*")
log.info("TodosLogoutHandler logging you out of the back-end app.")
}
}
Then wire this together in your security configuration class that extends WebSecurityConfigurerAdapter like this below. The last part, showing the logout section is the relevant part in the standard configure() method.
然后将这些连接到安全配置类中,扩展WebSecurityConfigurerAdapter,如下所示。最后一部分,显示logout部分是标准配置()方法中的相关部分。
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Allow any CORS OPTIONS calls
.antMatchers(HttpMethod.GET, "/priority", "/status").permitAll() // Allow all ref data
.anyRequest().authenticated()
.and()
.csrf().disable()
.httpBasic().realmName("Spring REST Todos")
.and()
// Custom logout handler only exists to handle a CORS problem with /logout
// where spring-session processes the logout request/response before it gets
// to the CORS filter so it doesn't get the allow-origin header which then
// causes the browser to reject the /logout response. Manually set the
// allow-origin header in the logout handler and Bob's your uncle.
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new TodosLogoutSuccessHandler())
.addLogoutHandler(new TodosLogoutHandler())
.invalidateHttpSession(true)
}
#1
7
When working with Spring Security, it is recommended to use CorsFilter. You will want to ensure that you order the CorsFilter
before Spring Security's FilterChainProxy
.
在使用Spring Security时,建议使用CorsFilter。您将希望确保在Spring Security的FilterChainProxy之前命令CorsFilter。
You can refer to Spring Data Rest and Cors for details on using CorsFilter
. For this issue, the difference is likely that you want to register only for the logout URL. For example:
您可以参考Spring数据Rest和Cors,了解使用CorsFilter的详细信息。对于这个问题,可能只需要注册logout URL。例如:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
// likely you should limit this to specific origins
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/logout", config);
return new CorsFilter(source);
}
#2
-1
I know this is a bit late. I was having the same problem with /logout being rejected by my Angular2 browser app because of the CORS header Access-Control-Allow-Origin not being returned in the /logout response. The /logout seems to be processed before the CORS filter is reached so doesn't get the header. I tried the solution above but it didn't work for me. So, i tried this next solution and it works great:
我知道这有点晚了。我的Angular2浏览器应用程序拒绝了相同的问题,因为CORS头的访问控制允许源不在/注销响应中返回。在到达CORS过滤器之前,/注销似乎要进行处理,所以没有得到消息头。我试过上面的方法,但对我没用。所以,我尝试了下一个解决方案,效果很好:
- Create a LogoutHandler implementation class and implement logout()
- 创建一个LogoutHandler实现类并实现logout()
- Create a LogoutSuccessHandler implementation class and implement onLogoutSuccess()
- 创建一个登录成功的实现类并实现onLogoutSuccess()
- Wire the two classes to the Spring security configuration
- 将两个类连接到Spring安全配置。
Turns out I didn't need the LogoutSuccessHandler class, just the LogoutHandler. The LogoutSuccessHandler (not shown) is just an empty implementation with a logging statement in it. The LogoutHandler is below. This is a snippet of a Spring-boot REST app coded in Groovy (very similar to java)
结果是我不需要logoutrelesshandler类,只是LogoutHandler。logoutrelesshandler(未显示)只是一个空实现,其中有一个日志语句。LogoutHandler下面。这是用Groovy编写的Spring-boot REST应用程序的一个片段(非常类似于java)
@Slf4j
class TodosLogoutHandler implements LogoutHandler {
/**
* For some reason the spring-session logout gets processed before the request
* reaches the CORS filter so the response doesn't get the allow-origin header
* which then causes the browser to reject the logout response. I tried a bunch
* of other methods of trying to include /logout to the CORS filter but they
* didn't work so figured a logout handler would be a place I could manually
* set the header to persuade the browser to accept the response - it worked!!
* @param request
* @param response
* @param authentication
*/
@Override
void logout(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {
response.setHeader("Access-Control-Allow-Origin", "*")
log.info("TodosLogoutHandler logging you out of the back-end app.")
}
}
Then wire this together in your security configuration class that extends WebSecurityConfigurerAdapter like this below. The last part, showing the logout section is the relevant part in the standard configure() method.
然后将这些连接到安全配置类中,扩展WebSecurityConfigurerAdapter,如下所示。最后一部分,显示logout部分是标准配置()方法中的相关部分。
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Allow any CORS OPTIONS calls
.antMatchers(HttpMethod.GET, "/priority", "/status").permitAll() // Allow all ref data
.anyRequest().authenticated()
.and()
.csrf().disable()
.httpBasic().realmName("Spring REST Todos")
.and()
// Custom logout handler only exists to handle a CORS problem with /logout
// where spring-session processes the logout request/response before it gets
// to the CORS filter so it doesn't get the allow-origin header which then
// causes the browser to reject the /logout response. Manually set the
// allow-origin header in the logout handler and Bob's your uncle.
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new TodosLogoutSuccessHandler())
.addLogoutHandler(new TodosLogoutHandler())
.invalidateHttpSession(true)
}