Reputation: 22766
I have a spring-boot REST API application. The REST endpoints are protected by spring-security.
This is the configuration of spring-security:
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.exceptionHandling().authenticationEntryPoint(new CustomForbiddenErrorHandler())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/api/**").authenticated() // HTTP 403 if the request is not authenticated
.antMatchers("/**").permitAll();
}
It works fine. If I make a rest call without having an auth-token on the HTTP header I get back the proper HTTP error code.
Can I force spring somehow to add a self auth-token if it is not presented in order so I can make REST calls without having my own access management system? It will be installed later.
I am not asking how to write JUnit test. What I am asking is how to generate a mock auth-token on the fly and add it to the request if it does not exist.
Upvotes: 2
Views: 2197
Reputation: 2644
You can override the existing authentication filter, or create a new custom filter, to check if a request contains a bearer token or not. Based on the result, you can either process the request as it is, or augment the request with your custom authentication object.
Check out OAuth2AuthenticationProcessingFilter, this extracts an OAuth2 token from the incoming request and uses it to populate the Spring Security context. You can either override its behavior or create a new filter that populates the security context with your mock authentication object.
Here is a sample code to get you started:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
boolean debug = logger.isDebugEnabled();
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
try {
Authentication authentication = this.tokenExtractor.extract(request);
if (Objects.isNull(authentication)) {
final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken("username", "password");
authenticationToken.setDetails(Collections.singletonMap("user_uuid", userUuid.toString()));
final OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(null, authenticationToken);
// You can either ask your authenticatoin manager to authenticate these credentials or directly publish auth success event with your mock auth object.
this.eventPublisher.publishAuthenticationSuccess(oAuth2Authentication);
SecurityContextHolder.getContext().setAuthentication(oAuth2Authentication);
} else {
request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal());
if (authentication instanceof AbstractAuthenticationToken) {
AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken)authentication;
needsDetails.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
Authentication authResult = this.authenticationManager.authenticate(authentication);
if (debug) {
logger.debug("Authentication success: " + authResult);
}
this.eventPublisher.publishAuthenticationSuccess(authResult);
SecurityContextHolder.getContext().setAuthentication(authResult);
}
Upvotes: 1