在自定义 UserDetailsService 中访问当前 ClientDetails
Posted
技术标签:
【中文标题】在自定义 UserDetailsService 中访问当前 ClientDetails【英文标题】:Accessing current ClientDetails inside custom UserDetailsService 【发布时间】:2021-02-24 11:41:08 【问题描述】:我正在使用 Spring Boot OAuth 授权服务器(旧堆栈)并使用 Oauth2 password
流实现我自己的 ClientDetailsService
和 UserDetailsService
版本.
我们的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;
之后,我们的JpaUserDetailsService
实现的loadUserByUsername
方法被调用,接收试图认证的用户的用户名:
@Service
public class JpaUserDetailsService implements UserDetailsService
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
return null;
我的问题是:
我如何访问由JpaClientDetailsService.loadClientByClientId
在JpaUserDetailsService.loadUserByUsername
中返回的当前ClientDetails
?
谢谢!
【问题讨论】:
【参考方案1】:我意识到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)));
//....
就是这样。
【讨论】:
以上是关于在自定义 UserDetailsService 中访问当前 ClientDetails的主要内容,如果未能解决你的问题,请参考以下文章
Spring security - 未调用自定义 userDetailsService 实现
使用我的自定义 UserDetailsService 后,httpsession 生命周期事件不起作用
Spring security 3.2:自定义 UserDetails 和 UserDetailsService 是不是需要自定义 AuthenticationManager?
如何摆脱这个异常“没有定义名为'userDetailsService'的bean”虽然它是在xml文件中定义的?