I created a simple restful application using springboot. It only has two api, login and signup. After user signs in, it returns a jwt. Here is my configuration
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/users/checkUsernameAvailability", "/api/users/checkEmailAvailability").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
The problem is, I noticed an authenticated user can call /login api again, with a new jwt token returned.
Is there a way to configure some api for unauthenticated user only? Like .antMatchers(HttpMethod.POST, "/api/auth/**").unauthenticatedOnly()
If no configuraion, the walkaround on top of my mind is adding a is_authenticated
column to user table, and only authenticate user whose is_authentiacted = false
. Is it a good way?
If you want to validate occurrence of the jwt token on the server-side, I think the token has to be saved in storage like Redis, etc, and check it via Filter(set it in Spring Security).
A possible simple solution is using the Spring session instead if you want to control it by Spring security itself(without extra work).
Spring Session is like HttpSession but backed by Redis, Mongo, etc, thus you can use the session concurrency strategy provided in Spring Security to ensure only one user authentication is valid. You have to switch to Stateful in your backend.
Personally, I used Spring session in several projects(secures RESTful API), I think it is good. Here is an example of using Spring session (Reactive stack)(but I have not configured the session control rule). Here is a microservice example(Servlet stack).