Oauth2 Server возвращает «токен доступа» вместо Jwt токена - PullRequest
0 голосов
/ 10 февраля 2020

Следуя инструкции, которую можно найти здесь , чтобы заменить существующую конфигурацию oauth, которая возвращает «токен доступа» для токена jwt. Когда я запускаю приложение и запрашиваю сервер для аутентификации, кажется, что он возвращает «access_token» вместо токена JWT. В учебном пособии используется пружинная загрузка, а наше приложение представляет собой обычную пружину без загрузки mvc, поэтому не уверены, есть ли какие-либо дополнительные шаги?

Ответ сервера: {"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ3aWxsbGFkaXNsYXciLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjQ2OGI3MzFmLTUxMzgtNDZhYi04MTU3LTU1MmZlMjM1MzY2ZSIsImNsaWVudF9pZCI6ImNsaWVudGFwcCIsInNjb3BlIjpbInJlYWRfd3JpdGUiXSwib3JnYW5pemF0aW9uIjoid2lsbGxhZGlzbGF3QmdNSiJ9.fUhFeUDuhm8f2V7CuURsZWKoAKjNZixk5rUa0Jyzov8","refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbsUiOiJ3aWxsbGFkaXNsYXciLCJzY29wZSI6WyJyZWFkX3dyaXRlIl0sIm9yZ2FuaXphdGlvbiI6IndpbGxsYWRpc2xhd0JnTUoiLCJhdGkiOiI0NjhiNzMxZi01MTM4LTQ2YWItODE1Ny01NTJmZTIzNTM2NmUiLCJleHAiOjE1ODM4NDA5NTgsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiOGIxNGE3NjMtZmMwMy00MDQ4LWJkNGQtYjZiMTUyOGU2NTE4IiwiY2xpZW50X2lkIjoiY2xpZW50YXBwIn0.UhkxVsgM4CnZeRRKGyyCbiyqb2M0BmL56sHbsxt5Opk","idToken":null,"tokenEndpoint":"http://localhost:8080/oauth/token","scopes":["read_write"],"expiration":null}

// OAuth-сервер

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    final String clientId;
    final String clientSecret;
    final String redirectUri;
    final String grantType;
    final String scope;
  ....

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    DataSource dataSource;

    @Autowired
    RepositoryUserDetailsService userDetailsService;

    @Autowired
    private CustomAccessTokenConverter customAccessTokenConverter;


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(
                Arrays.asList(tokenEnhancer(), accessTokenConverter()));

        endpoints.tokenStore(tokenStore())
                .tokenEnhancer(tokenEnhancerChain)
                .authenticationManager(authenticationManager);
    }

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


    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(passwordEncoder);
    }

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

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }

    @Bean
    @Primary
    public ResourceServerTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }


    @Bean
    protected AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }



    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {
        clients.
                jdbc(dataSource)
                .withClient(clientId)
                .secret(passwordEncoder.encode(clientSecret))
                .autoApprove(true)
                .redirectUris(redirectUri)
                .authorizedGrantTypes("password", "refresh_token")
                .accessTokenValiditySeconds(0)
                .scopes(scope);
    }
}

// Ресурсный сервер

@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
    @Autowired
    private CustomAccessTokenConverter customAccessTokenConverter;
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/register/**").permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin().loginPage("/signin/**")
                .and()
                .requestMatchers()
                .antMatchers("/api/**");

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices(tokenServices());
    }

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

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(customAccessTokenConverter);
        converter.setSigningKey("123");
        return converter;
    }

    @Bean
    @Primary
    public ResourceServerTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

}

// CustomTokenEnhancer Class

public class CustomTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(
            OAuth2AccessToken accessToken,
            OAuth2Authentication authentication) {
        Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put(
                "organization", authentication.getName() + randomAlphabetic(4));
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
                additionalInfo);
        return accessToken;
    }
}

// CustomAccessTokenConverter Class

@Component
public class CustomAccessTokenConverter extends DefaultAccessTokenConverter {

    @Override
    public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
        OAuth2Authentication authentication =
                super.extractAuthentication(claims);
        authentication.setDetails(claims);
        return authentication;
    }
}

1 Ответ

0 голосов
/ 10 февраля 2020

Ваша конфигурация Spring Security OAuth2 работает так, как она должна быть, и уже возвращает токен JWT.

Ниже приводится полезная нагрузка, которую она возвращает

eyJ1c2VyX25hbWUiOiJ3aWxsbGFkaXNsYXciLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjQ2OGI3MzFmLTUxMzgtNDZhYi04MTU3LTU1MmZlMjM1MzY2ZSIsImNsaWVudF9pZCI6ImNsaWVudGFwcCIsInNjb3BlIjpbInJlYWRfd3JpdGUiXSwib3JnYW5pemF0aW9uIjoid2lsbGxhZGlzbGF3QmdNSiJ9

Так выглядит после декодирования это с base64

{"user_name":"willladislaw","authorities":["ROLE_ADMIN"],"jti":"468b731f-5138-46ab-8157-552fe235366e","client_id":"clientapp","scope":["read_write"],"organization":"willladislawBgMJ"}

Теперь вы можете использовать следующий токен JWT в значении заголовка Authorization: Bearer <JWT Token> и получить доступ к любому защищенному ресурсу.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ3aWxsbGFkaXNsYXciLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjQ2OGI3MzFmLTUxMzgtNDZhYi04MTU3LTU1MmZlMjM1MzY2ZSIsImNsaWVudF9pZCI6ImNsaWVudGFwcCIsInNjb3BlIjpbInJlYWRfd3JpdGUiXSwib3JnYW5pemF0aW9uIjoid2lsbGxhZGlzbGF3QmdNSiJ9.fUhFeUDuhm8f2V7CuURsZWKoAKjNZixk5rUa0Jyzov8

То, что вы сделали, вы спросили Spring Security OAuth2 для создания токена JWT с автономной информацией о вошедшем в систему пользователе и замены ее для стандартного UUID на основе accessToken, который он использует по умолчанию. То, что вы используете JWT Token, не означает, что вы получите возврат jwtToken из конечной точки oauth/token при входе в систему. Узнать больше о JWT .

...