Since you intend to check for a particular header/cookie/request-attribute for every controller methods, you should opt for a Filter as this would be a standard and you can have a guarantee for it be executed for each and every method and that too only once by extending from OncePerRequestFilter
Having said that, there would be 2 way you can achieve this:
By extending AbstractAuthenticationProcessingFilter
or OncePerRequestFilter
For this you may refer the spring-security jwt token validation flow which all would advocate for:
- Add method security at your desired controller method as
@PreAuthorize("hasAuthority('USER_ROLE')")
- Intercept the request before
UsernamePasswordAuthenticationFilter
, extract the Authentication
header or cookies
from the request and validate the token value for claims.
public class CustomHeaderAuthFilter extends AbstractAuthenticationProcessingFilter{
@Override
public Authentication attemptAuthentication(
HttpServletRequest request, HttpServletResponse response){
// Get all the headers from request, throw exception if your header not found
Enumeration<String> reqHeaders = request.getHeaderNames();
Assert.notNull(reqHeaders, "No headers found. Abort operation!");
Collections.list(reqHeaders)
.stream()
.filter(header_ -> header_.equals("TARGET_HEADER_NAME"))
.findAny().ifPresent(header_ -> {
// header found, would go for success-andler
});
// Here it means request has no target header
SecurityContextHolder.clearContext();
failureHandler.onAuthenticationFailure(request, response, new CustomException(""));
}
}
Going by this way, you need to register your filter with WebSecurityConfigurerAdapter
and you may also provide your AuthenticationProvider
if you extend from AbstractAuthenticationProcessingFilter
.
- By accessing
HTTP Headers
in rest controllers using @RequestHeader
as dm-tr has mentioned.