isopropylcyanide / Jwt-Spring-Security-JPA

Backend MVP showcasing JWT (Json Web Token) authentication with multiple login, timeout / refresh / logout (with in memory invalidation) using Spring Security & MySQL JPA.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unsuitability when add CORS!

mjza opened this issue · comments

I needed to add CORS for development purposes. Then I added this snippet in the WebSecurity file.

@Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

However, when I added this some kind of unsuitability will happen. Sometimes the /api/user/me will failed, sometimes refresh token and so on. It will show 403 error:

{
    "timestamp": "2020-07-13T14:29:16.044+00:00",
    "status": 403,
    "error": "Forbidden",
    "message": "",
    "path": "/api/user/me"
}

And in the console:

14:29:16.027 [http-nio-9090-exec-10] INFO Spring Security Debugger -


Request received for GET '/api/user/me?_=1594650397767':

org.apache.catalina.connector.RequestFacade@46d44595

servletPath:/api/user/me
pathInfo:null
headers:
authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNTk0NjUwNDA4LCJleHAiOjE1OTQ2NTEzMDh9.Ez0UF8A-BytbzavjopGDOSwRlw57fjULzhRqunWjjJk9VEF-CYKvUGilm35wAnjh7GU
d8NKroPz_iIFFZo7I2A
user-agent: PostmanRuntime/7.26.1
accept: /
cache-control: no-cache
postman-token: ca351b9f-7cb0-4d2f-b542-b36a59b2154d
host: localhost:9090
accept-encoding: gzip, deflate, br
connection: keep-alive
cookie: JSESSIONID=96A9EE778A465B6CACCF7CEC0B1CC008

Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]


14:29:16.043 [http-nio-9090-exec-10] INFO Spring Security Debugger -


Request received for GET '/error?_=1594650397767':

org.apache.catalina.core.ApplicationHttpRequest@76e91dd

servletPath:/error
pathInfo:null
headers:
authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNTk0NjUwNDA4LCJleHAiOjE1OTQ2NTEzMDh9.Ez0UF8A-BytbzavjopGDOSwRlw57fjULzhRqunWjjJk9VEF-CYKvUGilm35wAnjh7GU
d8NKroPz_iIFFZo7I2A
user-agent: PostmanRuntime/7.26.1
accept: /
cache-control: no-cache
postman-token: ca351b9f-7cb0-4d2f-b542-b36a59b2154d
host: localhost:9090
accept-encoding: gzip, deflate, br
connection: keep-alive
cookie: JSESSIONID=96A9EE778A465B6CACCF7CEC0B1CC008

Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]


What is your suggestion for supporting CORS?

@isopropylcyanide Do you have any idea about this issue?

I think CORS needs to be enabled as a filter. Otherwise all requests would be dropped off. Not sure about it further. Found an article that might help for starters

Here is my solution for DevConfig:

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;


@Profile("dev")
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityDevConfig extends WebSecurityConfigurerAdapter {

    private static final Logger logger = Logger.getLogger(WebSecurityDevConfig.class);
    
    @Override
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        logger.info("Loaded inside a dev only");
        http.cors().and()
        	.csrf().disable()
        	.authorizeRequests()
	        .anyRequest().permitAll();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

Thank you for sharing your solution here @mjza I'm sure it would help a lot of folks. Also, might be related #1