如何在 Spring Boot 安全性中禁用 CORS
Posted
技术标签:
【中文标题】如何在 Spring Boot 安全性中禁用 CORS【英文标题】:How to disable CORS in sprint boot security 【发布时间】:2020-02-02 05:16:43 【问题描述】:我想在 Spring Boot 安全性中完全禁用 CORS,但我尝试过的所有方法似乎都不起作用
我尝试添加自定义过滤器并将其作为 bean 注入,我还尝试在 WebSecurityConfigurerAdapter 中禁用 cors 我还尝试在配置 HttpSecurity 方法中添加过滤器。
这些链接我已经试过了:
1:CORS problems with spring boot security。
2:Spring security CORS Filter
我当前的代码状态如下:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
private final CustomUserDetailsService customUserDetailsService;
private final AuthConfigProperties authConfigProperties;
public WebSecurityConfig(@Lazy CustomUserDetailsService customUserDetailsService, AuthConfigProperties authConfigProperties)
this.customUserDetailsService = customUserDetailsService;
this.authConfigProperties = authConfigProperties;
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception
return super.authenticationManager();
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder(authConfigProperties.getBcryptRounds());
@Override
public void configure(HttpSecurity http) throws Exception
http
.requestMatchers()
.antMatchers("/login", "/logout", "/oauth/authorize")
.and()
.logout()
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.csrf()
.disable();
http.cors().disable();
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
当我尝试访问前端的身份验证服务器时,我收到以下错误消息:
CORS 策略已阻止从源“http://localhost:3000”获取“http://localhost:8089/oauth/token”的访问权限:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。
【问题讨论】:
CORS 是浏览器端的东西;您确实需要启用吗?可能会帮助您阅读 about CORS 以了解它是什么。 @BoristheSpider 嗯,我不是在质疑你的回答,但如果是浏览器,为什么我们允许在后端配置它?在这两种情况下都有办法禁用它!我正在尝试将我的系统投入生产,但此问题不断出现。 不,没有办法禁用它。浏览器将所有运行的 JS 限制为单一来源策略 (SOP)。 CORS 允许您在服务器同意的情况下覆盖 SOP - 这就是它在服务器端的原因。您的身份验证服务器需要响应来自浏览器的预检提示“是的,我信任该来源,继续”。 @BoristheSpider 我已经通过设置代理解决了这个问题,为了使响应到达客户端,浏览器检查 Allow-Control-access-origin 的值是否相等到请求的原点。这就是我到现在为止的理解。如果我的评论没有任何意义,请纠正我。谢谢。 【参考方案1】:此代码确实有效:
import com.example.myAuthServer.service.CustomUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
private final CustomUserDetailsService customUserDetailsService;
private final AuthConfigProperties authConfigProperties;
public WebSecurityConfig(@Lazy CustomUserDetailsService customUserDetailsService, AuthConfigProperties authConfigProperties)
this.customUserDetailsService = customUserDetailsService;
this.authConfigProperties = authConfigProperties;
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception
return super.authenticationManager();
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder(authConfigProperties.getBcryptRounds());
@Override
public void configure(HttpSecurity http) throws Exception
http
.cors()
.and()
.requestMatchers()
.antMatchers("/login", "/logout", "/oauth/authorize")
.and()
.logout()
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.csrf()
.disable();
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
但为了使原始帖子中显示的错误变为红色,您只需让浏览器知道请求的服务器 url 具有相同的“Allow-Control-Access-Origin”响应的 url。
我们可以通过在客户端应用代理来做到这一点,在我的例子中,我使用的是 react。
在 src 目录下添加一个名为 setupProxy.js 的文件。
然后编写如下代码:
const proxy = require("http-proxy-middleware");
module.exports = function (app)
app.use(proxy("/oauth/token", target: "http://localhost:8089")); // put your host and api
;
并像这样使用它:
fetch("/oauth/token",
method: "POST",
body: qs.stringify(Auth.bodyForNewToken(username, password)),
headers:
"Content-Type": "application/x-www-form-urlencoded",
Authorization: "Basic " + btoa("<CLIENT>:<SECRET>")
);
此代码只是一个提示,您需要更改必要的行!!!。
【讨论】:
【参考方案2】:处理它的一种方法是添加 WebMvcConfigurer。尽管使用它,您应该考虑环境 profile(dev、prod 等),并且您可以将 WebSecurityConfigurerAdapter 保留为 cors 配置默认值。 (不需要禁用它)
一个例子:
@Configuration
public class WebMvc implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("*");
【讨论】:
我认为它和这篇文章***.com/a/58227186/10420300 一样,但是以一种通用的方式,这似乎也是一个糟糕的主意。 否,因为这是一个通用代理,您不需要控制 N 个控制器,它将应用于所有路由,如果您输入 @Profile("dev") 则不会有什么问题。当然,您可以在参数中更具体,但总体而言它会起作用以上是关于如何在 Spring Boot 安全性中禁用 CORS的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 2.2.0 的集成测试中禁用安全性?