将刷新令牌用于自定义身份验证提供程序

时间:2019-08-05 04:46:58

标签: spring-boot spring-security spring-security-oauth2

我结合了Jdbc身份验证提供程序和在授权服务器中配置的自定义身份验证提供程序。代码段如下所示。

SecurityConfig.java

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired(required = false)
    private List<AuthenticationProvider> providers;

    @Autowired
    private DataSource dataSource;

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

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**", "/webjars/**").antMatchers(HttpMethod.OPTIONS, "/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers().antMatchers("/login","/oauth/authorize")
            .and()
                .authorizeRequests().anyRequest().authenticated()
            .and()
                .formLogin().permitAll()
            .and()
                .logout().permitAll()
            .and()
                .csrf().disable().cors().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
        .usersByUsernameQuery("select username,password,enabled from tbl_users where username = ?")
        .authoritiesByUsernameQuery("select username, role as authority from tbl_user_roles where username = ?");
        if(providers !=null && !providers.isEmpty()) {
            providers.stream().forEach(auth::authenticationProvider);
        }
    }

    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

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

}

AuthServerConfig.java

@Configuration
@EnableAuthorizationServer
@EnableConfigurationProperties(AuthorizationServerProperties.class)
@Import({AuthorizationServerTokenServicesConfiguration.class})
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired(required = false)
    private AccessTokenConverter tokenConverter;


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

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService).reuseRefreshTokens(false);
        if(tokenConverter != null) {
            endpoints.accessTokenConverter(tokenConverter);
        }
        endpoints.tokenStore(tokenStore());
    }

}

CustomAuthProvider.java

@Configuration
@Order(103)
public class CustomAuthProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();
        if("kp_user".equals(username) && "password".equals(password)) {
            return new UsernamePasswordAuthenticationToken(username, password, Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

对于使用数据库注册的用户,使用刷新令牌进行身份验证和获取新的访问令牌的效果很好。

当我对自定义身份验证提供程序中存在的用户进行身份验证时,我可以进行身份​​验证并获取新的访问令牌和刷新令牌

curl -X POST \
  http://localhost:8080/oauth/token \
  -H 'Authorization: Basic Y2xpZW50XzE6c2VjcmV0' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'username=kp_user&password=password&grant_type=password'

但是,当我尝试使用refresh_token为自定义身份验证提供程序中存在的用户获取新的访问令牌时,出现错误User kp_user not found

curl -X POST \
  http://localhost:8080/oauth/token \
  -H 'Authorization: Basic Y2xpZW50XzE6c2VjcmV0' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJrcF91c2VyIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwidHJ1c3QiXSwiYXRpIjoiOTNmNDJkNWUtZDBkMy00YjgzLThkYjYtZDA1NTdhNmJkOWNhIiwiZXhwIjoxNTY1MDE0OTA3LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiMzM4MmEzYzctNzYwMi00YmY5LTk5YWItYjM2MTg5YmNiNzNkIiwiY2xpZW50X2lkIjoiY2xpZW50XzEifQ.KmB1vz4lIQYySkeQKR0HOyJEVepl-Z5R6LHJu3Zc7CA'

我不确定是否需要自定义DefaultTokenServices,可以在here中找到源代码。

0 个答案:

没有答案