Spring JWT декодер OpenID токен - PullRequest
0 голосов
/ 04 февраля 2019

Внешний поставщик OAuth2 не имеет общедоступного JwkUri, поэтому я попытался переопределить поведение по умолчанию, используя следующий фрагмент кода:

@EnableWebSecurity
public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("**/oauth2/code/esia**", "**/code/esia**", "**esia**").permitAll()
            .antMatchers("/user").fullyAuthenticated()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
            .cors().disable()
            .oauth2Client()
            .clientRegistrationRepository(this.clientRegistrationRepository)
            .authorizationCodeGrant()
            .authorizationRequestResolver(new CustomAuthorizationRequestResolver(
                    this.clientRegistrationRepository, esiaConfig, signatureUtil, timeUtil))
            .accessTokenResponseClient(customAccessTokenResponseClient())
            .and().and().oauth2Login().tokenEndpoint().accessTokenResponseClient(customAccessTokenResponseClient())
            .and().and().oauth2ResourceServer().jwt();
}
@Bean
JwtDecoder jwtDecoder() {
 return  new CustomJwtDecoder();
}
}

class CustomJwtDecoder implements JwtDecoder {
@Override
public Jwt decode(String token) throws JwtException {
    System.out.println(token);
    return null;
}
}

Однако Spring Security почему-то все еще использует реализацию по умолчанию, и я получаю следующую ошибку...

[missing_signature_verifier] Failed to find a Signature Verifier for Client Registration: 'esia'. Check to ensure you have configured the JwkSet URI.

Кроме того, я попытался установить пользовательский AuthenticationProvider, но Spring игнорирует его.

Я думаю, подвох в том, что метод пружины OAuth2LoginConfigurer init (B http) вызывает новый OidcAuthorizationCodeAuthenticationProvider (accessTokenResponseClient, oidcUserService)

1 Ответ

0 голосов
/ 04 февраля 2019

Для 5.1.3.RELEASE похоже, что вы не можете легко обойти эту проблему.

Это связано с OidcAuthorizationCodeAuthenticationProvider.getJwtDecoder

Это происходит в строка 156 , которая является вызовом частного метода

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        ...
        OidcIdToken idToken = createOidcToken(clientRegistration, accessTokenResponse);
        ...
    }

Опция one Я вижу, что вы делаете копию этого кода и изменяете его самостоятельно.Расширение самого класса не имеет смысла, потому что вся логика в значительной степени происходит в методе authenticate.Таким образом, вы все еще отвергаете это.затем вы добавляете своего провайдера, используя метод http.authenticationProvider

Другой вариант - переопределить метод SecurityConfigurerAdapter.postProcess класса OAuth2LoginConfigurer и сделать там что-нибудь умное,Как заполнение карты JWT декодера через отражение.

Ни одно из общепризнанных предпочтительных решений.Я считаю, что именно поэтому рефакторинг произошел в версии 5.2.

Учитывая последнюю версию 5.2.x, вы почти на месте, но вы должны переопределить правильный бин

    @Bean
    public JwtDecoderFactory<ClientRegistration> jwtDecoderFactory() {
        final JwtDecoder decoder = jwtDecoder();
        return context -> decoder;

    }

, и если вы не хотите использовать лямбды

    @Bean
    public JwtDecoderFactory<ClientRegistration> jwtDecoderFactory() {
        final JwtDecoder decoder = jwtDecoder();
        return new JwtDecoderFactory<ClientRegistration>() {
            @Override
            public JwtDecoder createDecoder(ClientRegistration context) {
                return decoder;
            }
        };

    }

Как я это выяснил, я взглянул на класс OAuth2LoginConfigurer.java , который делает

    JwtDecoderFactory<ClientRegistration> jwtDecoderFactory = getJwtDecoderFactoryBean();

, и закрытый метод, который выбирает компонент, выглядит так это

    private JwtDecoderFactory<ClientRegistration> getJwtDecoderFactoryBean() {
        ResolvableType type = ResolvableType.forClassWithGenerics(JwtDecoderFactory.class, ClientRegistration.class);
        String[] names = this.getBuilder().getSharedObject(ApplicationContext.class).getBeanNamesForType(type);
        if (names.length > 1) {
            throw new NoUniqueBeanDefinitionException(type, names);
        }
        if (names.length == 1) {
            return (JwtDecoderFactory<ClientRegistration>) this.getBuilder().getSharedObject(ApplicationContext.class).getBean(names[0]);
        }
        return null;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...