如何配置JBoss EAP 6.3 WebApp以进行Kerberos身份验证

时间:2015-03-17 16:08:30

标签: java jboss windows-server-2008 kerberos ntlm

我需要配置JBoss EAP 6.3来理解Kerberos身份验证。

我的环境包括:

  • 使用JBoss EAP 6.3的Linux服务器
  • 使用Windows 7 64位+ Chrome
  • 的客户端工作站
  • Windows Server 2008 Active Directory(充当KDC)

我已经尝试了很多例子,但没有一个能够奏效。基本上我按照这个文件做了一切: RedHat JBoss 6.3 Kerberos

和本文件: JBoss blog RadoslawRodak

和本文件: JBoss developer blog

我从测试servlet(jboss-negotiation-toolkit)获得的所有内容都是这样的消息: WARN [org.jboss.security.auth.spi.AbstractServerLoginModule](http- / 172.27.185.220:8080-1)不支持的谈判机制' NTLM'

有没有人全力以赴并以某种方式解决了这个问题?

提前感谢Josef

2 个答案:

答案 0 :(得分:1)

查看我的SPNEGO演示项目https://github.com/kwart/spnego-demo

尝试使用链接的kerberos-using-apacheds项目。

如果您可以成功对ApacheDS Kerberos进行身份验证,请尝试更改krb5.conf安全域中的Krb5LoginModulehost选项)以使用Active Directory进行身份验证。

常见的陷阱是错误的 SPN名称。服务主体必须采用 HTTP/hostname@REALM 格式(例如HTTP/www.my-company.com@MY-COMPANY.COM

您可以在我的旧演示文稿中找到其他一些提示 - http://www.slideshare.net/josef.cacek/dev-conf2013-ltkerberosas7

答案 1 :(得分:1)

谢谢大家。正如我之前所说,我们终于做到了。我们的解决方案是:

0)客户端计算机必须在域中,提供域凭据    还不够。

创建密钥表(对于2008服务器是关键的kvno 0):

ktpass -out bbb.keytab -princ HTTP/bbb.cez.loc@CEZ.LOC -mapUser CEZ.LOC\bbb -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 config(standalone.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 App配置:

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服务器地址添加到可信主机,进入Intranet部分下的Internet设置。从那时起,一切都有效。

Rest Web App可以使用它来获取有效的凭据:

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();
        }
    }
}