我需要配置 JBoss EAP 6.3 来理解 Kerberos 身份验证。
我的环境包括:
- Linux Server with JBoss EAP 6.3
- 客户端工作站与视窗 7 64 位 + 铬
- Windows Server 2008 Active Directory (充当 KDC)
我已经尝试了很多例子,但没有一个有效。基本上我根据此文档做了所有操作:红帽 JBoss 6.3 Kerberos
和这个文档:JBoss 博客 RadoslawRodak
和这个文档:JBoss 开发者博客
我从测试 servlet(jboss-negotiation-toolkit)中得到的所有内容都是这样的消息:WARN [org.jboss.security.auth.spi.AbstractServerLoginModule] (http-/172.27.185.220:8080-1) 不支持的协商机制"NTLM"
有没有人经历过这一切并以某种方式解决了它?
提前谢谢你,约瑟夫
看看我的 SPNEGO 演示项目 https://github.com/kwart/spnego-demo
尝试使其与链接的 kerberos-using-apacheds 项目一起工作。
如果可以成功对 ApacheDS Kerberos 进行身份验证,请尝试更改配置(krb5.conf
和host
安全域中的Krb5LoginModule
选项)以使用 Active Directory 进行身份验证。
常见的陷阱是错误的 SPN 名称。服务主体必须采用形式HTTP/hostname@REALM
(例如 HTTP/www.my-company.com@MY-COMPANY.COM
)
您可以在我的旧演示文稿中找到其他一些提示 - http://www.slideshare.net/josef.cacek/dev-conf2013-ltkerberosas7
谢谢大家。正如我之前所说,我们终于成功了。我们的解决方案是:
0) 客户端计算机必须位于域中,并提供域凭据 还不够。
创建密钥表(对于 2008 服务器是关键 kvno 0):
ktpass -out bbb.keytab -princ HTTP/bbb.cez.loc@CEZ.LOC -mapUser CEZ.LOCbbb -mapOp set -pass password -ptype KRB5_NT_PRINCIPAL -kvno 0
ktab -k bbb.keytab -l -e -t
Keytab name: bbb.keytab
KVNO Timestamp Principal
0 1/1/70 1:00 AM HTTP/bbb.cez.loc@CEZ.LOC (23:RC4 with HMAC)
停止 JBoss 并将其传输到 JBoss 配置文件夹下的 linux。 /opt/jboss-domain/standalone/configuration/bbb.keytab
1) JBoss 配置(单机.xml)
<system-properties>
<property name="java.security.krb5.kdc" value="CEZ.LOC"/>
<property name="java.security.krb5.realm" value="CEZ.LOC"/>
<property name="java.net.debug" value="all"/>
<property name="sun.security.krb5.debug" value="true"/>
</system-properties>
<security-domain name="host" cache-type="default">
<authentication>
<login-module code="Kerberos" flag="required">
<module-option name="storeKey" value="true"/>
<module-option name="useKeyTab" value="true"/>
<module-option name="principal" value="HTTP/bbb.cez.loc@CEZ.LOC"/>
<module-option name="keyTab" value="/opt/jboss-domain/standalone/configuration/bbb.keytab"/>
<module-option name="doNotPrompt" value="true"/>
<module-option name="debug" value="true"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="SPNEGO" cache-type="default">
<authentication>
<login-module code="SPNEGO" flag="requisite">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="serverSecurityDomain" value="host"/>
</login-module>
</authentication>
</security-domain>
2) 网页应用配置:
web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted</web-resource-name>
<url-pattern>/rest/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-role>
<role-name>*</role-name>
</security-role>
jboss-web.xml:
<jboss-web>
<security-domain>java:/jaas/SPNEGO</security-domain>
<valve>
<class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name>
</valve>
<context-root>kerberoes</context-root>
</jboss-web>
jboss-deployment-structure.xml:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.jboss.security.negotiation" />
</dependencies>
</deployment>
</jboss-deployment-structure>
3) 在 AD 上重新启动密钥分发服务
4) 启动 JBoss
5) 将 JBoss Web 服务器地址添加到受信任主机的互联网设置中 内网 部分。从那一刻开始,一切都在起作用。
Rest Web 应用可以使用此功能获取有效凭据:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
@Path("/ping")
public class Ping extends Application
{
@Context
private SecurityContext mySecurityContext;
@GET
public Response doGET()
{
try
{
Date now = Calendar.getInstance().getTime();
String reportDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(now);
String returnString = "";
// return ok json
returnString = "Time: " + reportDate + "<br>n";
returnString += "User: " +
mySecurityContext.getAuthenticationScheme() + " / " +
mySecurityContext.getUserPrincipal().getName() + "<br>n";
return Response.status(200).entity(returnString).build();
}
catch (Exception e)
{
return Response.status(500).entity("Exception! " +
e.getMessage()).build();
}
}
}