2016-05-30 18 views
6

Utilizzo il boot a molla per effettuare un semplice servizio di assistenza. Per consumarlo in Angular 2, ho riscontrato un problema con CORS durante il recupero di token su oauth/token endpoint.Opzioni di servizio di arresto dello stivale a molla 401 su oauth/token

Il messaggio di errore in Chrome è di seguito.

error message

zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token 
XMLHttpRequest cannot load http://192.168.0.9:8080/api/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:3000' is therefore not allowed access. The response had HTTP status code 401. 

I file correlati sono al di sotto.

MyConfig.java

@Configuration 
public class MyConfig { 
    @Bean 
    public WebMvcConfigurer corsConfigurer() { 
     return new WebMvcConfigurerAdapter() { 
      @Override 
      public void addCorsMappings(CorsRegistry registry) { 
       registry.addMapping("**") 
         .allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS") 
       .allowCredentials(true) 
       .allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers") 
       .exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials") 
       .maxAge(10); 
      } 
     }; 
    } 
} 

OAuth2ResourceServerConfig.java

@Configuration 
@EnableResourceServer 
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { 
    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http 
      .csrf().disable() 
      .anonymous() 
      .and() 
       .authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS,"**").permitAll() 
       .antMatchers("/authenticated/**").authenticated() 
       ; 
    } 

} 

Sono nuovo di Java e la primavera. Ho trovato alcune domande simili, come ad esempio OAuth2 - Status 401 on OPTIONS request while retrieving TOKEN, ma davvero non capisco come farlo funzionare nel boot di primavera.

Nota: l'endpoint del controller di riposo normale funziona correttamente. Il problema è oauth/token, la richiesta di opzioni restituisce lo stato 401.

Mostrami un codice di lavoro in avvio di primavera. Grazie!

risposta

9

È possibile aggiungere questo filtro CORS al progetto

@Component 
@Order(Ordered.HIGHEST_PRECEDENCE) 

public class SimpleCORSFilter implements Filter { 

@Override 
public void init(FilterConfig fc) throws ServletException { 
} 

@Override 
public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain chain) throws IOException, ServletException { 
    HttpServletResponse response = (HttpServletResponse) resp; 
    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, Content-Type, Authorization, credential, X-XSRF-TOKEN"); 

    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 
     response.setStatus(HttpServletResponse.SC_OK); 
    } else { 
     chain.doFilter(req, resp); 
    } 

} 

@Override 
public void destroy() { 
} 

} 
+0

Ho trovato questa risposta in un altro post. Ma in Spring Boot, raccomandava l'uso di WebMvcConfigurerAdapter come mostrato nel mio codice piuttosto che nel filtro. Puoi vedere che hanno un codice simile ad eccezione della parte "OPZIONI". Quindi mi chiedo se è possibile aggiungere un simile codice "OPZIONI" al mio file? Grazie. – weijun

+0

il tuo codice funziona! :) – weijun

+1

Grazie mille !!!!! Mi hai salvato la giornata dopo aver passato circa 4 giorni con questo problema !!! –

1

Ecco nativo soluzione Spring Framework:

@Bean 
public CorsFilter corsFilter(CorsConfiguration config) { 
    log.debug("Registering CORS filter"); 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    source.registerCorsConfiguration("/api/**", config); 
    source.registerCorsConfiguration("/v2/api-docs", config); 
    source.registerCorsConfiguration("/oauth/**", config); 
    return new CorsFilter(source); 
} 
1

se si utilizza avvio primavera + OAuth Primavera è necessario aggiungere

@Order(Ordered.HIGHEST_PRECEDENCE) 

al filtro CORS

@Configuration 
@Order(Ordered.HIGHEST_PRECEDENCE) 
public class CORSFilter implements Filter { 

    private FilterConfig config; 

    public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials"; 
    public static final String ORIGIN_NAME = "Access-Control-Allow-Origin"; 
    public static final String METHODS_NAME = "Access-Control-Allow-Methods"; 
    public static final String HEADERS_NAME = "Access-Control-Allow-Headers"; 
    public static final String MAX_AGE_NAME = "Access-Control-Max-Age"; 

    @Override 
    public void destroy() { 

    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse resp, 
         FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) resp; 
     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, Content-Type, Authorization, credential, X-XSRF-TOKEN"); 

     if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 
      response.setStatus(HttpServletResponse.SC_OK); 
     } else { 
      chain.doFilter(req, resp); 
     } 

    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     config = filterConfig; 
    } 
} 
Problemi correlati