【问题标题】:Access certificate content from loadUserByUsername从 loadUserByUsername 访问证书内容
【发布时间】:2016-06-14 12:27:32
【问题描述】:

我正在开发一个需要进行以下身份验证的 spring mvc 应用程序

  1. 通过tomcat证书存储验证客户端证书
  2. 验证客户端证书的附加属性

我尝试使用 loadUserByUsername() 实现#2,但不知道如何访问 loadUserByUsername() 中的证书内容?

我发现this 相关。发布的答案是从HttpServletRequest 阅读。我可以从loadUserByUsername() 访问HttpServletRequest 吗?

我试过了

SecurityContextHolder.getContext().getAuthentication().getCredentials();

但在loadUserByUsername() 中没有设置Authentication 对象。

【问题讨论】:

    标签: spring spring-security x509certificate


    【解决方案1】:

    更新

    在进行了一些挖掘之后,我发现 Java Config 提供了一种非常简单的方法来获取 X509Certificate,并通过简单的 AuthenticationUserDetailsS​​ervice 实现:

    @Configuration
    protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/**")
                .x509()
                .authenticationUserDetailsService(new X509AuthenticatedUserDetailsService());
        }
    
        protected static class X509AuthenticatedUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
    
            @Override
            public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
                    throws UsernameNotFoundException {
                X509Certificate certificate = (X509Certificate)token.getCredentials();
                // do your extra checking here...
    
                // add granted authorities, etc.
                Collection<GrantedAuthority> authorities = Collections.EMPTY_LIST;
    
                // generate your user how you deem fit
                User user = new User(certificate.getSubjectX500Principal().getName(), null, authorities);
                return user;
            }
    
        }
    }
    

    请注意,在 loadUserDetails 方法中,您所做的实际上与实现 UserDetailsService 时所做的相同,只是此方法采用整个 Authentication 对象。

    原创

    我不确定这是否是预期的方式;但是,X509Certificate 是通过在X509AuthenticationFilter 中生成的身份验证令牌传递的。调用 PreAuthenticatedAuthenticationToken#getCredentials 应该会为您获取证书。

    通过 API 稍作研究表明,PreAuthenticatedAuthenticationProvider 可以配置自定义 UserDetailsCheckerAuthenticatedUserDetailsService。这些可能足以让您从X509Certificate 中提取详细信息并进行验证。

    【讨论】:

    • 感谢您的帮助。我正在使用 Spring Security 3.0,我认为它不支持 Java Config。我想知道如何设置 x509 过滤来调用 security.xml 中的 X509AuthenticatedUserDetailsS​​ervice
    • 从文档看来,user-details-ref 想要一个 UserDetailsS​​ervice 所以我不相信你可以使用 标记。相反,您可以直接在 xml 中配置 X509AuthenticationFilter。你可以在这里找到一个很好的例子:stackoverflow.com/questions/12478589/… 你可以用 Spring 的 X509AuthenticationFilter 替换 com.example.MyPreAuthenticatedProcessingFilter。
    • 谢谢乔希!按照您的建议,我现在可以正常工作了。
    • 这是一个很棒的答案,需要更多的爱。使用AuthenticationUserDetailsService 访问完整对象!谢谢
    • 非常感谢,您的解决方案对我来说很好。
    【解决方案2】:

    在我的例子中,我确实在 UserDetailsS​​ervice 的以下实现中从 id 获取证书 ID。这是security.xml中的一个简单配置 public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException { 安全.xml

    但如果证书 onAuthenticationSuccess 没有在公共类中调用 myAuthSuccessHandler 实现 AuthenticationSuccessHandler {

    有什么建议吗?想法?

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 2017-04-22
      • 2014-06-03
      • 1970-01-01
      相关资源
      最近更新 更多