Spring Filter для добавления ролей в запрос от токена

Я ищу правильный способ добавить аутентификацию на основе ролей, когда я извлекаю роли из JWT.

В идеале я хотел бы извлечь роли из JWT после аутентификации. Это будет работать путем проверки веб-токена на наличие некоторых полей, связанных с ролями, которые мы получаем из нашей системы аутентификации, keycloak.

Мой вопрос: возможно ли добавить роли к запросу, а затем использовать конфигурацию http, чтобы потребовать одну из этих извлеченных ролей?

Ниже приведен соответствующий код, который поможет объяснить, что я делаю.

В моем WebSecurityConfigurer я делаю токен доступа доступным для каждого запроса.

@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken accessToken() {
    try {
        HttpServletRequest request =
            ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();
        return ((KeycloakSecurityContext) ((KeycloakAuthenticationToken) request
            .getUserPrincipal())
            .getCredentials()).getToken();
    } catch (Exception exc) {
        return null;
    }
}

Затем я переопределяю некоторые настройки http в методе configure.

http
// Disable session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// Allow calls to OPTIONS
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.and()
// Authenticate every other call
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().disable();

В идеале я хотел бы добиться чего-то вроде:

http.antMatchers("/foo").hasRole("jwt_extracted_role")

В настоящее время я создаю пользовательские фильтры, которые извлекают роли из токена, а затем проверяют правильные роли, но это, возможно, более громоздко, чем должно быть.

Любые указатели на то, какие методы каких классов конфигурации я должен переопределить, чтобы извлечь роли из запроса и добавить их в запрос?


person Cramja    schedule 10.06.2017    source источник


Ответы (1)


В итоге я решил эту проблему, переопределив KeycloakAuthenticationProvider и предоставив свой класс переопределения в виде bean-компонента в WebSecurityConfig. Мой класс ниже:

public class ResourceAwareAuthenticationProvider extends KeycloakAuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
          ... here I add granted authorities from the token's credentials ...
    }
}

Затем в моем class WebSecurityConfigurer extends KeycloakWebSecurityConfigurerAdapter я переопределяю AuthenticationProvider:

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return new ProviderManager(Lists.newArrayList(new ResourceAwareAuthenticationProvider()));
}

Это позволяет мне выполнять такие настройки, как:

http.authorizeRequests()
    .antMatchers("/**").hasAuthority("my-resource-authority")
person Cramja    schedule 10.06.2017
comment
Из любопытства, что вы пропустили в Keycloak Spring Security Adapter? Из коробки уже можно делать .antMatchers("/products*").hasRole("user") - person Sébastien Blanc; 12.06.2017
comment
Роли, которые достались Спрингу, были неполными. В моем классе ResourceAwareAuthenticationProvider я добавил больше ролей, чем предусмотрено фреймворком. - person Cramja; 12.06.2017