当我使用前端源代码调用后端java服务器时,遇到了以下错误。
Access to XMLHttpRequest at 'http://localhost:8513/oauth/token' from origin 'http://localhost:9513' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
我使用的是springboot(2.2.4.RELEASE) + OAuth2(2.2.1.RELEASE)+Jwt(1.0.9.RELEASE)。把我的pom.xml粘贴到这里
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>${oauth2.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>${spring-jwt.version}</version>
</dependency>
我已经添加了允许CORS警察的配置,但似乎它不工作。
JWTOAuth2Config.java。
@Configuration
@EnableAuthorizationServer
public class JWTOAuth2Config extends AuthorizationServerConfigurerAdapter{
private static final int accessTokenValiditySeconds = 5 * 60 * 1;
private static final int refreshTokenValiditySeconds = 60 * 60 * 1;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenEnhancer jwtTokenEnhancer;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
private UserService userService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtAccessTokenConverter));
endpoints
.tokenStore(tokenStore)
.accessTokenConverter(jwtAccessTokenConverter)
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager)
.userDetailsService(userService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("organization")
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("organization666"))
.authorizedGrantTypes("refresh_token", "password", "client_credentials")
.scopes("webclient", "mobileclient")
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds);
}
}
ResourceServerConfiguration.javaconfig允许CORS在ResourceServerConfigurerAdapter的HttpSecurity类,但不能工作。
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure (HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v1/moikiitos/**")
.authenticated()
.and().cors()
.and().csrf().disable();
}
}
配置允许在WebSecurityConfigurerAdapter中的HttpSecurity类进行CORS,但不能工作也.WebSecurityConfigurer.java。
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter{
@Autowired
UserService userService;
@Value("${security.enable-csrf}")
private boolean csrfEnabled;
@Override
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception{
return super.userDetailsServiceBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
if(!csrfEnabled) {
http.cors().and()
.csrf().disable();
}
}
}
在application.properties中设置csrf为flase。
security.enable-csrf=false
即使我也使用下面的java代码配置WebMvcConfiguer,但它也不能工作。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:9513")
.allowedMethods("*")
.allowedHeaders("*");
}
}
更何况,我还在我的控制器上使用了这个@CrossOrigin.有人能帮帮我吗?Appreciate.我读过一些文章,如 原点已被CORS策略Spring boot和React屏蔽。但不能帮助我。
我找到了原因。因为我在spring security中使用了Oauth+JWT。Spring security使用filter来设置cors,但是spring security中的filter很少。(@Order(Ordered.HIGHEST_PRECEDENCE)) 所以为我的过滤器设置一个序列是很重要的,附上源码供大家参考。
Cors配置
@Configuration
public class GlobalCorsConfiguration {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
配置认证
//This @Order is very important to setup the sequence of filter in spring security.
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter{
@Autowired
UserService userService;
@Override
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception{
return super.userDetailsServiceBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers(HttpMethod.OPTIONS, "/oauth/**")
.and()
.csrf().disable().formLogin()
.and()
.cors();
}
}
资源配置
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure (HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(HttpMethod.GET, "/v1/moikiitos/**").authenticated()
.and()
.authorizeRequests().antMatchers(HttpMethod.POST,"/v1/moikiitos/user/").permitAll()
.and()
.authorizeRequests().antMatchers(HttpMethod.POST,"/v1/moikiitos/**").authenticated();
}
}