How to enable CORS in spring boot with spring security - spring-boot

I have implemented WebMvcConfigurerAdapter as well as added a CorsFilter and configured headers.
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings( CorsRegistry registry )
{
registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowCredentials(false);
}
}
#Slf4j
public class CustomCorsFilter implements javax.servlet.Filter {
#Override
public void init( FilterConfig filterConfig ) throws ServletException
{
}
#Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
throws IOException, ServletException
{
if( req instanceof HttpServletRequest && res instanceof HttpServletResponse )
{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Access-Control-Allow-Origin
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
response.setHeader("Vary", "Origin");
// Access-Control-Max-Age
response.setHeader("Access-Control-Max-Age", "3600");
// Access-Control-Allow-Credentials
response.setHeader("Access-Control-Allow-Credentials", "false");
// Access-Control-Allow-Methods
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
// Access-Control-Allow-Headers
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, " + "X-CSRF-TOKEN");
log.info("********************** Configured ****************************************");
}
chain.doFilter(req, res);
}
#Override
public void destroy()
{
}
}
I have two other filters which does Authentication and Authorisation . But when a frontend app in a local system tries to hit the API, I am getting the following error,
Access to XMLHttpRequest at 'http://3.12.228.75:8090/rest/noauth/otp/sandesha#test.com' from origin 'http://0.0.0.0:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
How to resolve this? I am using spring-boot 1.5.10
and my WebSecurityConfig class is,
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
private CustomLogoutHandler logoutHandler;
#Autowired
private HttpLogoutSuccessHandler logoutSuccessHandler;
#Autowired
private UserModelRepository userModelRepository;
#Autowired
private RefreshTokenService refreshTokenService;
#Autowired
private AuthTokenModelRepository authTokenModelRepository;
#Autowired
private UserActivitiesRepository userActivitiesRepository;
#Autowired
private UserSubscriptionRepository userSubscriptionRepository;
#Autowired
private HandlerExceptionResolver handlerExceptionResolver;
#Autowired
private StringRedisTemplate redisTemplate;
#Autowired
private UserService userService;
#Override
protected void configure( HttpSecurity http ) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers("/rest/noauth/**").permitAll()
.antMatchers("/rest/login").permitAll()
.antMatchers("/rest/logout").permitAll()
.antMatchers("/static/**").permitAll()
.antMatchers("/ws/**").permitAll()
.antMatchers("/rest/razorpay/hook").permitAll()
.antMatchers("/rest/user/cc").permitAll()
.antMatchers("/v2/api-docs/**", "/configuration/ui/**", "/swagger-resources/**",
"/configuration/security/**", "/swagger-ui.html/**", "/webjars/**")
.permitAll()
.antMatchers("/rest/file/invoiceFileDownload", "/rest/file/fileDownload", "/rest/file/fileDownload/**")
.permitAll()
.anyRequest().authenticated()
.and()
.logout().addLogoutHandler(logoutHandler).logoutSuccessHandler(logoutSuccessHandler)
.logoutUrl("/rest/logout")
.and()
.addFilterBefore(
new JWTAuthenticationFilter("/rest/login", tokenService(), refreshTokenService,
authTokenModelRepository, userService, userActivitiesRepository,
handlerExceptionResolver, bCryptPasswordEncoder, redisTemplate),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthorizationFilter(authenticationManager(), authTokenModelRepository,
userSubscriptionRepository, handlerExceptionResolver, redisTemplate),
UsernamePasswordAuthenticationFilter.class);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure( AuthenticationManagerBuilder auth ) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
public TokenService tokenService()
{
return new TokenService(userModelRepository);
}
}

You must keep the configured value same as what you are actually requesting from.
Here you request from 0.0.0.0:3000 and set header as localhost:3000. There is string comparison that happens in org.springframework.web.cors.CorsConfiguration#checkOrigin which will fail in your case.

Related

Spring Authorization Server 0.3.1 CORS issue

