[英]Disable Spring Security for OPTIONS Http Method
是否可以为某种类型的 HTTP 方法禁用 Spring Security?
我们有一个 Spring REST 应用程序,其服务需要在 http 请求的标头中附加授权令牌。 我正在为它编写一个 JS 客户端并使用 JQuery 发送 GET/POST 请求。 应用程序已使用此过滤器代码启用 CORS。
doFilter(....) {
HttpServletResponse httpResp = (HttpServletResponse) response;
httpResp.setHeader("Access-Control-Allow-Origin", "*");
httpResp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResp.setHeader("Access-Control-Max-Age", "3600");
Enumeration<String> headersEnum = ((HttpServletRequest) request).getHeaders("Access-Control-Request-Headers");
StringBuilder headers = new StringBuilder();
String delim = "";
while (headersEnum.hasMoreElements()) {
headers.append(delim).append(headersEnum.nextElement());
delim = ", ";
}
httpResp.setHeader("Access-Control-Allow-Headers", headers.toString());
}
但是当 JQuery 发送 CORS 的 OPTIONS 请求时,服务器会以 Authorization Failed 令牌响应。 显然 OPTIONS 请求缺少授权令牌。 那么是否有可能让 OPTIONS 从 Spring Security Configuration 中逃脱安全层?
如果您使用基于注解的安全配置文件( @EnableWebSecurity
& @Configuration
),您可以在configure()
方法中执行以下操作,以允许 Spring Security 允许OPTION
请求而无需对给定路径进行身份验证:
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"/path/to/allow").permitAll()//allow CORS option calls
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
在上下文中允许所有选项:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
你有没有试过这个
您可以使用多个元素为不同的 URL 集定义不同的访问要求,但它们将按照列出的顺序进行评估,并使用第一个匹配项。 因此,您必须将最具体的匹配项放在顶部。 您还可以添加一个方法属性来限制与特定 HTTP 方法(GET、POST、PUT 等)的匹配。
<http auto-config="true">
<intercept-url pattern="/client/edit" access="isAuthenticated" method="GET" />
<intercept-url pattern="/client/edit" access="hasRole('EDITOR')" method="POST" />
</http>
上面的意思是你需要选择拦截的url模式和你想要的方法
如果有人正在寻找使用 Spring Boot 的简单解决方案。 只需添加一个额外的bean:
@Bean
public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() {
return configurer -> {
List<RequestMatcher> matchers = new ArrayList<>();
matchers.add(new AntPathRequestMatcher("/**", "OPTIONS"));
configurer.requestMatchers(new OrRequestMatcher(matchers));
};
}
请注意,根据您的应用程序,这可能会打开它以进行潜在的攻击。
打开问题以获得更好的解决方案: https : //github.com/spring-projects/spring-security/issues/4448
不推荐接受的答案,你不应该这样做。
以下是 Spring Security 和 jQuery ajax 的 CORS 设置的正确方法。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(userAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors() // <-- This let it use "corsConfigurationSource" bean.
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
...
}
@Bean
protected CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
// NOTE: setAllowCredentials(true) is important,
// otherwise, the value of the 'Access-Control-Allow-Origin' header in the response
// must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// NOTE: setAllowedHeaders is important!
// Without it, OPTIONS preflight request will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(Arrays.asList(
"Authorization",
"Accept",
"Cache-Control",
"Content-Type",
"Origin",
"ajax", // <-- This is needed for jQuery's ajax request.
"x-csrf-token",
"x-requested-with"
));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
从 jQuery 方面来看。
$.ajaxSetup({
// NOTE: Necessary for CORS
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
如果您使用的是基于注解的安全配置,那么您应该通过在配置中调用.cors()
来将 spring 的CorsFilter
添加到应用程序上下文中,如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic()
.and()
.cors();
}
在某些情况下,需要添加configuration.setAllowedHeaders(Arrays.asList("Content-Type"));
使用WebSecurityConfigurerAdapter
解决 cors 问题时将corsConfigurationSource()
改为corsConfigurationSource()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.