Java 当使用auth method=CLIENT-CERT时,如何避免在glassfish-web.xml文件中添加主体?

Java 当使用auth method=CLIENT-CERT时,如何避免在glassfish-web.xml文件中添加主体?,java,security,glassfish,glassfish-4.1,Java,Security,Glassfish,Glassfish 4.1,我刚刚开始为Glassfish 4.1编写一个web应用程序,我已经开始学习安全方面的知识 访问应用程序的用户将使用客户端证书来识别自己。我创建了一个自签名根CA。将此根CA添加到domain dir/config/cacerts.jks。创建了客户端证书,使用根CA对其进行签名,并将其添加到我的web浏览器中 web.xml: <web-app> <!-- other stuff --> <security-constraint> <w

我刚刚开始为Glassfish 4.1编写一个web应用程序,我已经开始学习安全方面的知识

访问应用程序的用户将使用客户端证书来识别自己。我创建了一个自签名根CA。将此根CA添加到domain dir/config/cacerts.jks。创建了客户端证书,使用根CA对其进行签名,并将其添加到我的web浏览器中

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>

/福
操作人员
CN=用户
这是可行的,但我不想在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>
。。。
...
...

。。。
...
...
但这也没用。我在日志中得到以下警告:“证书身份验证需要证书领域。”谷歌告诉我使用的领域必须是CertificateRealm的实例,我认为它的意思是com.sun.enterprise.security.auth.realm.Certificate.CertificateRealm,但该类是最终类,因此我无法扩展它

除了在glassfish-web.xml中定义之外,是否没有其他方法可以定义您的主体及其组?我应该抛弃玻璃鱼而使用其他东西,比如JBoss吗

编辑2015-03-31:

在问了这个问题后不久,我尝试了Jetty,在那里我成功地做了我想做的事情。我甚至能够将客户端证书身份验证与表单身份验证结合起来,如果客户端没有提供有效的证书,用户将被重新定向到基于表单的登录页面,并可以使用用户名和密码对自己进行身份验证

然后在身份验证时将角色添加到用户,以便Jetty可以控制对资源的访问


如果不必将每个用户添加到Glassfish-web.xml,就可以在CLIENT-CERT模式下控制Glassfish中用户的角色分配,但是能够从数据库中提取这些信息,并允许Glassfish控制对资源的访问仍然是一个有效的问题。但我并不急于得到答案。

我遇到了同样的问题,并通过以下链接解决了它:

只需使用domain.xml文件中的属性assign groups,如下所示:

<glassfish-web-app>
  <context-root>/foo</context-root>
  <security-role-mapping>
    <role-name>operator</role-name>
    <group-name>allusers</group-name>
  </security-role-mapping>
</glassfish-web-app>

allusers是为使用有效证书成功登录的所有用户动态创建的组

将主体标记和值替换为组名标记和值作为allusers。因此,您只需修改glassfish-web.xml,如下所示:

<glassfish-web-app>
  <context-root>/foo</context-root>
  <security-role-mapping>
    <role-name>operator</role-name>
    <group-name>allusers</group-name>
  </security-role-mapping>
</glassfish-web-app>
并使用以下内容检查DN部分:

String dn = certs[0].getSubjectX500Principal().getName();

希望有帮助。谢谢

不。对不起,但这真的没用。它解决了每个拥有有效证书的人都经过身份验证的问题,而无需将每个用户添加到glassfish-web.xml,但无需用户授权。并非服务器上的所有资源都是servlet,因此我无法在访问资源时始终检查证书。
String dn = certs[0].getSubjectX500Principal().getName();