2017-02-14 3 views
0

Есть ли способ обойти или использовать аутентификацию oauth (предъявителя) для операции refresh_token, используя весеннюю безопасность oauth? Я пробовал много конфигураций без успеха. В настоящее время единственным способом его работы является использование базовой аутентификации. Я думаю, что это плохо, потому что он заставляет клиента хранить пароль пользователя для обновления токена.Тип гранта refresh_token без базовой аутентификации

public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter { 
    @Autowired 
    private SecurityConfig securityConfig; 

    @Autowired 
    private AuthenticationManager authenticationManager; 

    @Autowired 
    private ClientDetailsService clientDetailsService; 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Override 
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.withClientDetails(clientDetailsService); 
    } 

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

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

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

    @Bean 
    protected JwtAccessTokenConverter jwtAccessTokenConverter() { 
     final KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(
      new ClassPathResource(securityConfig.getKeyResource()), securityConfig.getKeyPass().toCharArray()); 
     final JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 
     converter.setKeyPair(keyStoreKeyFactory.getKeyPair(securityConfig.getKeyAlias())); 
     return converter; 
    } 

    @Override 
    public void configure(final AuthorizationServerSecurityConfigurer oauthServer) 
     throws Exception { 
     oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); 
    } 

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

    @Bean 
    @Primary 
    public CustomTokenServices tokenServices() { 
     final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); 
     tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter())); 

     final CustomTokenServices services = new CustomTokenServices(); 
     services.setTokenStore(tokenStore()); 
     services.setTokenEnhancer(tokenEnhancerChain); 
     services.setSupportRefreshToken(true); 
     services.setClientDetailsService(clientDetailsService); 
     addUserDetailsService(services, userDetailsService); 
     return services; 
    } 

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

} 

WebSecurityConfiguration:

@Configuration 
//@EnableGlobalMethodSecurity(prePostEnabled = true) 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private ClientDetailsService clientDetailsService; 

    @Override 
    public void configure(final AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(clientDetailsUserService()); 
    } 

    @Bean 
    protected UserDetailsService clientDetailsUserService() { 
     return new ClientDetailsUserDetailsService(clientDetailsService); 
    } 

    @Override 
    protected void configure(final HttpSecurity http) throws Exception { 
     // disable caching 
     http.headers().cacheControl(); 

     http 
      .authorizeRequests() 
      .antMatchers(HttpMethod.OPTIONS).permitAll() 
      .antMatchers(HttpMethod.POST, "/login").permitAll() 
      .anyRequest().authenticated() 
      .and().csrf().disable(); 
    } 

    @Override 
    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

} 

ответ

0

Нет, это не возможно, чтобы обновить маркер доступа без действительных учетных данных клиента.

RFC 6749 раздел 1.5 говорит:

(G) клиент запрашивает новый маркер доступа с помощью аутентификации с сервера авторизации и представления токен обновления. [...]

С точки зрения безопасности и соответствия стандартам нецелесообразно применять такой подход в своей заявке.

Я думаю, что это плохо, потому что это заставляет клиента хранить пароль пользователя для обновления токена.

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

Рассмотрите возможность использования Spring Cloud Security. Он дает вам токен-реле между серверами ресурсов бесплатно, и вам не нужно беспокоиться об обновлении токенов доступа.

Посмотрите на это tutorial на spring.io.

Смежные вопросы