Spring Security OAuth2 中 CORS 跨域问题

错误情况

项目中包含 Spring Security 就会有 401 的问题,Spring Security 本身是通过 Filter 实现的,如果没有对其单独做 CORS 的处理,在 Web Security 报错 401 的时候是不会返回相应的 CORS 的字段的。这会导致出现的 401 错误成为了一个无法进行跨域的错误,导致前端程序无法正常的处理 401 相应 。对于spring security oauth2 默认接口,例如 /oauth/token 跨域问题,可以通过全局 CORS Filter 解决

解决办法

1、在spring boot项目中配置跨域

@Configuration
public class MyCorsConfiguration {

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1  
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedMethod("*"); // 3  
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4  
        return new CorsFilter(source);
    }

}

2、设置对/oauth/路径的特殊处理

在函数头中加入注解:

@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-1)

在config中加入

http.requestMatchers().antMatchers(HttpMethod.OPTIONS, "/oauth/**")
				.and()
				.cors()
				.and()
				.csrf().disable();

代码展示

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-1)
public class WebsecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private MyUserDetailsService userDetailsService;

	@Autowired
	public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.exceptionHandling().accessDeniedHandler(new InterestAccessDeniedHandler());
		http.authorizeRequests().anyRequest().authenticated();
		http.requestMatchers().antMatchers(HttpMethod.OPTIONS, "/oauth/**")
				.and()
				.cors()
				.and()
				.csrf().disable();
//		http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/oauth/**");
		http.formLogin().failureUrl("/login?error").permitAll();
		http.logout().permitAll();
		http.csrf().disable();
	}

	// 配置内存模式的用户
	/*
	 * @Bean
	 * 
	 * @Override protected UserDetailsService userDetailsService(){
	 * InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
	 * manager.createUser(User.withUsername("test").password("123").authorities(
	 * "USER").build());
	 * manager.createUser(User.withUsername("test1").password("123").authorities(
	 * "USER").build()); return manager; }
	 */

	/**
	 * 需要配置这个支持password模式 support password grant type
	 * 
	 * @return
	 * @throws Exception
	 */
	@Override
	@Bean
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}

}

猜你喜欢

转载自blog.csdn.net/windows_2006/article/details/94736457