I have Spring boot rest application. Recently I have implemented user authentication using JsonWebToken.
Everything seems to work fine when I test it using postman, but when the rest is called from Angular Application I got errors refering to cors:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.
Here is my code:
@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
{
}
}
My login Controller has a mapping "/token", and all other controllers are mapped as "/rest/**" Interesting is that calling a "/token" controller works fine... it returns token and user details. Server respond contains:
- access-control-allow-credentials →true
- access-control-allow-origin → http://localhost:4200
but when I call any other controller... for example "/rest/task/all" I got error and there is no access-control-allow-credentials and access-control-allow-origin headers.
when I change
source.registerCorsConfiguration("/rest/**", configuration);
to
source.registerCorsConfiguration("/**", configuration);
I got error that I have two values in access-control-allow-origin header http://localhost:4200 and http://localhost:4200
Anyone has any help to offer :D ?