在自定义 UserDetailsS​​ervice 中访问当前 ClientDetails

Posted

技术标签:

【中文标题】在自定义 UserDetailsS​​ervice 中访问当前 ClientDetails【英文标题】:Accessing current ClientDetails inside custom UserDetailsService 【发布时间】:2021-02-24 11:41:08 【问题描述】:

我正在使用 Spring Boot OAuth 授权服务器旧堆栈)并使用 Oauth2 password 流实现我自己的 ClientDetailsServiceUserDetailsService 版本.

我们的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.loadClientByClientIdJpaUserDetailsService.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)));

        //....

    


就是这样。

【讨论】:

以上是关于在自定义 UserDetailsS​​ervice 中访问当前 ClientDetails的主要内容,如果未能解决你的问题,请参考以下文章

Spring security - 未调用自定义 userDetailsS​​ervice 实现

使用我的自定义 UserDetailsS​​ervice 后,httpsession 生命周期事件不起作用

Spring security 3.2:自定义 UserDetails 和 UserDetailsS​​ervice 是不是需要自定义 AuthenticationManager?

如何摆脱这个异常“没有定义名为'userDetailsS​​ervice'的bean”虽然它是在xml文件中定义的?

Spring Security 自定义 UserDetailsS​​ervice 和自定义 User 类

集成 Spring Security:身份验证自定义 UserDetailsS​​ervice