簡體   English   中英

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

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

我剛剛開始為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>

這可行,但是我不想在glassfish-web.xml中為每個新用戶添加一個主體名稱。 我想從數據庫中獲取該信息以及每個用戶的組信息。

我已經研究並嘗試編寫自己的擴展com.sun.appserv.security.AppservRealm的領域。我以適當的方式添加了該領域,但是只有在將web.xml中的auth-method設置為BASIC時才能使用它。 使用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>

在第二種情況下,將使用預定義的領域“證書”。 使用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>

但這也無濟於事。 我在日志中收到以下警告:“證書身份驗證需要證書領域。” Googling告訴我,使用的領域必須是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控制對資源的訪問仍然是一個有效的問題。 但是我不急於得到答案。

我遇到了同樣的問題,並通過以下鏈接解決了此問題: 此處

只需使用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將是為所有成功使用有效證書登錄的用戶動態創建的組。

將組名標簽和值替換為主體標簽和值,並作為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>

無需在web.xml中添加主體。 您可以在Servlet中檢入連接了哪個證書后,可以使用以下方法檢索它:

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

並使用以下方法檢查DN部分:

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

希望對您有所幫助。謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM