Security自定义Provider如何获取更多用户信息

在使用Spring Security集成Oauth2.0做Auth server时,使用自定义的UserDetailsService实现时,在Controller层通过自动注入,可以获取详细的用户信息。

@GetMapping("/user")
public Principal user(Principal user) {
  return user;
}

但是,使用自定义的Provider去做账户校验时,获取的Principal就只含有用户名信息。

分析原码发现

// org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter
public Authentication extractAuthentication(Map<String, ?> map) {
  if (map.containsKey(USERNAME)) {
    Object principal = map.get(USERNAME);
    Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
    if (userDetailsService != null) {
      UserDetails user = userDetailsService.loadUserByUsername((String) map.get(USERNAME));
      authorities = user.getAuthorities();
      principal = user;
    }
    return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
  }
  return null;
}

通过jwt方式进行认证的会执行DefaultUserAuthenticationConverter代码,其中的userDetailsService是null,所以返回的principal就只有用户名。

可以通过在创建DefaultUserAuthenticationConverter时,给他set上userDetailsService,这样就获取更多的信息了。

如下:

@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
    jwtAccessTokenConverter.setSigningKey("demo");
    final AccessTokenConverter accessTokenConverter = jwtAccessTokenConverter.getAccessTokenConverter();
    if (accessTokenConverter instanceof DefaultAccessTokenConverter) {
        ((DefaultAccessTokenConverter) accessTokenConverter).setUserTokenConverter(userAuthenticationConverter());
    }
    return jwtAccessTokenConverter;
}

@Bean
public UserAuthenticationConverter userAuthenticationConverter() {
    DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
    defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
    return defaultUserAuthenticationConverter;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!