415. Custom Authentication Filter - dkkahm/study-springfamework5 GitHub Wiki
Filter with Api-Key and Api-Secret
@Slf4j
public class RestHeaderAuthFilter extends AbstractAuthenticationProcessingFilter {
public RestHeaderAuthFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
super(requiresAuthenticationRequestMatcher);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Request is to process authentication");
}
try {
Authentication authResult = this.attemptAuthentication(request, response);
if(authResult != null) {
successfulAuthentication(request, response, chain, authResult);
} else {
chain.doFilter(request, response);
}
} catch (AuthenticationException e) {
unsuccessfulAuthentication(request, response, e);
}
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String userName = getUsername(request);
String password = getPassword(request);
if(userName == null) {
userName = "";
}
if(password == null) {
password = "";
}
log.debug("Authencation User: " + userName);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userName, password);
if(!StringUtils.isEmpty(userName)) {
return this.getAuthenticationManager().authenticate(token);
} else {
return null;
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.clearContext();
if (log.isDebugEnabled()) {
log.debug("Authentication request failed: " + failed.toString(), failed);
log.debug("Updated SecurityContextHolder to contain null Authentication");
}
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
private String getUsername(HttpServletRequest request) {
return request.getHeader("Api-Key");
}
private String getPassword(HttpServletRequest request) {
return request.getHeader("Api-Secret");
}
}
Add RestHeaderAuthFilter berfore UsernamePasswordAuthenticationFilter
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public RestHeaderAuthFilter restHeaderAuthFilter(AuthenticationManager authenticationManager) {
RestHeaderAuthFilter filter = new RestHeaderAuthFilter(new AntPathRequestMatcher("/api/**"));
filter.setAuthenticationManager(authenticationManager);
return filter;
}
....
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(restHeaderAuthFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
http
.authorizeRequests()
....
}
Test
@WebMvcTest
public class BeerRestControllerIT extends BaseIT {
@Test
void deleteBeer() throws Exception {
mockMvc.perform(delete("/api/v1/beer/493410b3-dd0b-4b78-97bf-289f50f6e74f")
.header("Api-Key", "spring")
.header("Api-Secret", "guru")
)
.andExpect(status().isOk());
}
@Test
void deleteBeerHttpBasic() throws Exception {
mockMvc.perform(delete("/api/v1/beer/493410b3-dd0b-4b78-97bf-289f50f6e74f")
.with(httpBasic("spring", "guru"))
)
.andExpect(status().is2xxSuccessful());
}
@Test
void deleteBeerNoAuth() throws Exception {
mockMvc.perform(delete("/api/v1/beer/493410b3-dd0b-4b78-97bf-289f50f6e74f"))
.andExpect(status().isUnauthorized());
}
@Test
void deleteBeerBadCreds() throws Exception {
mockMvc.perform(delete("/api/v1/beer/493410b3-dd0b-4b78-97bf-289f50f6e74f")
.header("Api-Key", "spring")
.header("Api-Secret", "guruxxx")
)
.andExpect(status().isUnauthorized());
}
....