Мне нужно реализовать авторизацию с определенным заголовком (скажем, "sessionId") и защитить все URI, кроме одного.
Я расширил OncePerRequestFilter
и реализовал пользовательский AuthenticationProvider
, чтобы проверить, является ли sessionId действительным (кака также пользовательский класс токенов и т. д.).
Как это работает сейчас: для любого uri он сразу же переходит к методу AuthSessionAuthenticationProvider
authenticate
сразу после применения AuthSessionFilter
и возвращает403, если заголовок sessionId
не указан.Но я хочу, чтобы некоторые URI разрешили доступ без этого заголовка.
Все вместе:
config:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(permittedUris).permitAll()
.anyRequest().authenticated()
.and().exceptionHandling().accessDeniedHandler(new AuthSessionAccessDeniedHandler())
.and().addFilterBefore(new AuthSessionFilter(), BasicAuthenticationFilter.class);
}
Фильтр:
public class AuthSessionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
Authentication auth = new AuthSessionToken(request.getHeader("sessionId"));
SecurityContextHolder.getContext().setAuthentication(auth);
filterChain.doFilter(request, response);
}
}
Провайдер:
public class AuthSessionAuthenticationProvider implements AuthenticationProvider {
//...
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
AuthSessionToken token = (AuthSessionToken) authentication;
if (token.getSessionId() == null) {
throw new AccessDeniedException("Missing header sessionId");
}
AuthSessionAuthorities user = authSessionService.getUserAuthoritiesToken(token.getSessionId());
if (user == null) {
throw new AccessDeniedException("Session ID invalid: " + token.getSessionId());
}
token.setAuthenticatedUser(user);
return token;
}
//...
}