2017-08-28 7 views
0

funktioniert I Konfiguration in meinem Frühling Boot-App folgende haben:Spring Security OAuth2 widerrufen Token nicht

@Configuration 
public class SecurityConfig { 

@Configuration 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private MyUserDetailsService userDetailsService; 

    @Autowired 
    private BCryptPasswordEncoder passwordEncoder; 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); 
    } 

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

@Configuration 
@EnableAuthorizationServer 
public static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private MyUserDetailsService userDetailsService; 

    @Autowired 
    @Qualifier("authenticationManagerBean") 
    private AuthenticationManager authenticationManager; 

    @Autowired 
    @Qualifier("myOauth2ClientDetailsService") 
    private ClientDetailsService clientDetailsService; 

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

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     // set custom exception translator 
     endpoints.exceptionTranslator(e -> { 
      if (e instanceof OAuth2Exception) { 
       OAuth2Exception exception = (OAuth2Exception) e; 
       return ResponseEntity 
         .status(exception.getHttpErrorCode()) 
         .body(new MyWLoginException(exception.getMessage())); 
      } else { 
       throw e; 
      } 
     }); 
     // other settings 
     TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); 
     tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter())); 
     endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService).tokenStore(tokenStore()) 
       .tokenEnhancer(tokenEnhancerChain); 
    } 

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

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

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

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

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

@Configuration 
@EnableResourceServer 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@Order(-10) 
public static class ResourceServerConfig extends ResourceServerConfigurerAdapter { 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http.addFilterAfter(new AuditorFilter(), BasicAuthenticationFilter.class) 
       .headers().frameOptions().disable() 
      .and().csrf().disable() 
      .authorizeRequests() 
       .antMatchers("/img/**").permitAll() 
       .anyRequest().authenticated(); 

    } 

    @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(); 
     DefaultAccessTokenConverter defaultAccessTokenConverter = new DefaultAccessTokenConverter(); 
     defaultAccessTokenConverter.setUserTokenConverter(userAuthenticationConverter()); 
     converter.setAccessTokenConverter(defaultAccessTokenConverter); 
     converter.setSigningKey("123"); 
     return converter; 
    } 

    @Bean 
    public UserAuthenticationConverter userAuthenticationConverter() { 
     return new MyUserAuthenticationConverter(); 
    } 

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

}

Auch habe ich spezielle Endpunkt Token zu widerrufen, die Anfrage in folgenden Verfahren behandelt:

@Autowired 
private TokenStore tokenStore; 
@Autowired 
private AuthorizationServerTokenServices authorizationServerTokenServices; 
@Autowired 
private ResourceServerTokenServices resourceServerTokenServices; 
... 
final String tokenValue = ((OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); 
     final OAuth2AccessToken token = tokenStore.readAccessToken(tokenValue); 
     tokenStore.removeAccessToken(token); 
     boolean authRemoved = ((DefaultTokenServices) authorizationServerTokenServices).revokeToken(tokenValue); // <- true 
     boolean resourceRemoved = ((DefaultTokenServices) resourceServerTokenServices).revokeToken(tokenValue); // <- true 
     SecurityContextHolder.getContext().setAuthentication(null); 

Es liegen keine Fehler vor. Ich sehe, dass Token-Dienste true (entfernt) zurückgeben. Aber wenn ich einen Endpunkt mit einem alten Zugriffs-Token anrufe, funktioniert es wie dieses Token noch am Leben. Aber ich entferne Token von Auth-Server und Ressourcen-Server. Wie behebe ich dieses Problem?

Antwort

1

Der Token-Widerruf funktioniert nicht mit JWT, da der Token, in den er eingebettet ist, abgelaufen ist. Ihr Autorisierungsserver wird nach der Ausgabe keine Informationen über das Token erhalten. Vielleicht sollten Sie versuchen, einen JdbcTokenStore in Ihrem Autorisierungsserver zu verwenden, um Ihre Token in einem DB zu halten und sie dann wie gewünscht zu widerrufen (oder könnte auch im Speicher sein). Wenn Ihre Apps getrennt sind, können Sie Ihre Tokens mit RemoteTokenServices validieren.

ist ein Tutorial, das Ihnen zeigt, wie Sie dies erreichen können.

+0

Ich denke, Sie haben Recht. Ich plane, RedisTokenStore zu verwenden. Ich denke, ich brauche einen einzigen und klaren Speicher für Token –

Verwandte Themen