Spring boot Oauth2 + Angular CORS问题
Posted
技术标签:
【中文标题】Spring boot Oauth2 + Angular CORS问题【英文标题】:Spring boot Oauth2 + Angular CORS problem 【发布时间】: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
过滤器也不起作用。
【问题讨论】:
【参考方案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 允许原始标头
【讨论】:
以上是关于Spring boot Oauth2 + Angular CORS问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 spring-boot OAuth2 服务器保护的 Spring-boot 应用程序
让 oauth2 与 spring-boot 和 rest 一起工作
Spring Boot Restful WebAPI集成 OAuth2
Spring Boot + Spring Security + Spring OAuth2 + Google 登录