带有JWT的Spring Boot Oauth2-React CORS问题

时间:2019-05-18 09:36:46

标签: reactjs spring-boot cors jwt spring-security-oauth2

我正在使用Spring Security Oauth2设置授权服务器。一切都能按照邮递员的预期进行,但是当尝试使用axios从ReactJS前端获取JWT令牌时,我遇到了CORS问题。

我已经尝试过servlet过滤器方式和弹簧安全性CorsConfigurationSource bean注入。似乎没有任何工作。前端向OPTIONS请求发送API后,我得到了401,紧接着来自起源“ http://localhost:9000/uaa/oauth/token?grant_type=password&username=user&password=password”的“ http://localhost:3001”被CORS策略阻止:对预检请求的响应未通过访问控制检查:它没有HTTP正常状态。

我的Cors过滤器类:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterJwt implements Filter {


@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", "http://localhost:3001");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Authorization,Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}

WebSecurityConfig:

@Configuration
@Order(2147483636)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

private final DataSource dataSource;
private final CustomUserDetailsService userDetailsService;

@Autowired
public WebSecurityConfig(DataSource dataSource,CustomUserDetailsService userDetailsService) {
    this.dataSource=dataSource;
    this.userDetailsService=userDetailsService;
}

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

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/login").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic();
}


@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService)
            .and()
            .jdbcAuthentication()
            .passwordEncoder(encoder())
            .dataSource(dataSource);
}

@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder(11);
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.addAllowedHeader("*");
    configuration.addAllowedMethod("*");
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}}

WebMvcConfig:

@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("login");
    registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}

@Bean
FilterRegistrationBean forwardedHeaderFilter() {
    FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
    filterRegBean.setFilter(new ForwardedHeaderFilter());
    filterRegBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return filterRegBean;
}

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                    .allowedHeaders("*");
        }
    };
}

反应AXIOS代码:

signInWithEmailAndPassword = (username, password) => {
    return new Promise((resolve, reject) => {
        axios.post('http://localhost:9000/uaa/oauth/token?grant_type=password&username=user&password=password', {
            data: {
                username: username,
                password: password,
                grant_type:'password',
                scope:'ui',

            },
        }).then(response => {
            if ( response.data.user )
            {
                this.setSession(response.data.access_token);
                resolve(response.data.user);
            }
            else
            {
                reject(response.data.error);
            }
        });
    });
};

一旦我将axios post请求发送到令牌端点,我将获得401状态代码以用于OPTIONS请求,然后从原始地址“ http://localhost:9000/uaa/oauth/token?grant_type=password&username=user&password=password”访问“ http://localhost:3001”处的XMLHttpRequest已被CORS政策阻止:对预检请求的响应未通过访问控制检查:它没有HTTP正常状态。

当您从Postman调用API时,效果很好。

0 个答案:

没有答案