如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]

Posted

技术标签:

【中文标题】如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]【英文标题】:How to configure CORS in spring boot with spring security? [duplicate] 【发布时间】:2021-11-06 05:12:41 【问题描述】:

我的 CORS 有问题。我有以下安全配置:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    CustomUserDetailsService userDetailsService;

    @Autowired
    private CustomJwtAuthenticationFilter customJwtAuthenticationFilter;

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    public PasswordEncoder passwordEncoder()
        return new BCryptPasswordEncoder();
    

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    @Override
    public void configure(HttpSecurity http) throws Exception 

        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
        corsConfiguration.setAllowedOrigins(List.of("*"));
        corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setExposedHeaders(List.of("Authorization"));

        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/helloadmin").hasRole("ADMIN")
                .antMatchers("/hellouser").hasAnyRole("USER","ADMIN")
                .antMatchers("/techshop/web/v1/product/save").hasRole("ADMIN")
                .antMatchers("techshop/web/v1/product").hasAnyRole("USER", "ADMIN")
                .antMatchers("techshop/web/v1/product/id").hasRole("ADMIN")
                .antMatchers("/authenticate").permitAll().anyRequest().authenticated()
                .and().exceptionHandling()
                //if any exception occurs call this
                .authenticationEntryPoint(unauthorizedHandler).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

                //Add a filter to validate the tokens with every request
                http.addFilterBefore((Filter) customJwtAuthenticationFilter,
                UsernamePasswordAuthenticationFilter.class);
    


我有以下控制器:

@RestController
@RequestMapping(value = "")
public class AuthenticationController 

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping(path = "/authenticate",  consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest request) throws Exception 
        try
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                    request.getUsername(), request.getPassword()));
         catch (DisabledException e) 
            throw new Exception("USER_DISABLE", e);
         catch (BadCredentialsException e)
            throw new Exception("INVALID_CREDENTIALS", e);
        
        final UserDetails userDetails = customUserDetailsService.loadUserByUsername(request.getUsername());
        final String token = jwtUtil.generateToken(userDetails);

        return ResponseEntity.ok(new AuthenticationResponse(token));
    


还有:

@RestController
@RequestMapping("techshop/web/v1")
public class ProductController 

    @Autowired
    private ProductServiceI productService;

    @PostMapping(value = "/product/save", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Object> save(@RequestBody ProductDto request)
        productService.save(request);

        return ResponseEntity.ok(Boolean.TRUE);
    

    @GetMapping(value = "/product", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Object> findAll()
        return ResponseEntity.ok(productService.findAll());
    

    @PutMapping(value = "/product/id", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Object> updateProduct(@PathVariable("id") int id, @RequestBody ProductDto request)
        productService.update(request, id);
        return ResponseEntity.ok(Boolean.TRUE);
    

    @DeleteMapping(value = "/product/id")
    public ResponseEntity<Object> deleteById(@PathVariable("id") int id)
        productService.deletedById(id);
        return ResponseEntity.ok(Boolean.TRUE);
    

当我发出以下请求时,浏览器显示 CORS 问题:

let datos = 
    username:"admin",
    password:"admin"


const getToken = () => 
    axios(
        method: 'post',
        url: 'localhost:8080/test',
        data: datos
        );


getToken()

enter image description here

我已经尝试了所有方法,使用 @CrosOrigin ("*") 注释,使用 lambda,使用从 corsConfigurer 扩展的 Bean WebConfig,但没有任何效果。

如果您能帮助我,我将不胜感激。

【问题讨论】:

【参考方案1】:

请尝试以下方法:

const getToken = () => 
    axios(
        method: 'post',
        url: 'http://localhost:8080/test',
        data: datos
        );

【讨论】:

以上是关于如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何结合 Spring Boot HornetQAutoConfiguration 和 CachingConnectionFactory?

如何在 Spring Boot pom.xml 中临时禁用依赖项 [关闭]

构建一个简单的Spring Boot项目

找不到带有spring boot的html页面

Spring Boot 获得帮助

使用带有spring数据缓存的redis时如何启用分布式/集群缓存