2016-08-28 28 views
1

在这里工作是采用了棱角分明1.5的应用程序发出请求时什么我得到在Chrome控制台:CORS不会在春季4.3的OAuth2

的XMLHttpRequest无法加载http://localhost:8080/api/oauth/token。 对预检请求的响应未通过访问控制检查:否 请求的 资源上存在“访问控制 - 允许来源”标头。原因'http://localhost:8000'因此不允许 访问。该响应具有HTTP状态代码401.

当我删除OAuth2配置时,错误消失。

这是我的CORS配置:

class AppWebSpringConfig extends WebMvcConfigurerAdapter implements ServletContextAware { 

... 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
     registry.addMapping("/**") 
       .allowedOrigins("*") 
       .allowedMethods("GET", "POST", "PUT", "DELETE") 
       .allowedHeaders("X-Requested-With", "X-Auth-Token", "Origin", "Content-Type", "Accept") 
       .allowCredentials(false) 
       .maxAge(3600); 
    } 

... 
} 

而且我的OAuth2配置类:

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { 

    @Override 
    protected MethodSecurityExpressionHandler createExpressionHandler() { 
     return new OAuth2MethodSecurityExpressionHandler(); 
    } 

} 

@Configuration 
class OAuth2ServerConfiguration { 

    private static final int ONE_HOUR = 3600; 
    private static final int THIRTY_DAYS = 2592000; 

    @Configuration 
    @EnableResourceServer 
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

     @Override 
     public void configure(HttpSecurity http) throws Exception { 
      // @formatter:off 
      http 
        .authorizeRequests() 
        .anyRequest().authenticated(); 
      // @formatter:on 
     } 

    } 

    @Configuration 
    @EnableAuthorizationServer 
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 

     @Autowired 
     @Qualifier("authenticationManagerBean") 
     private AuthenticationManager authenticationManager; 

     @Autowired 
     private UserSecurityService userSecurityService; 

     @Autowired 
     private DataSource dataSource; 

     @Autowired 
     private Environment env; 

     @Override 
     public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
      // @formatter:off 
      endpoints 
        .tokenStore(tokenStore()) 
        .authenticationManager(authenticationManager) 
        .userDetailsService(userSecurityService); 
      // @formatter:on 
     } 

     @Bean 
     public TokenStore tokenStore() { 
      return new JdbcTokenStore(dataSource); 
     } 

     @Override 
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
      // @formatter:off 
      clients 
        .jdbc(dataSource) 
        .withClient(env.getProperty(CLIENT_ID_WEB)) 
        .secret(env.getProperty(CLIENT_SECRET_WEB)) 
        .authorizedGrantTypes("password", "refresh_token") 
        .scopes("read", "write") 
        .accessTokenValiditySeconds(ONE_HOUR) 
        .refreshTokenValiditySeconds(THIRTY_DAYS); 
      // @formatter:on 
     } 

     @Bean 
     @Primary 
     public DefaultTokenServices tokenServices() { 
      final DefaultTokenServices tokenServices = new DefaultTokenServices(); 
      tokenServices.setSupportRefreshToken(true); 
      tokenServices.setTokenStore(tokenStore()); 
      return tokenServices; 
     } 

    } 

} 

编辑:我也试图与以下过滤器实现,但它不工作。我在doFilter()方法中放置了一个断点,但执行不会停在那里,就像我的过滤器没有注册一样。但是,当我添加一个默认构造函数来过滤并在其中放置一个断点时,它会停止,这意味着该过滤器已被注册。

@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() { 
    } 
} 

我也尝试过这种方法,但没有运气再次声明:Allow OPTIONS HTTP Method for oauth/token request

我认为OAuth2用户配置不允许以请求甚至通过配置CORS过滤得到。 有人知道这个问题的解决方案吗?

EDIT2: 所以,事实证明,有一类:

public class AppSecurityInitializer extends AbstractSecurityWebApplicationInitializer { 

    // nothing here, using defaults 

} 

一旦我评论它,CORS配置开始工作(可能是由于过滤器的传球),但现在我的OAuth2配置不工作所有!每个URL都是暴露的,没有安全性。有什么想法吗?

回答

1

HIII我有同样的问题带弹簧4.3,但在这里解决的是答案: -

你需要重写AuthorizationServerConfigurerAdapter的以下方法在AuthorizationServerConfiguration类,并添加CORS筛选有使用addTokenEndpointAuthenticationFilter AuthorizationServerSecurityConfigurer的方法如下: -

@Override 
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { 
     security.addTokenEndpointAuthenticationFilter(new CORSFilter()); 
} 

你AuthorizationServerConfiguration类将是: -

@Configuration 
    @EnableAuthorizationServer 
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 

     @Autowired 
     @Qualifier("authenticationManagerBean") 
     private AuthenticationManager authenticationManager; 

     @Autowired 
     private UserSecurityService userSecurityService; 

     @Autowired 
     private DataSource dataSource; 

     @Autowired 
     private Environment env; 

     @Override 
     public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
      // @formatter:off 
      endpoints 
        .tokenStore(tokenStore()) 
        .authenticationManager(authenticationManager) 
        .userDetailsService(userSecurityService); 
      // @formatter:on 
     } 

     @Bean 
     public TokenStore tokenStore() { 
      return new JdbcTokenStore(dataSource); 
     } 

     @Override 
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
      // @formatter:off 
      clients 
        .jdbc(dataSource) 
        .withClient(env.getProperty(CLIENT_ID_WEB)) 
        .secret(env.getProperty(CLIENT_SECRET_WEB)) 
        .authorizedGrantTypes("password", "refresh_token") 
        .scopes("read", "write") 
        .accessTokenValiditySeconds(ONE_HOUR) 
        .refreshTokenValiditySeconds(THIRTY_DAYS); 
      // @formatter:on 
     } 

     @Bean 
     @Primary 
     public DefaultTokenServices tokenServices() { 
      final DefaultTokenServices tokenServices = new DefaultTokenServices(); 
      tokenServices.setSupportRefreshToken(true); 
      tokenServices.setTokenStore(tokenStore()); 
      return tokenServices; 
     } 

     // ***** Here I added CORS filter ***** 
     @Override 
     public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { 
       security.addTokenEndpointAuthenticationFilter(new CORSFilter()); 
     } 
}