Пружинный адаптер Keycloak - проверьте, что authToken активен с каждым запросом http - PullRequest
0 голосов
/ 26 апреля 2018

Проблема, которую я хочу решить: Для каждого звонка в службу я хочу проверить, что токен активен - если он не активен, я хочу перенаправить пользователя на страницу входа.

Текущая настройка: Грааль 3.2.9, Keycloak 3.4.3

Идеи до сих пор: Эта статья выглядела многообещающе: https://www.linkedin.com/pulse/json-web-token-jwt-spring-security-real-world-example-boris-trivic

В настройках безопасности я добавил токен-фильтр

@Bean
public TokenAuthenticationFilter authenticationTokenFilter() throws Exception {
    return new TokenAuthenticationFilter();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure http
    http
        .addFilterBefore(authenticationTokenFilter(), BasicAuthenticationFilter.class)
        .logout()
            .logoutSuccessUrl("/sso/login") // Override Keycloak's default '/'
        .and()
        .authorizeRequests()
            .antMatchers("/assets/*").permitAll()
            .anyRequest().hasAnyAuthority("ROLE_ADMIN") 
            .and()
        .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());      
}

Мой TokenAuthenticationFilter просто распечатывает заголовки запроса в данный момент:

открытый класс TokenAuthenticationFilter расширяет OncePerRequestFilter {

private String getToken( HttpServletRequest request ) {

    Enumeration headerEnumeration = request.getHeaderNames();
    while (headerEnumeration.hasMoreElements()) {
        println "${ headerEnumeration.nextElement()}"
    }

    return null;
}


@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {        
    String authToken = getToken( request );
}

}

Что возвращает:

  • хост
  • пользовательский агент
  • принимаем
  • принимает язык
  • Accept-Encoding
  • печенье
  • подключение
  • модернизируют-небезопасные-запросов
  • кэш-контроль

Код / логика, которую я хочу реализовать в фильтре, выглядит примерно так:

    KeycloakAuthenticationToken token = SecurityContextHolder.context?.authentication 

    RefreshableKeycloakSecurityContext context = token.getCredentials()

    if(!context.isActive()){
        // send the user to the login page 
    }

Однако я потерян, как туда добраться. Любая помощь с благодарностью

1 Ответ

0 голосов
/ 03 мая 2018

Насколько я понимаю, ваш вопрос о том, "как проверить токен активен?" а не «как перенаправить пользователя на страницу входа?».

Как я вижу, вы добавили теги "spring-boot" и "keycloak", возможно, вы могли бы использовать "Keycloak Spring Boot Adapter". Предполагая, что вы используете версию 3.4 Keycloak (v4.0 все еще в бета-версии), вы можете найти некоторую документацию здесь .

Если вы не можете (или не хотите) использовать Spring Boot Adapter, вот часть KeycloakSecurityContextRequestFilter исходного кода , которая может быть интересна для вашего случая:

KeycloakSecurityContext keycloakSecurityContext = getKeycloakPrincipal();
if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) {
    RefreshableKeycloakSecurityContext refreshableSecurityContext = (RefreshableKeycloakSecurityContext) keycloakSecurityContext;
    if (refreshableSecurityContext.isActive()) {
        ...
    } else {
        ...
    }
}

и вот (Java) исходный код метода getKeycloakPrincipal:

private KeycloakSecurityContext getKeycloakPrincipal() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    if (authentication != null) {
        Object principal = authentication.getPrincipal();

        if (principal instanceof KeycloakPrincipal) {
            return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext();
        }
    }

    return null;
}

И если вы хотите понять, как устанавливается Аутентификация в SecurityContextHolder, прочитайте этот фрагмент (Java) кода из KeycloakAuthenticationProcessingFilter:

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    if (authResult instanceof KeycloakAuthenticationToken && ((KeycloakAuthenticationToken) authResult).isInteractive()) {
        super.successfulAuthentication(request, response, chain, authResult);
        return;
    }

    ...

    SecurityContextHolder.getContext().setAuthentication(authResult);

    ...

    try {
        chain.doFilter(request, response);
    } finally {
        SecurityContextHolder.clearContext();
    }
}

В качестве альтернативы вы также можете проверить этот github-репозиторий dynamicind: https://github.com/dynamind/grails3-spring-security-keycloak-minimal

Надеясь, что может помочь.
С уважением,
Jocker.

...