我有Spring Boot Rest应用程序。 最近,我已经使用JsonWebToken实现了用户身份验证。
当我使用邮递员进行测试时,一切似乎都可以正常工作, 但是当从Angular Application调用其余部分时,我得到了错误 指的是cors:
对预检请求的响应未通过访问控制检查:所请求的资源上不存在“ Access-Control-Allow-Origin”标头。因此,不允许访问来源“ http://localhost:4200”。响应的HTTP状态码为403。
这是我的代码:
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthFilter authFilter;
@Autowired
private JwtAuthenticationProvider authenticationProvider;
@Autowired
private JwtAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().ignoringAntMatchers("/token");
http.csrf().disable();
http.cors().and().authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/token").permitAll()
.antMatchers("/rest/**").authenticated()
.and()
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS","PUT","DELETE"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/rest/**", configuration);
return source;
}
}
JwtAuthFilter:
@Component
public class JwtAuthFilter implements Filter
{
@Override
public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String authorization = servletRequest.getHeader("Authorization");
String origin = servletRequest.getHeader("Origin");
if (authorization != null)
{
JwtAuthToken token = new JwtAuthToken(authorization.replaceAll("Bearer ", ""));
SecurityContextHolder.getContext().setAuthentication(token);
}
filterChain.doFilter(servletRequest, response);
}
@Override
public void destroy()
{
}
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
}
我的登录Controller映射为“ / token”,所有其他控制器映射为“ / rest / **” 有趣的是,调用“ / token”控制器可以正常工作……它返回令牌和用户详细信息。服务器响应包含:
但是当我调用任何其他控制器...例如“ / rest / task / all”时,我得到了错误,并且没有access-control-allow-credentials和access-control-allow-origin头。
当我更改
source.registerCorsConfiguration("/rest/**", configuration);
到
source.registerCorsConfiguration("/**", configuration);
我收到一个错误,我在access-control-allow-origin标头中有两个值 http://localhost:4200和http://localhost:4200
任何人都可以提供:D吗?
答案 0 :(得分:0)
这是一个古老的问题,我不确定您是否找到答案。我只能提出调试这些问题的方法,因为这些问题通常是非常本地化的。
1.First-仅Java代码不足以调试CORS问题。您需要查看“浏览器网络”选项卡,并查看哪个呼叫失败-OPTIONS呼叫或实际数据呼叫。其次,在浏览器中,需要仔细查看请求和响应标头以查找失败的请求,并特别列出那些。这些下面。
在请求方-Origin
在响应方面-Access-Control-Allow-Credentials
,Access-Control-Allow-Headers
,Access-Control-Allow-Methods
和Access-Control-Allow-Origin
2。
当我使用邮递员进行测试时,一切似乎都可以正常工作,但是当 其余的是从Angular Application调用的,我遇到了引用错误 科尔斯:
这是正常现象,因为CORS是浏览器安全功能,并且在任何其他客户端中都可能看不到此问题。 CORS错误并不表示您的API调用未成功,仅表示浏览器抑制了响应并且没有前进。
因此,如果您的API使用者不是网络浏览器,那么您在API方面最可能与CORS无关。其他客户端不会通过包含OPTIONS
请求来使其分为两步。
3。配置行-http.cors()
将向您的过滤器链添加过滤器-org.springframework.web.filter.CorsFilter
,因此请在此处和您的JwtAuthFilter
中放置断点,以查看代码流向何处。
4。预期URL的系统行为会有所不同-/token
和/rest/**
,因为令牌URL不安全,而rest / **只允许经过身份验证的用户使用,因此会出现其他过滤器。
Spring Security exclude url patterns in security annotation configurartion
How to disable spring security for particular url
因此,查找CORS问题的理想方法是通过接受有问题的请求并验证响应头-Access-Control-Allow-Origin
是否正确填充来调试代码。