Java 如何在WebSphere上为远程EJB调用启用Kerberos身份验证?

Java 如何在WebSphere上为远程EJB调用启用Kerberos身份验证?,java,jakarta-ee,ejb,websphere,kerberos,Java,Jakarta Ee,Ejb,Websphere,Kerberos,我的应用程序是一个独立的Swing客户端,通过经典的JNDI查找和RMI-IIOP方法调用调用EJB无状态会话bean。它是作为一个JavaWebStart应用程序启动的。我的目标是使用getCallerPrincipal方法从EJBContext检索客户端用户的身份,这要归功于运行在Linux上的Windows工作站、ActiveDirectory和WebSphere服务器之间的Kerberos SSO 我已经在NetworkDeployment模式下成功地配置了WebSphere单元,以支持

我的应用程序是一个独立的Swing客户端,通过经典的JNDI查找和RMI-IIOP方法调用调用EJB无状态会话bean。它是作为一个JavaWebStart应用程序启动的。我的目标是使用
getCallerPrincipal
方法从
EJBContext
检索客户端用户的身份,这要归功于运行在Linux上的Windows工作站、ActiveDirectory和WebSphere服务器之间的Kerberos SSO

我已经在NetworkDeployment模式下成功地配置了WebSphere单元,以支持Kerberos身份验证

krb5.conf
krb5.keytab
文件都是正常的,并且在Linux
kinit
klist
wsadmin
$AdminTask validateKrbConfig
上都进行了测试

仅引用JAAS
login.config
文件以启用with command system属性。我的直觉告诉我这可能还不够

但是现在,我找不到更多的信息来完成测试用例:

  • 必须如何设置JNDI初始上下文环境以触发Kerberos协商
  • 服务器端是否有其他要求,比如用角色保护我的EJB(例如JBoss不需要)
更新

由于没有使用
/launchClient
运行JavaEE客户端容器,我在JNLP中设置了读取
sas.client.props
和JAAS登录配置所需的属性:

<property name="java.security.auth.login.config" value="C:\temp\wsjaas_client.config"/>
<property name="com.ibm.CORBA.ConfigURL" value="C:\temp\sas.client.props"/>
我的
sas.client.props包含:

WSKRB5Login{
    com.sun.security.auth.module.Krb5LoginModule required
       debug=true useTicketCache=true doNotPrompt=true;
};
com.ibm.CORBA.securityEnabled=true
com.ibm.CORBA.authenticationTarget=KRB5
com.ibm.CORBA.loginSource=krb5Ccache
com.ibm.CORBA.loginUserid=
com.ibm.CORBA.loginPassword=
com.ibm.CORBA.krb5CcacheFile=
com.ibm.CORBA.krb5ConfigFile=C:\\temp\\krb5.conf
目前,未触发Kerberos身份验证:在我的Kerberos缓存(来自Windows或Linux工作站)中没有SPN
WAS/myserver.mydomain.com
的TGS,JNDI连接仍以匿名方式建立

没有错误消息,没有警告,最后没有主体。我如何诊断出哪里有问题或缺少什么

更新2012/06/20

以下是一些前进的步骤。在使用Oracle Java运行的应用程序JNLP中,我设置了以下属性以使用IBM ORB并启用完整跟踪和调试信息:

<property name="org.omg.CORBA.ORBSingletonClass" value="com.ibm.rmi.corba.ORBSingleton"/>
<property name="org.omg.CORBA.ORBClass" value="com.ibm.CORBA.iiop.ORB"/>
<property name="traceSettingsFile" value="C:\temp\TraceSettings.properties"/>

即使在阅读了本文的大部分内容后,我仍然无法从客户端获得CSIv2触发器Kerberos身份验证。

由于您在随后的步骤中没有特别提到,您是否已按照提供的客户端设置链接配置了sas.client.props

您可以查看红皮书,了解如何进行此配置的示例,以及应用程序客户端的剩余配置

第13.5节(13.5配置Java EE应用程序客户端)给出了设置厚客户端运行时的示例,包括sas.client.props文件。

