【问题标题】:Spring boot Oauth2 + Angular CORS problemSpring boot Oauth2 + Angular CORS问题
【发布时间】:2020-09-08 00:29:02
【问题描述】:

我是提供身份验证服务的新手。当我尝试从 Postman 获取访问令牌时,一切正常。但是当我使用 Angular 时,我得到了这个错误:

Access to XMLHttpRequest at 'localhost:8082/oauth/token' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

我的配置是:

@SpringBootApplication
@EnableEurekaClient
@EnableWebSecurity
public class AuthMsApplication extends WebSecurityConfigurerAdapter {

public static void main(String[] args) {
    SpringApplication.run(AuthMsApplication.class, args);
 }
}

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter("/*")
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "content-type, x-requested-with, authorization");
        response.setHeader("Access-Control-Max-Age", "3600");
        if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

    @EnableAuthorizationServer
    @Configuration
    public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        private static final String READ = "read";
        private static final String WRITE = "write";
        private static final String PASSWORD = "password";
        private static final String REFRESH_TOKEN = "refresh_token";

        @Value("${client.id}")
        private String clientId;
        @Value("${client.secret}")
        private String clientSecret;
        @Value("${tokenSignature}")
        private String tokenSignature;
        @Value("${accessTokenValiditySeconds}")
        private int accessTokenValiditySeconds;
        @Value("${refreshTokenValiditySeconds}")
        private int refreshTokenValiditySeconds;

        private final AuthenticationManager authenticationManager;
        private final UserDetailsService customDetailsService;

        public OAuth2Config(@Qualifier("authenticationProviderImpl") AuthenticationManager authenticationManager,
                            UserDetailsService customDetailsService) {
            this.authenticationManager = authenticationManager;
            this.customDetailsService = customDetailsService;
        }

        @Bean
        public JwtAccessTokenConverter tokenEnhancer() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setSigningKey(tokenSignature);
            return converter;
        }

        @Bean
        public JwtTokenStore tokenStore() {
            return new JwtTokenStore(tokenEnhancer());
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            endpoints.authenticationManager(authenticationManager)
                    .tokenStore(tokenStore())
                    .accessTokenConverter(tokenEnhancer())
                    .userDetailsService(customDetailsService);
        }

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

        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) {
            security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");

        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            String encodedClientSecret = encoder().encode(clientSecret);
            clients.inMemory()
                    .withClient(clientId)
                    .secret(encodedClientSecret)
                    .scopes(READ, WRITE)
                    .authorizedGrantTypes(PASSWORD, REFRESH_TOKEN)
                    .accessTokenValiditySeconds(accessTokenValiditySeconds)
                    .refreshTokenValiditySeconds(refreshTokenValiditySeconds);
        }
    }

任何搜索信息都不能作为全局 CORS。一件事正在发挥作用

@CrossOrigin(origins = "*", allowedHeaders = "*")

但是我可以把它放在我自己的控制器上,我不知道如何为 oauth/token 端点设置它。

这个官方文档解决方案不起作用。 https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html

过滤器也不起作用。

【问题讨论】:

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


    【解决方案1】:

    3 天后,我找到了解决方案。首先,我删除了身份验证服务中的所有过滤器。其次,我在我的网关服务中添加了这个道具:

    cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*"
            allowedHeaders:
              - content-type
              - x-requested-with
              - Authorization
            allowedMethods:
              - GET
              - POST
              - OPTIONS
              - DELETE
              - PUT
    

    您只需在网关道具中为您的所有服务添加全局标头,这也可以与服务中的过滤器相结合以获得更灵活的设置。 我希望这可以帮助一些人节省 3 天)

    【讨论】:

    • 这与doFilter() 中的做法有何不同?我和你有同样的问题,但我的 Java 应用程序中没有任何网关配置。
    【解决方案2】:

    这是一个普遍的问题, 因为来源不同所以保护不同来源的注入。

    解决方案:

    1) 如果您使用的是 for dev,则在 chrome 上启用 CORS(扩展)(POSTMAN 默认执行此操作)

    2) 在生产中,托管它的 Angular 应用程序应将您的 API URL 列入白名单,

    3) 第三组 cors 允许原始标头

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 2017-04-13
      • 2017-05-13
      • 2018-10-30
      • 2021-04-11
      • 2019-02-14
      • 2016-07-09
      • 2018-07-12
      相关资源
      最近更新 更多