[英]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.