Home > Java > javaTutorial > body text

How to solve the problem that SpringBoot+Spring Security cannot achieve cross-domain

WBOY
Release: 2023-05-16 15:40:55
forward
1056 people have browsed it

SpringBoot Spring Security cannot achieve cross-domain

Cross-domain when Security is not used:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
@AutoConfigureBefore(SecurityConfig.class)
public class MyMvcConfigurer implements WebMvcConfigurer {
    public void addCorsMappings(CorsRegistry registry){
        LOGGER.info("跨域已设置");
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}
Copy after login

When integrating Security, we found that there are still cross-domain problems when only using the above method to separate the front and back ends,

The solution is as follows:

@Configuration
@AutoConfigureBefore(Swagger2Configuration.class)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginProcessingUrl("/user/login")
                .loginPage("/singIn.html")
                .successHandler(moyuAuthenticationSuccessHandler)
                .failureHandler(moyuAuthenticationFailureHandler)
                .and()
                .apply(moyuSocialSecurityConfig)
                .and()
                .rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(3600*24*7)
                .userDetailsService(userDetailsService)
                .and()
                .authorizeRequests()
                .antMatchers("/user/login","/login","/singIn.html","**","/**").permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .cors()
                .and()
                .csrf().disable();
    }
}
Copy after login

Focus on adding code:

   .and()
   .cors()//新加入
   .and()
   .csrf().disable();
Copy after login

Quoting the cross-domain processing of the Spring Security project

The recent project adopts a framework of front-end and back-end separation. The front-end and back-end interfaces are not deployed to a site, and a cross-domain problem occurs. What is cross-domain, I will not go into details here, and just talk about the solution.

Spring has many ways to solve cross-domain problems. I personally use Crosfilter.

The specific code is as follows:

@Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new      UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
Copy after login

After the configuration is completed, test the call and report an error 401, but it still doesn’t work. . After checking the information online, I learned that cross-domain requests will be made twice. The specific process is shown in the figure below:

SpringBoot+Spring Security无法实现跨域怎么解决

For each cross-domain request, before the actual request reaches the backend, the browser will first initiate a preflight request, and the request method is OPTIONS to query the server. Whether to accept the cross-domain request, the specific parameters are as follows:

SpringBoot+Spring Security无法实现跨域怎么解决

#But the request cannot carry cookies and self-defined headers.

Since Spring security was introduced in the project, the token delivery method I used was to use the authorization field in the header. In this way, I relied on Spring Security to intercept the preflight request and found that it did not carry a token, and an error 401 was reported, not authorized. .

Solving this problem is very simple. You can use the following configuration

to make Spring security not verify the preflight request.

 @Override
    public void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry 
        = http.authorizeRequests();
        registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//让Spring security放行所有preflight request 
    }
Copy after login

It will be fixed if you try again, but directly configuring the backend to support cross-domain will result in two requests. Another way is to use Nginx to forward the request.

The above is the detailed content of How to solve the problem that SpringBoot+Spring Security cannot achieve cross-domain. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!