1

J'ai une implémentation OAuth2 qui fonctionne correctement pour l'attribut type = mot de passe. Maintenant, j'ai besoin d'ajouter une logique de restriction de la même combinaison utilisateur/mot de passe pour être autorisé à se connecter à nouveau si l'utilisateur est connecté plus tôt. Pour cela, j'ai recherché et pensé que je créer une nouvelle classe (MyDefaultTokenService) qui étend la classe DefaultTokenServices, puis ajouter ma logique dans la méthode redéfinie createAccessToken. Mais pour une raison quelconque, lorsque je débogue et que je teste, je ne frappe pas les points d'arrêt placés dans la classe MyDefaultTokenService. Il frappe toujours la classe DefaultTokenServices de Springboot. Je ne sais pas où je vais mal, quelqu'un pourrait s'il vous plaît.Spring Boot Oauth2 Extension de DefaultTokenServices

AuthorizationConfiguration.java

package com.company.config; 

import java.util.Arrays; 

import javax.sql.DataSource; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.boot.bind.RelaxedPropertyResolver; 
import org.springframework.context.EnvironmentAware; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 
import org.springframework.core.env.Environment; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.oauth2.common.OAuth2AccessToken; 
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 
import org.springframework.security.oauth2.provider.OAuth2Authentication; 
import org.springframework.security.oauth2.provider.TokenRequest; 
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; 
import org.springframework.security.oauth2.provider.token.TokenEnhancer; 
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; 
import org.springframework.security.oauth2.provider.token.TokenStore; 
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; 

import com.alcord.enums.Authorities; 
import com.alcord.model.Account; 

@Configuration 
@EnableAuthorizationServer 
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter 
     implements EnvironmentAware { 

    private static final String ENV_OAUTH = "authentication.oauth."; 
    private static final String PROP_CLIENTID = "clientid"; 
    private static final String PROP_SECRET = "secret"; 
    private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds"; 

    private RelaxedPropertyResolver propertyResolver; 

    @Autowired 
    private DataSource dataSource; 

    @Bean 
    public TokenStore tokenStore() { 
     return new JdbcTokenStore(dataSource); 
    } 

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

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 

     final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); 
     tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer())); 
     endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain) 
       .authenticationManager(authenticationManager); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory().withClient(propertyResolver.getProperty(PROP_CLIENTID)).scopes("read", "write") 
       .authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_DRIVER.name(), 
         Authorities.ROLE_PASSENGER.name()) 
       .authorizedGrantTypes("password", "refresh_token", "authorization_code", "implicit") 
       .secret(propertyResolver.getProperty(PROP_SECRET)).accessTokenValiditySeconds(
         propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800)); 
    } 

    @Override 
    public void setEnvironment(Environment environment) { 
     this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH); 
    } 

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

    @Bean 
    @Primary 
    public DefaultTokenServices tokenServices() { 
     MyTokenService tokenService = new MyTokenService(); 
     tokenService.setTokenStore(tokenStore()); 
     tokenService.setSupportRefreshToken(true); 
     tokenService.setTokenEnhancer(tokenEnhancer()); 
     return tokenService; 
    } 

    class MyTokenService extends DefaultTokenServices { 

     public MyTokenService() { 
     } 

     @Override 
     public OAuth2AccessToken readAccessToken(String accessToken) { 
      return super.readAccessToken(accessToken); 
     } 

     @Override 
     public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException { 
      OAuth2AccessToken token = super.createAccessToken(authentication); 
      Account account = (Account) authentication.getPrincipal(); 
      // This is where I will add my logic when it hits the breakpoint. 
      return token; 
     } 

     @Override 
     public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) 
       throws AuthenticationException { 

      OAuth2AccessToken token = super.refreshAccessToken(refreshTokenValue, tokenRequest); 
      return token; 
     } 
    } 
} 

Configuration des ressources du serveur

package com.company.config; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.HttpMethod; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.http.SessionCreationPolicy; 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; 
import org.springframework.security.oauth2.provider.token.TokenStore; 

import com.alcord.security.CustomAuthenticationEntryPoint; 
import com.alcord.security.CustomLogoutSuccessHandler; 

@Configuration 
@EnableResourceServer 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

    // The DefaultTokenServices bean provided at the AuthorizationConfig 
    @Autowired 
    private DefaultTokenServices tokenServices; 

    // The TokenStore bean provided at the AuthorizationConfig 
    @Autowired 
    private TokenStore tokenStore; 

    @Autowired 
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint; 

    @Autowired 
    private CustomLogoutSuccessHandler customLogoutSuccessHandler; 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 

     http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).and().logout() 
       .logoutUrl("/oauth/logout").logoutSuccessHandler(customLogoutSuccessHandler).and().csrf().disable() 
       .headers().frameOptions().disable().exceptionHandling().and().sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS, "/**").permitAll().antMatchers("/api/v1/login/**").permitAll() 
       .antMatchers("/api/v1/admin/**").permitAll().antMatchers("/api/v1/test/**").permitAll() 
       .antMatchers("/oauth/token").permitAll().antMatchers("/api/**").authenticated(); 
    } 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) { 
     resources.tokenServices(tokenServices).tokenStore(tokenStore).resourceId("oauth2_id"); 

    } 

} 

Répondre

0

La réponse à cette question. Manqué d'ajouter tokenServices() dans la méthode de configuration

@Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 

     final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); 
     tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer())); 
     endpoints.tokenStore(tokenStore()).tokenServices(tokenServices()).tokenEnhancer(tokenEnhancerChain) 
       .authenticationManager(authenticationManager); 
    } 
0

En utilisant le flux de configuration similaire à avoir un Bean ici:

@Bean 
@Primary 
public DefaultTokenServices tokenServices() throws Exception { 
    DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); 
    // .... more config stuff 
    return defaultTokenServices; 
} 

... et config du service au point final:

@Override 
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
    //@formatter:off 
    endpoints.tokenServices(tokenServices()). 
    authenticationManager(authenticationManager).approvalStoreDisabled(); 
    //@formatter:on 
} 

.. mais je rencontre des erreurs suivantes:

at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) 
... 31 common frames omitted 

Caused by: java.lang.IllegalStateException: @Bean method 
AuthorizationServerConfig.tokenServices called as a bean reference 
for type [org.springframework.security.oauth2.provider.token.DefaultTokenServices] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy105]. Overriding bean of same name declared in: 
class path resource [com/xxx/xxx/authorization/server/config/AuthorizationServerConfig.class] 
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.obtainBeanInstanceFromFactory(ConfigurationClassEnhancer.java:402) 
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) 
at com.xxx.xxx.authorization.server.config.AuthorizationServerConfig$$EnhancerBySpringCGLIB$$253a93dd.tokenServices(<generated>) 
at com.xxx.xxx.authorization.server.config.AuthorizationServerConfig.configure(AuthorizationServerConfig.java:113) 
at org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration.init(AuthorizationServerEndpointsConfiguration.java:77) 

... peut-être que quelqu'un peut me dire pourquoi?