Standalone Spring OAuth2 JWT Authorization Server + CORS

前端 未结 6 1315
长发绾君心
长发绾君心 2020-11-28 04:01

So I have the following Authorization Server condensed from this example from Dave Syer

@SpringBootApplication
publi         


        
相关标签:
6条回答
  • 2020-11-28 04:20

    I found a solution using the solution for the question. But I have another way to describe the solution:

    @Configuration
    public class WebSecurityGlobalConfig extends WebSecurityConfigurerAdapter {
          ....
          @Override
          public void configure(WebSecurity web) throws Exception {
            web.ignoring()
              .antMatchers(HttpMethod.OPTIONS);
          }
          ...
    }
    
    0 讨论(0)
  • 2020-11-28 04:22
    I tried different things to solve this issue. I would say that the below was fixed this issue on my side (Using Spring Boot 2)
    1-Add the below method to the below method class that extends WebSecurityConfigurerAdapter:
        // CORS settings
         @Override
         public void configure(WebSecurity web) throws Exception {
           web.ignoring()
             .antMatchers(HttpMethod.OPTIONS);
         }
    
    2-Add the below to my class that extends AuthorizationServerConfigurerAdapter
    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // enable cors for "/oauth/token"
        Map<String, CorsConfiguration> corsConfigMap = new HashMap<>();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
       
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedMethods(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        corsConfigMap.put("/oauth/token", config);
        endpoints.getFrameworkEndpointHandlerMapping()
                .setCorsConfigurations(corsConfigMap);
        // add the other configuration
    }
    
    0 讨论(0)
  • 2020-11-28 04:23

    Found the reason for my Problem!

    I just needed to end the filterchain and return the result immediatly if a OPTIONS request is processed by the CorsFilter!

    SimpleCorsFilter.java

    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class SimpleCorsFilter implements Filter {
    
        public SimpleCorsFilter() {
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
    
            if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                chain.doFilter(req, res);
            }
        }
    
        @Override
        public void init(FilterConfig filterConfig) {
        }
    
        @Override
        public void destroy() {
        }
    }
    

    After that I could ignore the OPTIONS preflight request in my AuthServer =D

    So the Server works as in the snipped above and you can ignore the block comment with MyWebSecurity class in the beginning.

    0 讨论(0)
  • 2020-11-28 04:28

    well, you're right! that's a solution, and it worked also for me (I had the same issue)

    But let me sussgest to use a smarter CORS Filter implementation for Java: http://software.dzhuvinov.com/cors-filter.html

    This is very complete solution for Java applications.

    Actually, you can see here how your point is resolved.

    0 讨论(0)
  • 2020-11-28 04:31

    I came across similar issue using following

    • Backend Spring Boot 1.5.8.RELEASE
    • Spring OAuth2 Spring OAuth 2.2.0.RELEASE w
    • Vuejs app using axios ajax request library

    With postman everything works! When I started making request from Vuejs app then I got the following errors

    OPTIONS http://localhost:8080/springboot/oauth/token 401 ()

    and

    XMLHttpRequest cannot load http://localhost:8080/springboot/oauth/token. Response for preflight has invalid HTTP status code 401

    After reading a bit, I found out that I can instruct my Spring OAuth to ignore the OPTIONS request by overriding configure in my WebSecurityConfigurerAdapter implementation class as follow

    @Override
    public void configure(WebSecurity web) throws Exception {
       web.ignoring().antMatchers(HttpMethod.OPTIONS);
    }
    

    Addition of the above helped but then, I came across the CORS specific error

    OPTIONS http://localhost:8080/springboot/oauth/token 403 ()

    and

    XMLHttpRequest cannot load http://localhost:8080/springboot/oauth/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 403.

    And solved the above issue with the help of a CorsConfig as shown below

    @Configuration
    public class CorsConfig {
        @Bean
        public FilterRegistrationBean corsFilterRegistrationBean() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.applyPermitDefaultValues();
            config.setAllowCredentials(true);
            config.setAllowedOrigins(Arrays.asList("*"));
            config.setAllowedHeaders(Arrays.asList("*"));
            config.setAllowedMethods(Arrays.asList("*"));
            config.setExposedHeaders(Arrays.asList("content-length"));
            config.setMaxAge(3600L);
            source.registerCorsConfiguration("/**", config);
            FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
            bean.setOrder(0);
            return bean;
        }
    }
    

    After addition of the above class, it works as expected. Before I go prod I will research consequences of using

    web.ignoring().antMatchers(HttpMethod.OPTIONS);

    as well as best practices for above Cors configuration. For now * does the job but, definitely not secure for production.

    Cyril's answer helped me partially and then I came across the CorsConfig idea in this Github issue.

    0 讨论(0)
  • 2020-11-28 04:32

    Using Spring Boot 2 here.

    I had to do this in my AuthorizationServerConfigurerAdapter

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    
        Map<String, CorsConfiguration> corsConfigMap = new HashMap<>();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        //TODO: Make configurable
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedMethods(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        corsConfigMap.put("/oauth/token", config);
        endpoints.getFrameworkEndpointHandlerMapping()
                .setCorsConfigurations(corsConfigMap);
    
        //additional settings...
    }
    
    0 讨论(0)
提交回复
热议问题