i created an authorization server using spring-auth-server 0.3.1, and implemented the Authorization code workflow, my issue is that when my front end -springdoc- reaches the last step i get a 401 and this is what's logged into browser console :
Access to fetch at 'http://authorization-server:8080/oauth2/token' from origin 'http://client:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
i'm using spring boot 2.6.12 and here is my CORS configuration for authorization server (also copy pasted it to the client in case ):
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration {
private final Set<String> allowedOrigins;
#Autowired
public WebSecurityConfiguration(
#Value("${spring.security.cors.allowed-origins:*}") List<String> allowedOrigins) {
this.allowedOrigins = new LinkedHashSet<>(allowedOrigins);
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors().configurationSource(corsConfigurationSource())
.and()
.csrf().disable() // without session cookies we do not need this anymore
.authorizeRequests().anyRequest().permitAll();
return http.build();
}
private CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
boolean useAllowedOriginPatterns = allowedOrigins.isEmpty() || allowedOrigins.contains("*");
if (useAllowedOriginPatterns) {
configuration.setAllowedOriginPatterns(Collections.singletonList(CorsConfiguration.ALL));
} else {
configuration.setAllowedOrigins(new ArrayList<>(allowedOrigins));
}
configuration.setAllowedMethods(Collections.singletonList(CorsConfiguration.ALL));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
and here are my security filter chain for the Auth server :
#Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
return http.formLogin(Customizer.withDefaults()).build();
}
#Bean
#Order(2)
public SecurityFilterChain standardSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
Any idea on what i'm missing ?
If your backend and your app are not running on the same address your browser does normally not allow you to call your backend. This is intended to be a security feature.
To allow your browser to call your api add the Access-Control-**** headers to your backend response (when answering from Spring).
please add the below line in your header
Access-Control-Allow-Origin: *
here is an tutorial also, please visit here on spring.io
i solved it by dropping the corsconfiguration from filter chain bean and creating a filter instead.
'''
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
private final Set<String> allowedOrigins;
#Autowired
public SimpleCORSFilter(#Value("${spring.security.cors.allowed-origins:*}") Set<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
#Override
public void init(FilterConfig fc) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
String origin = request.getHeader("referer");
if(origin != null ){
Optional<String> first = allowedOrigins.stream().filter(origin::startsWith).findFirst();
first.ifPresent(s -> response.setHeader("Access-Control-Allow-Origin", s));
}
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
#Override
public void destroy() {
}
}
'''

Spring boot Oauth2 + Angular CORS problem

I am new in making auth services. When i try get acces token form Postman everything working fine. But when i use Angular i got this error:
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.
My config is:
#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);
}
}
Any searching info not working as global CORS. One thing is working it's
#CrossOrigin(origins = "*", allowedHeaders = "*")
But i can put this on my own controllers, and i dont know how set it for oauth/token endpoint.
this official doc solution doesnt work.
https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html
filter doesnt work too.
After 3 days i found solution. At firs i remove all filters in my auth service. Second i add this props in my gateway service:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders:
- content-type
- x-requested-with
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
- DELETE
- PUT
You just need add global headers for all your services in gateway props, also this can combine with filters in services for more flexible settings.
I hope this can help for some one to save 3 days)
This is a common issue everywhere,
since the origins are different it protects the injection of different origins.
Solution :
1) if you are using for dev then enable CORS on chrome (Extension) (POSTMAN do it by default)
2) In production, the angular application where it is hosted should white list you API URL,
3) third set cors allow origin headers

Spring using MockMvc Test with CORS filter

I have am trying to run a basic MVC test
#Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}
However, this will always result in java.lang.IllegalArgumentException: Header value must not be null
I found out that if I deactivate the CORS filter the test will work without errors.
My SimpleCORSFilter
#Component
public class SimpleCORSFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter() {
log.info("SimpleCORSFilter init");
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
//...
chain.doFilter(req, res);
}
}
Part of my Security Config
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsServiceImp userDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new SimpleCORSFilter(),UsernamePasswordAuthenticationFilter.class);
}
}
Only if I remove the #Component in the SimpleCORSFilter and remove the line .addFilterBefore(new SimpleCORS...) in SecurityConfig the test works.
How can I use mockMVC in my test? Either how do I disable the CORSFilter for the test or how do I make the request in mockMvc correctly so it doesn't throw an error about "header value must not be null".
I have tried setting a random header value in the mockMvc but that didn't change the error.
java.lang.IllegalArgumentException: Header value must not be null.so pass the header value using .header(key,value) like below:
#Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/").header("Origin","*")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}

Spring boot security x-auth-token not found in header

