Java 禁用Http方法选项的Spring安全性
是否可以为一种HTTP方法禁用Spring安全性 我们有一个SpringREST应用程序,其中的服务要求在http请求的头中附加授权令牌。我正在为它编写一个JS客户端,并使用JQuery发送GET/POST请求。应用程序已使用此筛选代码启用CORSJava 禁用Http方法选项的Spring安全性,java,spring,spring-mvc,spring-security,cors,Java,Spring,Spring Mvc,Spring Security,Cors,是否可以为一种HTTP方法禁用Spring安全性 我们有一个SpringREST应用程序,其中的服务要求在http请求的头中附加授权令牌。我正在为它编写一个JS客户端,并使用JQuery发送GET/POST请求。应用程序已使用此筛选代码启用CORS doFilter(....) { HttpServletResponse httpResp = (HttpServletResponse) response; httpResp.setHeader("Access-Control-Allow
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());
}
doFilter(…){
HttpServletResponse httpResp=(HttpServletResponse)响应;
httpResp.setHeader(“访问控制允许源代码”、“*”);
setHeader(“访问控制允许方法”、“POST、GET、OPTIONS、DELETE”);
httpResp.setHeader(“访问控制最大年龄”,“3600”);
枚举头枚举=((HttpServletRequest)请求).getHeaders(“访问控制请求头”);
StringBuilder标头=新的StringBuilder();
字符串delim=“”;
while(headersEnum.hasMoreElements()){
headers.append(delim.append(headersEnum.nextElement());
delim=“,”;
}
setHeader(“访问控制允许头”,Headers.toString());
}
但是,当JQuery为CORS发送选项请求时,服务器会使用授权失败令牌进行响应。显然,选项请求缺少授权令牌。那么,是否可以让选项从Spring安全配置中脱离安全层呢?您尝试过这个吗
可以使用多个元素来定义不同的
不同URL集的访问要求,但它们将是
按列出的顺序计算,将使用第一个匹配项。那么你呢
必须将最具体的匹配项放在顶部。您还可以添加
方法属性将匹配限制为特定HTTP方法(GET,
邮寄、邮寄等)
上面的意思是,您需要选择要截取的url模式以及所需的方法如果您使用的是基于注释的安全配置文件(
@EnableWebSecurity
&@Configuration
),您可以在配置()中执行以下操作
允许Spring Security在不验证给定路径的情况下允许选项
请求的方法:
@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, "/**");
}
以防有人正在寻找使用Spring Boot的简单解决方案。只需添加一个额外的bean:
@Bean
public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() {
return configurer -> {
List<RequestMatcher> matchers = new ArrayList<>();
matchers.add(new AntPathRequestMatcher("/**", "OPTIONS"));
configurer.requestMatchers(new OrRequestMatcher(matchers));
};
}
@Bean
公共IgnoredRequestCustomizer选项ignoredRequestsCustomizer(){
返回配置器->{
列表匹配器=新的ArrayList();
添加(新的AntPathRequestMatcher(“/**”,“选项”);
配置器。请求匹配器(新的或请求匹配器(匹配器));
};
}
请注意,根据您的应用程序,这可能会打开它进行潜在的利用
打开问题以获得更好的解决方案:在某些情况下,需要添加
配置.setAllowedHeaders(Arrays.asList(“内容类型”)当使用websecurityConfigureAdapter
解决cors问题时,将code>添加到corscoConfiguration Source()
。如果使用基于注释的安全配置,则应通过在配置中调用.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();
}
不推荐接受的答案,您不应该这样做。
下面是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;
}
}
但是我想我们不能有像
这样的东西。是吗?根据,我不认为@PreAuthorize注释的情况下该如何工作,我希望Put方法具有管理员访问权限,Post方法具有用户访问权限在java配置中是等效的。请查看我的问题+1正是我们为启用CORS选项请求所做的。它工作正常,感谢您的提示我搜索和调试了很多,但无法修复现在我已修复它使用此tipsI在研究类似问题时找到了您的答案,该问题尚未以当前形式响应您的解决方案。你愿意看一看吗?以下是链接:这可能有助于一般理解:我自己不是JavaSpring用户,我在后端使用不同的语言时遇到了相同的问题。Java/Spring是否在安全性方面带来了任何额外的抽象,或者忽略所有选项请求的身份验证中间件方法基本上是安全的?这似乎是允许选项请求而不需要auhorization的唯一方法。如果您随后创建了一个要保护的选项端点,您将忘记配置中的排除,每个人都可以访问它。您应该考虑使用过滤器来允许CORS选项请求从Spring Security中排除:HtpSecurity是http.AuthigeRealStices()。“如果您随后创建了一个要保护的选项端点”@Tim为什么会有人需要它?IgnoredRequestCustomizer
自spring boot 2以来已被弃用。
@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;
}
}
$.ajaxSetup({
// NOTE: Necessary for CORS
crossDomain: true,
xhrFields: {
withCredentials: true
}
});