【问题标题】:CORS doesn't work on Spring 4.3 with OAuth2CORS 不适用于带有 OAuth2 的 Spring 4.3
【发布时间】:2017-01-04 14:28:04
【问题描述】:

这是我在使用 Angular 1.5 应用程序发出请求时在 Chrome 控制台中得到的内容:

XMLHttpRequest 无法加载 http://localhost:8080/api/oauth/token。 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“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 过滤器。 有人知道这个问题的解决方案吗?

编辑2: 所以,原来有一个类:

public class AppSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    // nothing here, using defaults

}

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

【问题讨论】:

    标签: spring spring-security oauth cors spring-security-oauth2


    【解决方案1】:

    嗨,我在 spring 4.3 上遇到了同样的问题,但这里解决了答案:-

    您需要在 AuthorizationServerConfiguration 类中覆盖 AuthorizationServerConfigurerAdapter 的以下方法,并使用 AuthorizationServerSecurityConfigurer 的 addTokenEndpointAuthenticationFilter 方法在其中添加 CORS 过滤器,如下所示:-

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

    【讨论】:

      猜你喜欢
      • 2016-04-20
      • 2016-03-13
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2020-02-07
      • 2016-03-25
      • 2019-05-25
      相关资源
      最近更新 更多