I have a spring boot application having REST services secured with spring security. Redis is used for storing sessions. I have deployed the application in Glassfish 4.1.2. When trying to login using basic auth, x-auth-token is not returned in response header. What could be the issue ?
Below are my configuration classes:
ApplicationSecurityConfig
#Configuration
#EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
private CustomAuthenticationDetailsSource source;
#Autowired
private HttpLogoutSuccessHandler logoutSuccessHandler;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/crr/**").access("hasRole('CRR')")
.anyRequest().authenticated()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.httpBasic().authenticationDetailsSource(source).authenticationEntryPoint(authenticationEntryPoint);
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.csrf().disable();
}
}
CORSCustomFilter
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSCustomFilter implements Filter {
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"X-Requested-With,content-type, Authorization");
chain.doFilter(servletRequest, servletResponse);
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
Note: When I deploy the application in Tomcat,x-auth-token is successfully generated in response header.
To retrieve it from response headers, Add x-auth-token to Access-Control-Allow-Credentials and Access-Control-Expose-Headers
response.setHeader("Access-Control-Expose-Headers", "x-auth-token");
response.setHeader("Access-Control-Allow-Credentials", "x-auth-token");
This worked for me.

Spring Security with JWT - Authenticated at every tenth call

I've some strange problem with my spring security configuration.
I use it with an simple JWT implementation.
I use "GlobalMethodSecurity" and annotated my method with #PreAuthorize
Here a secured sample method:
#PreAuthorize("hasAnyRole('ROLE_USER')")
#RequestMapping(value = "/user/ok", method = RequestMethod.GET)
public ResponseEntity ok( ) {
return new ResponseEntity( "{text:\"ok\"}", HttpStatus.OK );
}
if I call this without a security token I get an "UNAUTHORIZED" nine times (as expected). At the exact tenth time I will get the "ok" json from the method. (The 11th to 19th call is "UNAUTHORIZED" and at the 20th I will became the "ok" message again and so on)
Here are my SecurityConfiguration:
#Configuration
#EnableGlobalMethodSecurity( prePostEnabled = true )
#EnableWebSecurity
#EnableTransactionManagement
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
public void configureAuthentication( AuthenticationManagerBuilder authenticationManagerBuilder ) throws Exception {
authenticationManagerBuilder
.userDetailsService( userDetailsService )
.passwordEncoder( new BCryptPasswordEncoder() );
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean(name = "authenticationTokenFilter")
public AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();
authenticationTokenFilter.setAuthenticationManager( super.authenticationManagerBean() );
return authenticationTokenFilter;
}
#Override
protected void configure( HttpSecurity httpSecurity ) throws Exception {
// Custom JWT based authentication
httpSecurity
.addFilterBefore( authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class )
.exceptionHandling()
.authenticationEntryPoint( authenticationEntryPoint )
.and()
.sessionManagement()
.sessionCreationPolicy( SessionCreationPolicy.STATELESS )
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
and my Filter Class:
public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter {
#Autowired
private TokenUtils tokenUtils;
#Autowired
private UserDetailsService userDetailsService;
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
tokenUtils = WebApplicationContextUtils
.getRequiredWebApplicationContext(this.getServletContext())
.getBean(TokenUtils.class);
userDetailsService = WebApplicationContextUtils
.getRequiredWebApplicationContext(this.getServletContext())
.getBean(UserDetailsService.class);
HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
resp.setHeader("Access-Control-Max-Age", "3600");
resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Authorization, Accept, " + AppConstant.tokenHeader);
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authToken = httpRequest.getHeader(AppConstant.tokenHeader);
String username = this.tokenUtils.getUsernameFromToken(authToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (this.tokenUtils.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
}
Edit
I found out that this only happen if a user was logged in once.
So in the example ok() method I had the previously logged in user in the security context although I haven't sent any token in the header.
But as I said - not in every request - There must be a kind of Thread or session thing I miss.
For a advice I would be very grateful
Thanks!
Take a look at this example: https://github.com/bfwg/springboot-jwt-starter
Live Demo: http://fanjin.computer:8080
SecurityConfiguration:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
#Bean
public JwtLogoutHandler jwtLogoutHandler() {
return new JwtLogoutHandler();
}
#Autowired
CustomUserDetailsService jwtUserDetailsService;
#Autowired
RestAuthenticationEntryPoint restAuthenticationEntryPoint;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(jwtUserDetailsService);
}
#Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS ).and()
.exceptionHandling().authenticationEntryPoint( restAuthenticationEntryPoint ).and()
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/", "/index.html", "/login.html", "/home.html").permitAll()
.anyRequest()
.authenticated().and()
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler).and()
.logout()
.addLogoutHandler(jwtLogoutHandler())
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))) ;
}
}
Filter Class:
#Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String authToken = getToken( request );
// get username from token
String username = tokenHelper.getUsernameFromToken( authToken );
if ( username != null ) {
// get user
UserDetails userDetails = userDetailsService.loadUserByUsername( username );
// create authentication
TokenBasedAuthentication authentication = new TokenBasedAuthentication( userDetails );
authentication.setToken( authToken );
authentication.setAuthenticated( true );
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
Hope this helps.

Resources