我正在使用 Spring Boot OAuth授权服务器(旧堆栈),并使用Oauth2实现自己的ClientDetailsService
和UserDetailsService
版本password
流。
我们的JpaClientDetailsService
实现loadClientByClientId
并返回ClientDetails
,其中包含正在认证的客户端的详细信息。
@Service
public class JpaClientDetailsService implements ClientDetailsService {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails baseClientDetails = new BaseClientDetails(...);
//do processing....
return baseClientDetails;
}
}
此后,我们实现loadUserByUsername
的方法JpaUserDetailsService
被调用,接收试图进行身份验证的用户的用户名:
@Service
public class JpaUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return null;
}
}
我的问题是:
我如何访问ClientDetails
内部JpaClientDetailsService.loadClientByClientId
返回的当前JpaUserDetailsService.loadUserByUsername
?
谢谢!
答案 0 :(得分:0)
我意识到SecurityContextHolder.getContext().getAuthentication()
包含有关正在认证的client
的信息。因此,我能够获得client
的名称并按如下方式加载其数据:
@Service
public class JpaUserDetailsService implements UserDetailsService {
@Autowired
private OAuthClientsRepository oAuthClientsRepository;
@Override
public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//Gets the Authentication from SecurityContextHolder
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//ClientId is 'Principal's' Username
var clientId = ((User) authentication.getPrincipal()).getUsername();
//Gets clientDetails from JPA Repository. This would execute another Roundtrip to Database, but since we have 2nd level cache configured, this
//problema is minimized.
ClientDetails authClient = oAuthClientsRepository
.findByClientId(clientId)
.orElseThrow(() -> new NoSuchClientException(String.format("ClientId '%s' not found", clientId)));
//....
}
}
就是这样。