根据指南,在调用JNDI上下文之前,必须对Kerberos进行身份验证。执行Kerberos配置后,请按如下方式配置初始上下文:

  • 创建初始上下文时,将context.SECURITY\u AUTHENTICATION(在API参考文档中)环境属性设置为字符串“GSSAPI”
我过去曾处理过让Java客户机使用Kerberos的问题(尽管没有使用JNDI)。以下是我在客户端消除JVM选项和本地配置文件需求的方法(在客户端尝试进行身份验证之前调用此代码):

publicstaticvoid initKerberosConfig()
{                 
System.setProperty(“javax.security.auth.UseSubjectCredOnly”、“false”);
setProperty(“java.security.krb5.kdc”,“host.name:88”);
setProperty(“java.security.krb5.realm”、“realm”);
System.setProperty(“sun.security.krb5.debug”、“false”);
配置progConfig=getProgrammaticLoginConfig();
setConfiguration(progConfig);
} 
私有静态配置GetProgrammaticLoginConFig()
{ 
HashMap选项=新建HashMap();
期权。看跌期权(“useTicketCache”、“true”);
期权。看跌期权(“不提示”、“真实”);
AppConfigurationEntry krb5LoginModule=新的AppConfigurationEntry(“com.sun.security.auth.module.krb5LoginModule”,LoginModule控制标志.REQUIRED,选项);
最终AppConfigurationEntry[]aces=新AppConfigurationEntry[]{krb5LoginModule};
配置progConfig=新配置()
{ 
@凌驾
公共AppConfigurationEntry[]getAppConfigurationEntry(字符串arg0)
{                                 
返回A;
} 
}; 
返回progConfig;
} 

您可能需要根据您的上下文对其进行调整(
java.security.krb5.kdc
java.security.krb5.realm
将不正确)-但我希望它能有所帮助。打开
sun.security.krb5.debug
true
查看大量日志记录

总结一下上下文:我们的部署是在IBM WebSphere在Linux上运行多年后开始生产的,而应用程序的部署要感谢Java WebStart在Sun JavaSE 6上运行,包括IBM ORB,并配置为无需任何身份验证即可连接。现在,我们希望通过RMI-IIOP启用Kerberos身份验证和单点登录,这是WebSphere6(我认为)以来支持的

下面是一些答案

自WebSphere7以来,引入了一个新概念来在每台服务器的基础上配置安全方面:安全域。从理论上讲,在安全域中未更改的任何选项都将从全局安全部分继承

在测试Kerberos设置时,我们为测试服务器创建了一个专用的安全域,以避免计算单元中运行的其他服务器出现问题

但是即使在全局安全中启用了Kerberos,对于配置了自己的securit的服务器,它也不会被继承/启用
traceFileName=c:\\temp\\traces.log
ORBRas=all=enabled
SASRas=all=enabled
com.ibm.*=all=enabled
public static void initKerberosConfig() 
{                 
        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); 
        System.setProperty("java.security.krb5.kdc", "host.name:88"); 
        System.setProperty("java.security.krb5.realm", "REALM"); 
        System.setProperty("sun.security.krb5.debug", "false");                                 
        Configuration progConfig = getProgramaticLoginConfig(); 
        Configuration.setConfiguration(progConfig); 
} 

private static Configuration getProgramaticLoginConfig() 
{ 
        HashMap<String, String> options = new HashMap<String, String>(); 
        options.put("useTicketCache", "true"); 
        options.put("doNotPrompt", "true");                                                 
        AppConfigurationEntry krb5LoginModule = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", LoginModuleControlFlag.REQUIRED, options); 
        final AppConfigurationEntry[] aces = new AppConfigurationEntry[]{krb5LoginModule}; 
        Configuration progConfig = new Configuration() 
        { 
                @Override 
                public AppConfigurationEntry[] getAppConfigurationEntry(String arg0) 
                {                                 
                        return aces; 
                } 

        }; 
        return progConfig; 
}