Preface:
Using OAuth2 in web projects, after springBoot integrated OAuth2, series 3 (UserDetailsService), the Postman access interface was no longer a problem, but there were cross-domain errors in separating web pages from front and back ends
Series of articles:
SpringBoot integration with OAuth2 Series 1 (simplest configuration)
SpringBoot integrated OAuth2 series 2
SpringBoot integrated oAuth2, Series 3 (UserDetailsService)
SpringBoot integrates oAuth2, Series 4 (Cross-domain issues of using oAuth2 in Front and back End Separation web pages)
The solution
1. The maven configurations, Add spring-security-oauth2 before spring-security-oauth2-autoconfigure (because the version of spring-security-oauth2 included in autoconfigure is higher) Some oAuth features have been deprecated and Spring Security 5 is recommended.)
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> < version > 2.3.1. RELEASE < / version > < / dependency > < the dependency > < groupId > org. Springframework. Security. Request. The boot < / groupId > < artifactId > spring ws-security - oauth2 - autoconfigure < / artifactId > < version > 2.3.1. RELEASE < / version > < / dependency >Copy the code
2. Configure CorsConfig globally
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); Config.addallowedorigin ("*"); AddAllowedHeader ("*"); // # Set Origin config.addAllowedHeader(" "); // # Set Origin config.addAllowedHeader(" "); Config.setmaxage (18000L); Config.addallowedmethod ("*"); config.addAllowedMethod("*"); / / allowed to submit a request, the method of * said all allow source in registerCorsConfiguration (" / * *, "); return new CorsFilter(source); } @Bean public FilterRegistrationBean customCorsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); //IMPORTANT #2: I didn't stress enough the importance of this line in my original answer, //but it's here where we tell Spring to load this filter at the right point in the chain //(with an order of precedence higher than oauth2's filters) bean.setOrder(Ordered.HIGHEST_PRECEDENCE); return bean; }}Copy the code
3. @ EnableAuthorizationServer from start classes instead of in the corresponding configuration
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @autowired public PasswordEncoder PasswordEncoder; public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .inMemory() .withClient("first-client") .secret(passwordEncoder.encode("noonewilleverguess")) .scopes("resource:read") .authorizedGrantTypes("password","authorization_code"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints.authenticationManager(authenticationManager); }}Copy the code
4.@EnableResourceServer From the boot class to the corresponding configuration
import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http // .cors().and().csrf().disable() .authorizeRequests() .antMatchers("/boke/**","/sys/request-log/**").permitAll() .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() .anyRequest().authenticated(); }}Copy the code
On the pit process
1. The first thing that comes to mind is cros().disable()
import org.mayanze.dcims.base.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired MyUserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager() throws Exception { return super.authenticationManager(); } @Bean @Override public UserDetailsService userDetailsService() { return userDetailsService; } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } // @override // public void configure(HttpSecurity HTTP) throws Exception {// // All requests must authenticate // http.authorizerequests () // .antMatchers("/boke/**","/sys/request-log/**","/oauth/token").permitAll() // .anyRequest().authenticated().and() // .cors().and().csrf().disable(); / /}}Copy the code
Cors ().and().csrf().disable().cors().csrf().disable().cors().csrf().disable().cors().cors().csrf().disable()
import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http // .cors().and().csrf().disable() .authorizeRequests() .antMatchers("/boke/**","/sys/request-log/**").permitAll() .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() .anyRequest().authenticated(); }}Copy the code
3. After countless network searches, configure a global cross-domain solution
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); Config.addallowedorigin ("*"); AddAllowedHeader ("*"); // # Set Origin config.addAllowedHeader(" "); // # Set Origin config.addAllowedHeader(" "); Config.setmaxage (18000L); Config.addallowedmethod ("*"); config.addAllowedMethod("*"); / / allowed to submit a request, the method of * said all allow source in registerCorsConfiguration (" / * *, "); return new CorsFilter(source); } @Bean public FilterRegistrationBean customCorsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); //IMPORTANT #2: I didn't stress enough the importance of this line in my original answer, //but it's here where we tell Spring to load this filter at the right point in the chain //(with an order of precedence higher than oauth2's filters) bean.setOrder(Ordered.HIGHEST_PRECEDENCE); return bean; }}Copy the code