Oauth2-java.lang.IllegalStateException:需要UserDetailsS ervice。带有刷新令牌

问题描述 投票:1回答:3

我正在尝试在春季启动时使用jwt来实现oauth2,并且可以正常工作,但是当我想要获取refresh_token时,发生错误,指示以下内容...

java.lang.IllegalStateException:需要UserDetailsS​​ervice。在org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter $ UserDetailsS​​erviceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:464)处在org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:68)在org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider.authenticate(PreAuthenticatedAuthenticationProvider.java:103)处在org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)在org.springframework.security.oauth2.provider.token.DefaultTokenServices.refreshAccessToken(DefaultTokenServices.java:150)

我在做什么错?

这些是我的文件

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

@Value("${token.secret}")
private String secret;
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${oauth2.client.id}")
public String  CLIENT_ID;
@Value("${oauth2.client.secret}")
public String  CLIENT_SECRET;
@Value("${oauth2.scope.read}")
public String  SCOPE_READ;
@Value("${oauth2.grant.types}")
public String  GRANT_TYPES;
@Value("${oauth2.scopes}")
public String  SCOPES;
@Value("${oauth2.access.token.validity}")
public Integer  TOKEN_VALID_SECONDS;
@Value("${oauth2.refresh.token.validity}")
public Integer  REFRESH_TOKEN_VALID_SECONDS;


@Autowired
private DataSource dataSource;

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

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

@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { 
    clients.inMemory()
            .withClient(CLIENT_ID)
            .secret(passwordEncoder().encode(CLIENT_SECRET))
            .authorizedGrantTypes("password", "refresh_token", "client_credentials","authorization_code")
            .scopes("read", "write", "trust")
            .accessTokenValiditySeconds(TOKEN_VALID_SECONDS)
            .refreshTokenValiditySeconds(REFRESH_TOKEN_VALID_SECONDS);
} 

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

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

}

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


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

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
}

这是我的SecurityConfig类

@EnableGlobalMethodSecurity(securedEnabled=true)
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private final CustomUserDetailsService customUserDetailsService;
@Autowired
public BCryptPasswordEncoder passwordEncoder;

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

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

@Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/oauth/**").permitAll()
    .antMatchers("/oauth/token/**").permitAll()
    .antMatchers("/api/**" ).authenticated()
    .anyRequest().authenticated()
    .and().formLogin().permitAll()
    .and().csrf().disable();

}

}

public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private UserService userService;
//login web service url describe on properties file
@Value("${loginServiceUri}")
public String loginServiceUri;
//login web service enabled 
@Value("${loginWebServiceEnabled}")
public Boolean loginWebServiceEnabled;


@Override
public UserDetails loadUserByUsername(String username) {

    log.debug("Trying to authenticate user with details....");

    if (loginWebServiceEnabled && loginServiceUri != null){
        //its necessary to call external Web Service to find the user and then look for 
        //into database
        UserDto userDto = this.loginWebService(username);

        if (userDto != null) {
            // look for the user in data base
            log.debug("User found at external login web service trying to look for at data base");
            return lookUserDataBase(userDto.getUsername());
        } else {
            log.error("User not found at external login web service", username);
            throw new UsernameNotFoundException(username);
        }

    } else {
        // look for the user in data base
        return lookUserDataBase(username);
    }


}

/**
 * Look for use in data base by user name

 * @return
 */
private UserDetails lookUserDataBase(String userName) {
    UserEntity user = userService.findEntityByUsername(userName);
    if (user == null) {
        log.error("User not found in data base", userName);
        throw new UsernameNotFoundException(userName);
    }
    log.debug("User found in data base with userName: " + userName + " and authorities: " + user.getUserAuthority().toString());
    return new UserAuthenticatedDetails(user);
}


/**
 *  Example Login Web Service call login 
 * @param name
 * @return
 */
private UserDto loginWebService (String name){
    xxxxxxxxxxx
}

}

spring spring-boot oauth-2.0 spring-security-oauth2
3个回答
0
投票
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password("password") .roles("USER") .and() .withUser("manager") .password("password") .credentialsExpired(true) .accountExpired(true) .accountLocked(true) .authorities("WRITE_PRIVILEGES", "READ_PRIVILEGES") .roles("MANAGER"); }

或您实现UserDetailService,例如在数据库中查找用户。


0
投票
@Autowired public void setApplicationContext(ApplicationContext context) { super.setApplicationContext(context); AuthenticationManagerBuilder globalAuthBuilder = context .getBean(AuthenticationManagerBuilder.class); try { globalAuthBuilder.userDetailsService(userDetailsService); } catch (Exception e) { e.printStackTrace(); } }

[有一个“本地” AuthenticationManagerBuilder和一个“全局” AuthenticationManagerBuilder,我们需要在全局版本上进行设置,以便将此信息传递给其他构建器上下文。

阅读有关它的更多信息here

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.