2017-08-12 259 views
1

我有一个OAuth2实现,对grant type = password正常工作。现在我需要添加一个限制相同用户/密码组合的逻辑,以便在用户先前登录时再次登录。 为此,我研究并认为我要创建一个新的类(MyDefaultTokenService),它扩展了DefaultTokenServices类,然后在重写的createAccessToken方法中添加我的逻辑。但出于某种原因,当我调试和测试时,我没有打到放置在MyDefaultTokenService类中的断点。它总是击中Springboot的DefaultTokenServices类。我不知道我哪里错了,请问有人可以。Spring Boot Oauth2扩展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; 
     } 
    } 
} 

资源服务器配置

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"); 

    } 

} 

回答

0

这个问题的答案。错过了加入tokenServices()在配置方法

@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

采用类似配置流在这里有一个Bean:

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

...和配置服务到端点:

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

..但我遇到以下错误:

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) 

...也许有人可以告诉我为什么?

相关问题