Мне нужно разработать систему безопасности службы отдыха с помощью Spring Security (версия 4.0.3. RELEASE).
Сценарий:
- аутентификация клиента, выполняющего запрос (идентификатор клиента + клиент
токен в пользовательском заголовке)
- в случае ошибок необходимо отправить ответ JSON
Я создал пользовательский OncePerRequestFilter
, который выполняет чтение пользовательского токена так же, как если бы это был basic auth
токен.
public class MyClientAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// omitting implementation
}
}
Затем я создал собственный AuthenticationEntryPoint
, который выполняет запись ошибки JSON в ответ.
public class MyAuthorizationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
// omitting implementation
}
}
Затем я подключил их вот так:
@Configuration
@EnableWebSecurity
public class WebApiSecurityConfig extends WebSecurityConfigurerAdapter implements TogatherWebApiCostants {
private static final Logger log = LoggerFactory.getLogger(WebApiSecurityConfig.class);
private @Inject Environment environment;
@Bean
protected AuthenticationEntryPoint clientAuthorizationEntryPoint() {
return new MyAuthorizationEntryPoint();
}
@Bean
protected Filter clientAuthorizationFilter() {
return new MyAuthorizationFilter();
}
/**
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
log.debug("Configuring HTTP security");
// @formatter:on
http
.addFilterBefore(clientAuthorizationFilter(), BasicAuthenticationFilter.class)
.exceptionHandling().authenticationEntryPoint(clientAuthorizationEntryPoint());
// @formatter:off
}
}
Все работает, кроме пользовательской точки входа. Это не срабатывает, и кажется, что Spring по-прежнему использует по умолчанию. Я также пытался переключиться на конфигурацию XML (я гораздо больше привык к этому, чем с подходом JavaConfig), но поведение остается тем же.
Может кто-нибудь сказать мне, что я делаю не так?
ПРИМЕЧАНИЕ. Я попытался отладить Spring Security, добавив регистратор org.springframework.security
с уровнем, установленным на debug
, но я не вижу ни одного сообщения журнала
~~~~~~~~~~~~~~
EDIT: добавление текущего обходного пути
На данный момент, не имея элегантного решения, я просто явно назвал точку входа из фильтра.
public class MyClientAuthorizationFilter extends OncePerRequestFilter {
...
private @Inject AuthenticationEntryPoint entryPoint;
...
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
// omitting logic
} catch(AuthenticationException ae) {
SecurityContextHolder.clearContext();
entryPoint.commence(request, response, ae);
return;
}
}
}