简体   繁体   English

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

[英]How to avoid adding principal in glassfish-web.xml file when using auth-method=CLIENT-CERT?

I have just started writing a web application for Glassfish 4.1 and I've started of with the security stuff. 我刚刚开始为Glassfish 4.1编写Web应用程序,并且从安全性方面入手。

Users accessing the application will identify them self with a client certificate. 访问该应用程序的用户将使用客户端证书标识自己。 I created a self-signed root CA. 我创建了一个自签名的根CA。 Added this root CA to domain-dir /config/cacerts.jks. 将此根CA添加到domain-dir /config/cacerts.jks。 Created a client certificate, signed it with root CA and added it to my web browser. 创建了一个客户端证书,并用根CA对其进行了签名并将其添加到我的Web浏览器中。

web.xml: 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.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>

This works, but I don't want to have to add a principal-name in glassfish-web.xml for each new user. 这可行,但是我不想在glassfish-web.xml中为每个新用户添加一个主体名称。 I would like to fetch that information from a database together with group information for each user. 我想从数据库中获取该信息以及每个用户的组信息。

I have looked into and tried to write my own realm extending com.sun.appserv.security.AppservRealm .I have added the realm in the proper way, but it can only be used if I set auth-method in web.xml to BASIC . 我已经研究并尝试编写自己的扩展com.sun.appserv.security.AppservRealm的领域。我以适当的方式添加了该领域,但是只有在将web.xml中的auth-method设置为BASIC时才能使用它。 Using CLIENT-CERT will ignore the realm-name element: 使用CLIENT-CERT将忽略realm-name元素:

<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>

In the second case, the pre-defined realm 'certificate' will be used. 在第二种情况下,将使用预定义的领域“证书”。 And using BASIC will obviously not use a client certificate. 使用BASIC显然不会使用客户端证书。

There is another way and that is to modify domain-dir /config/domain.xml and replace 还有另一种方法,那就是修改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>

with

...
<config name="server-config">
  ...
  <security-service>
    ...
    <auth-realm classname="org.foo.MyCertificateRealm" name="certificate"></auth-realm>

But that doesn't help either. 但这也无济于事。 I get the following warning in the log: "Certificate authentication requires certificate realm." 我在日志中收到以下警告:“证书身份验证需要证书领域。” Googling told me that the used realm must be an instance of CertificateRealm and I take it it means com.sun.enterprise.security.auth.realm.certificate.CertificateRealm , but that class is final, so I can't extend it. Googling告诉我,使用的领域必须是CertificateRealm的实例,我认为这意味着com.sun.enterprise.security.auth.realm.certificate.CertificateRealm ,但是该类是最终的,因此我无法对其进行扩展。

Is there no way to have your principals and their groups defined somewhere else than in glassfish-web.xml? 除了在glassfish-web.xml中,没有其他方法可以定义您的主体及其组吗? Should I ditch Glassfish and use something else, like JBoss? 我应该抛弃Glassfish并使用其他东西,例如JBoss吗?

EDIT 2015-03-31: 编辑2015-03-31:

Soon after asking this question I tried out Jetty and there I managed to do what I wanted to do. 问了这个问题后不久,我尝试了Jetty,在那里我做了自己想做的事。 I was even able to combine CLIENT-CERT authentication with FORM authentication in a way that if the client doesn't provide a valid certificate, the user is re-directed to a form based log-in page and can authenticate herself with a user name and password. 我什至可以将CLIENT-CERT身份验证与FORM身份验证结合使用,如果客户端不提供有效证书,则该用户将被重定向到基于表单的登录页面,并可以使用用户名进行身份验证和密码。

Roles are then added to the user at the time of authentication so that Jetty can control access to resources. 然后在身份验证时将角色添加到用户,以便Jetty可以控制对资源的访问。

If control of role-assignment to a user in Glassfish in CLIENT-CERT mode can be accomplished without having to add each user to glassfish-web.xml, but to be able to pull this information from eg a data base, and allowing Glassfish to control access to resources is still a valid question. 如果可以在CLIENT-CERT模式下完成对Glassfish中用户的角色分配控制,而不必将每个用户都添加到glassfish-web.xml中,但是能够从例如数据库中提取此信息,并允许Glassfish控制对资源的访问仍然是一个有效的问题。 But I'm in no hurry to receive an answer. 但是我不急于得到答案。

I got the same problem and resolve it whith this link: here 我遇到了同样的问题,并通过以下链接解决了此问题: 此处

Just use the property assign-groups in the domain.xml file like that: 只需使用domain.xml文件中的assign-groups属性,如下所示:

<auth-realm classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm" name="certificate"> <property name="assign-groups" value="allusers"></property> </auth-realm>

allusers will be the group dynamically created for all users who successfully log in with a valid certificate. allusers将是为所有成功使用有效证书登录的用户动态创建的组。

Replace the principal tag and value, by the group-name tag and value as allusers. 将组名标签和值替换为主体标签和值,并作为allusers。 So you will have to just modify your glassfish-web.xml like that: 因此,您只需要像这样修改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>

No need to add Principals in the web.xml. 无需在web.xml中添加主体。 You can after check in a Servlet which certificate is connected by retrieving it with: 您可以在Servlet中检入连接了哪个证书后,可以使用以下方法检索它:

X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");

and check the DN part with something like: 并使用以下方法检查DN部分:

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

Hope it helps.Thanks! 希望对您有所帮助。谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM