我刚刚开始为 Glassfish 4.1 编写一个 Web 应用程序,并且开始处理安全问题。
访问应用程序的用户将使用客户端证书来识别他们自己。我创建了一个自签名的根 CA。将此根 CA 添加到domain-dir /config/cacerts.jks。创建客户端证书,使用根 CA 对其进行签名并将其添加到我的 Web 浏览器。
网页.xml:
<web-app>
<!-- other stuff -->
<security-constraint>
<web-resource-collection>
<web-resource-name>foo</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>operator</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
<security-role>
<role-name>operator</role-name>
</security-role>
</web-app>
glassfish-web.xml:
<glassfish-web-app>
<context-root>/foo</context-root>
<security-role-mapping>
<role-name>operator</role-name>
<principal-name>CN=user</principal-name>
</security-role-mapping>
</glassfish-web-app>
这可行,但我不想在 glassfish-web.xml 中为每个新用户添加一个主体名称。我想从数据库中获取该信息以及每个用户的组信息。
我已经研究并尝试编写我自己的扩展com.sun.appserv.security.AppservRealm的领域。我已经以正确的方式添加了领域,但只有当我将 web.xml 中的 auth-method 设置为BASIC时才能使用它. 使用CLIENT-CERT将忽略领域名称元素:
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>my-realm</realm-name>
</login-config>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>my-realm</realm-name>
</login-config>
在第二种情况下,将使用预定义的领域“证书”。并且使用BASIC显然不会使用客户端证书。
还有另一种方法,那就是修改domain-dir /config/domain.xml 并替换
...
<config name="server-config">
...
<security-service>
...
<auth-realm classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm" name="certificate"></auth-realm>
和
...
<config name="server-config">
...
<security-service>
...
<auth-realm classname="org.foo.MyCertificateRealm" name="certificate"></auth-realm>
但这也无济于事。我在日志中收到以下警告:“证书身份验证需要证书领域。” 谷歌搜索告诉我,使用的领域必须是 CertificateRealm 的一个实例,我认为它的意思是com.sun.enterprise.security.auth.realm.certificate.CertificateRealm,但该类是最终的,所以我不能扩展它。
除了 glassfish-web.xml 之外,没有办法让您的主体及其组定义在其他地方吗?我应该放弃 Glassfish 并使用其他东西,比如 JBoss 吗?
编辑 2015-03-31:
问完这个问题后不久,我尝试了 Jetty,并在那里我设法做我想做的事。我什至能够将 CLIENT-CERT 身份验证与 FORM 身份验证相结合,如果客户端不提供有效证书,用户将被重定向到基于表单的登录页面,并且可以使用用户名对自己进行身份验证和密码。
然后在身份验证时将角色添加到用户,以便 Jetty 可以控制对资源的访问。
如果可以在 CLIENT-CERT 模式下在 Glassfish 中控制对用户的角色分配,而无需将每个用户添加到 glassfish-web.xml,但能够从例如数据库中提取此信息,并允许 Glassfish控制对资源的访问仍然是一个有效的问题。但我并不急于得到答复。