Настройка TokenEndpoint в Sprin OAuth2 - PullRequest
0 голосов
/ 17 марта 2019

Я хотел бы предоставить пользовательскую реализацию класса TokenEndpoint в среде Spring.

Я скопировал класс Spring TokenEndpoint и внес изменения в необходимые места.Но когда запускаются приложения, я всегда получаю сообщение об ошибке

Caused by: java.lang.IllegalStateException: TokenGranter must be provided

Я предоставил реализацию для TokenGranter в своем OAuthConfig, но Spring не принимает это

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.pathMapping("/oauth/token", "/oauth/token/v1")
             .tokenServices(tokenServices())
             .tokenGranter(tokenGranter())
            .authenticationManager(authenticationManager).tokenStore(tokenStore())
            .tokenEnhancer(tokenEnhancer()).accessTokenConverter(accessTokenConverter());
}

@Bean
@Primary
public TokenGranter tokenGranter() {
    TokenGranter tokenGranter = null;
    if (tokenGranter == null) {
        tokenGranter = new TokenGranter() {
            private CompositeTokenGranter delegate;

            @Override
            public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
                if (delegate == null) {
                    delegate = new CompositeTokenGranter(getDefaultTokenGranters());
                }
                return delegate.grant(grantType, tokenRequest);
            }
        };
    }
    return tokenGranter;
}

Iдаже пытался обеспечить эту реализацию в моем собственном классе TokenEndpoint.На данный момент реализация пользовательского TokenEndpoint точно такая же, как и в TokenEndpoint Spring.

OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);

private List<TokenGranter> getDefaultTokenGranters() {
    ClientDetailsService clientDetails = clientDetailsService();
    AuthorizationServerTokenServices tokenServices = tokenServices();
    AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
    OAuth2RequestFactory requestFactory = requestFactory();

    List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();
    tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails,
            requestFactory));
    tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
    ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
    tokenGranters.add(implicit);
    tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
    if (authenticationManager != null) {
        tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetails,
                requestFactory));
    }
    return tokenGranters;
}

private DefaultTokenServices createDefaultTokenServices() {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setTokenStore(tokenStore());
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setReuseRefreshToken(true);
    tokenServices.setClientDetailsService(clientDetailsService());
    tokenServices.setTokenEnhancer(tokenEnhancer());
    addUserDetailsService(tokenServices, new CustomDetailsService());
    return tokenServices;
}

private ClientDetailsService clientDetailsService() {
    ClientDetailsService clientDetailsService = null;
    clientDetailsService = new InMemoryClientDetailsService();
    addUserDetailsService(createDefaultTokenServices(), new CustomDetailsService());
    return clientDetailsService;
}

private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetailsService userDetailsService) {
    if (userDetailsService != null) {
        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken>(
                userDetailsService));
        tokenServices
                .setAuthenticationManager(new ProviderManager(Arrays.<AuthenticationProvider> asList(provider)));
    }
}

private AuthorizationCodeServices authorizationCodeServices() {
    AuthorizationCodeServices authorizationCodeServices = new InMemoryAuthorizationCodeServices();
    return authorizationCodeServices;
}

private OAuth2RequestFactory requestFactory() {
    OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetailsService());
    return requestFactory;
}

@Bean
public JwtTokenStore tokenStore() {
    JwtTokenStore jwtTokenStore = new JwtTokenStore(accessTokenConverter());
    return jwtTokenStore;
}

@Bean
@Primary
public AuthorizationServerTokenServices tokenServices() {
    final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setAccessTokenValiditySeconds(-1);
    defaultTokenServices.setTokenStore(tokenStore());
    return defaultTokenServices;
}

@Bean
public TokenEnhancer tokenEnhancer() {
    return new CustomTokenEnhancer();
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
    final JwtAccessTokenConverter converter = new JwtAccessTokenConverter() {
        @Override
        public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            return accessToken;
        }
    };
    return converter;
}

Я пытался понять это пару дней, но безуспешно.Поэтому любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 17 марта 2019

Зачем вам нужно снова реализовать TokenEndpoint?

Вы можете создать бин TokenGranter и внедрить его в конечные точки по умолчанию.

Где метод getDefaultTokenGranters()?

Похоже, у вас есть неполная копия исходного кода AuthorizationServerEndpointsConfigurer.

Обновление :

Если вы хотите настроить ответ токена, используйте TokenEnhancer.

например:

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        OurUser user = (OurUser) authentication.getPrincipal();
        final Map<String, Object> additionalInfo = new HashMap<>();
        Map<String, Object> userDetails = new HashMap<>();
        userDetails.put(USERID, user.getId().getId());
        userDetails.put(NAME, user.getName());
        userDetails.put(MOBILE, user.getMobile());
        userDetails.put(EMAIL, user.getEmail());
        additionalInfo.put(USERINFO, userDetails);
        // Set additional information in token for retriving in #org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }

}

в конфигурации OAuth2:

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        super.configure(endpoints);
        endpoints.
                .....
                // Include additional information to OAuth2 Access token with custom token enhancer
                .tokenEnhancer(tokenEnhancer());
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

https://stackoverflow.com/a/28512607/4377110

...