I have a Spring Boot application that is only exposing a REST API. I need to secure it and I'm using a token-based approach ― specifically JWT.
So far, this is what I have implemented:
//
// The Spring Security configuration class
@EnableGlobalAuthentication
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/login", "/api/logout").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtFilter(), BasicAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
//
// The JWT filter class to check for the token in the HTTP request (headers)
public final class JwtFilter extends GenericFilterBean {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws
IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest)request;
final String header = req.getHeader("Authorization");
logger.debug("{} {}", req.getMethod(), req.getRequestURI());
if ((null == header) || !header.startsWith("Bearer ")) {
logger.debug("Missing or invalid Authorization header");
}
try {
// Check the token here; the implementation is not relevant here
/*SecurityContextHolder.getContext()
.setAuthentication(manager.authenticate(new JwtToken(JWTParser.parse(header.substring(7)))));*/
chain.doFilter(request, response);
} catch (final AuthenticationException e) {
SecurityContextHolder.clearContext();
// Do some other stuff here
} catch (final ParseException e) { /* ... */ }
}
}
The issue is that the filter executes correctly for every single URI, but I want to be able to exclude some endpoints from the same set. My API is placed in this context /api/*
and I want to exclude, for instance, /api/login
and /api/logout
.
NOTE: My Spring Boot application.yml
file doesn't have settings to enable/modify any security-related features.
Filters will be executed for all the endpoints that are configured through HttpSecurity. If you do not want filters to be applied for certain endpoints, include them in a method that configures WebSecurity. For example,
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/api/login", "/api/logout");
}
Please read this post for more details.