Spring 启动 Oauth2 + Angular CORS 问题
Spring boot Oauth2 + Angular CORS problem
我是制作授权服务的新手。当我尝试从 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) 如果您使用的是 dev,则在 chrome 上启用 CORS(扩展)(POSTMAN 默认执行此操作)
2) 在生产中,托管它的 angular 应用程序应该将您列入白名单 API URL,
3)第三组cors允许原点headers
3 天后我找到了解决方案。首先,我删除了我的身份验证服务中的所有过滤器。其次,我在我的网关服务中添加了这个道具:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders:
- content-type
- x-requested-with
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
- DELETE
- PUT
您只需要在网关属性中为所有服务添加全局headers,这也可以与服务中的过滤器结合使用以进行更灵活的设置。
我希望这可以帮助一些人节省 3 天)
我是制作授权服务的新手。当我尝试从 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) 如果您使用的是 dev,则在 chrome 上启用 CORS(扩展)(POSTMAN 默认执行此操作)
2) 在生产中,托管它的 angular 应用程序应该将您列入白名单 API URL,
3)第三组cors允许原点headers
3 天后我找到了解决方案。首先,我删除了我的身份验证服务中的所有过滤器。其次,我在我的网关服务中添加了这个道具:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders:
- content-type
- x-requested-with
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
- DELETE
- PUT
您只需要在网关属性中为所有服务添加全局headers,这也可以与服务中的过滤器结合使用以进行更灵活的设置。 我希望这可以帮助一些人节省 3 天)