使用 Vaadin 应用程序的通用访问卡 (CAC) 身份验证

Posted

技术标签:

【中文标题】使用 Vaadin 应用程序的通用访问卡 (CAC) 身份验证【英文标题】:Common Access Card (CAC) Authentication using Vaadin Application 【发布时间】:2015-10-11 02:00:48 【问题描述】:

我正在创建一个要求用户通过登录名和密码进行身份验证的 Vaadin Web 应用程序,我想知道是否可以添加 CAC 身份验证作为另一种身份验证方式。

总之,我的目标是如果用户已经通过其 CAC 身份验证,则允许访问该网站,或者如果用户未通过 CAC 身份验证,则需要标准登录(名称/密码)

通过搜索和谷歌搜索,我找到了Java PKCS#11,但它看起来像是一个用于桌面集成的库。

我还看到了this 和this 的帖子,这些帖子看起来与我的情况相似,但实际上并非如此。第一个是通过配置 Web 服务器来讨论整个 Web 应用程序的认证要求。第二个将 Java PKCS#11 作为桌面解决方案。

再次,我希望有一个“并行”登录,如果浏览器向服务器发送 CAC 证书,服务器不应该要求标准登录,否则是的。可能吗?此外,如果将 CAC 证书发送到服务器,是否有办法检索有关此 CAC 的数据,例如所有者的姓名?

【问题讨论】:

这不是 vaadin 特定的,它只是普通的 servlet 容器。您需要检查浏览器是否确实发送了客户端证书以及该证书是否有效 好的,我只需要知道如何执行这个检查浏览器是否从 servlet 发送客户端证书的过程。然后我将删除 Vaadin 标记。 你使用什么 servlet 容器? 我正在使用 Eclipse Jetty 【参考方案1】:

在正确配置的 servlet 容器中,您可以使用它来读取客户端证书(如果存在)

String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");

if (cipherSuite != null) 
    X509Certificate certChain[] = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
    if (certChain != null) 
        for (int i = 0; i < certChain.length; i++) 
            System.out.println ("Client Certificate [" + i + "] = "
                    + certChain[i].toString());
        
    

【讨论】:

我试过这个,但cipherSuite 始终为空。我用于此测试的 CAC 卡已连接并列在我的证书下。我应该先配置 Jetty 吗? 您的码头是否需要客户端证书?如果没有,那么客户就不可能寄给你一个 不,它没有。我没有在我的 Jetty 上配置 SSL。你有任何关于如何做到这一点的信息吗? 你的码头是接受 https 连接的,还是前面有 apache/nginx 或其他服务器? 设置一个请求客户端身份验证的嵌入式Jetty服务器非常容易:只需添加语句 SslContextFactory.setNeedClientAuth(true);配置服务器时到 ssl 上下文。任何在服务器的信任库中拥有其证书的客户端都能够建立到服务器的 TLS 连接。但弱点是在信任库中拥有正确的密钥......

以上是关于使用 Vaadin 应用程序的通用访问卡 (CAC) 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用通用访问卡连接到 HTTPS 服务器

如何在 Node/Express 中使用 CAC 对用户进行身份验证

CAC卡/读卡器的PKCS11驱动

具有自定义内容的 Vaadin 选项卡

为 CAC 卡身份验证配置 Apache HTTPD 的步骤

我可以创建单例 vaadin 组合框组件吗?