用于远程处理的 Kerberos 身份验证集成
Kerberos Authentication Integration for Remoting
我在这里遵循这些说明:章节 3. Additional Features - Red Hat Customer Portal
具体来说,我正在尝试按照第 3.3 节让 Kerberos 与远程应用程序一起工作。
我的 standalone.xml 看起来像文档中的示例。我的服务主体、密钥表和用户工作,因为我可以按照 3.2 节并通过管理界面登录。
<security-realm name="krbRealm">
<server-identities>
<kerberos>
<keytab principal="remote/tmf-is3-sec.nsonet.com@NSONET.COM" path="tmfkrbrem.keytab" relative-to="jboss.server.config.dir" debug="true"/>
</kerberos>
</server-identities>
<authentication>
<kerberos remove-realm="true"/>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-domain name="krb-remoting-domain">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="realm" value="krbRealm"/>
</login-module>
</authentication>
<mapping>
<mapping-module code="SimpleRoles" type="role">
<module-option name="testuser" value="Users"/>
</mapping-module>
</mapping>
</security-domain>
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
<endpoint/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="krbRealm"/>
</subsystem>
我正在使用基于此处显示的客户端的示例客户端代码:[JBEAP-715] EJB authentication via Kerberos does not work with wildfly-security-api - JBoss Issue Tracker
// Remoting
Context context = null;
try {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.util.logging.manager", "java.util.logging.LogManager");
System.setProperty("java.util.logging.config.file", "logging.properties");
System.setProperty("java.util.logging.ConsoleHandler.level", "TRACE");
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://tmf-is3-sec.nsonet.com:8080");
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
props.put("remote.connection.main.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS","true");
props.put("remote.connection.main.connect.options.org.xnio.Options.SSL_ENABLED", "false");
props.put("remote.connection.main.connect.options.org.jboss.remoting3.RemotingOptions.SASL_PROTOCOL", "remote");
context = new InitialContext(props);
} catch (Exception e) {
e.printStackTrace();
}
tmfService tmfBean = (tmfService) context.lookup("tmf-app/com.mentor.tmf.bean//tmfBean!com.mentor.tmf.api.internal.tmfService");
tmfRequest req = new tmfRequest("First test");
req.print();
tmfResponse resp = tmfBean.firstOperation(req);
resp.print();
}
这是我的豆子:
@Stateless
@Remote(tmfService.class)
@SecurityDomain("krb-remoting-domain")
@RolesAllowed("Users")
public class tmfBean implements tmfService {
public tmfBean() {
// nothing here
}
@Override
public tmfResponse firstOperation(tmfRequest req) {
System.out.println("tmfBean gets request <" + req.getMyData() + ">\n");
tmfResponse rval = new tmfResponse(req.getMyData() + " MODIFIED");
return rval;
}
}
我在客户端收到这些错误:(登录成功)
Exception in thread "main" javax.naming.AuthenticationException: Failed to connect to any server. Servers tried: [http-remoting://tmf-is3-sec.nsonet.com:8080 (Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication)] [Root exception is javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:238)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:149)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:130)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:272)
at org.jboss.naming.remote.client.RemoteContext.lookupInternal(RemoteContext.java:104)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:93)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:146)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mentor.tmf.client.tmfTest.main(tmfTest.java:154)
Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
我在服务器上收到此错误:
08:06:12,851 INFO [stdout] (default I/O-1) Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is C:\wildfly-10.0.0.Final\standalone\configuration\tmfkrbrem.keytab refreshKrb5Config is false principal is remote/tmf-is3-sec.nsonet.com@NSONET.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
08:06:12,853 INFO [stdout] (default I/O-1) principal is remote/tmf-is3-sec.nsonet.com@NSONET.COM
08:06:12,853 INFO [stdout] (default I/O-1) Will use keytab
08:06:12,854 INFO [stdout] (default I/O-1) Commit Succeeded
08:06:12,854 INFO [stdout] (default I/O-1)
08:06:13,029 TRACE [org.jboss.remoting.remote.server] (default task-2) Server sending authentication rejected: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)]
at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(Unknown Source)
at org.jboss.sasl.gssapi.GssapiServer.run(GssapiServer.java:60)
at org.jboss.sasl.gssapi.GssapiServer.run(GssapiServer.java:56)
... 27 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
... 19 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128.decrypt(Unknown Source)
... 22 more
如有任何帮助,我们将不胜感激。我们找不到任何关于如何使用 Kerberos 验证客户端以访问 EJB 的文档。
谢谢,
-汤姆
我找到了解决方案。基本上,服务主体需要在同一个帐户的名称中同时包含 remoting/... 和 remote/..。
我在一个帐户中只有 "remote/...",在另一个测试帐户中只有 "remoting/..."。我删除了重复的测试帐户并将 "remoting/..." 添加到服务帐户。
C:>setspn -a remoting/tmf-is3-sec.nsonet.com tmfkrbrem
Registering ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com
remoting/tmf-is3-sec.nsonet.com
Updated object
结果应如下所示:
C:>setspn -l tmfkrbrem
Registered ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com:
remoting/tmf-is3-sec.nsonet.com
remote/tmf-is3-sec.nsonet.com
然后我创建了一个新的密钥表,但这可能不需要。
C:>ktpass -princ remote/tmf-is3-sec.nsonet.com@NSONET.COM -pass Test1234 -mapuser NSONET\tmfkrbrem -
ptype KRB5_NT_PRINCIPAL -crypto AES128-SHA1 -kvno 0 -out C:\Users\Administrator\Desktop\tmfkrbrem.keytab
Targeting domain controller: nso-dc.nsonet.com
Using legacy password setting method
Successfully mapped remote/tmf-is3-sec.nsonet.com to tmfkrbrem.
Key created.
Output keytab to C:\Users\Administrator\Desktop\tmfkrbrem.keytab:
Keytab version: 0x502
keysize 75 remote/tmf-is3-sec.nsonet.com@NSONET.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x11 (AES128-SHA1) keylength
16 (0x9477d8bdfbf874ae5ad0b24fd611fb30)
我在这里遵循这些说明:章节 3. Additional Features - Red Hat Customer Portal
具体来说,我正在尝试按照第 3.3 节让 Kerberos 与远程应用程序一起工作。
我的 standalone.xml 看起来像文档中的示例。我的服务主体、密钥表和用户工作,因为我可以按照 3.2 节并通过管理界面登录。
<security-realm name="krbRealm">
<server-identities>
<kerberos>
<keytab principal="remote/tmf-is3-sec.nsonet.com@NSONET.COM" path="tmfkrbrem.keytab" relative-to="jboss.server.config.dir" debug="true"/>
</kerberos>
</server-identities>
<authentication>
<kerberos remove-realm="true"/>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-domain name="krb-remoting-domain">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="realm" value="krbRealm"/>
</login-module>
</authentication>
<mapping>
<mapping-module code="SimpleRoles" type="role">
<module-option name="testuser" value="Users"/>
</mapping-module>
</mapping>
</security-domain>
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
<endpoint/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="krbRealm"/>
</subsystem>
我正在使用基于此处显示的客户端的示例客户端代码:[JBEAP-715] EJB authentication via Kerberos does not work with wildfly-security-api - JBoss Issue Tracker
// Remoting
Context context = null;
try {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.util.logging.manager", "java.util.logging.LogManager");
System.setProperty("java.util.logging.config.file", "logging.properties");
System.setProperty("java.util.logging.ConsoleHandler.level", "TRACE");
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://tmf-is3-sec.nsonet.com:8080");
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
props.put("remote.connection.main.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS","true");
props.put("remote.connection.main.connect.options.org.xnio.Options.SSL_ENABLED", "false");
props.put("remote.connection.main.connect.options.org.jboss.remoting3.RemotingOptions.SASL_PROTOCOL", "remote");
context = new InitialContext(props);
} catch (Exception e) {
e.printStackTrace();
}
tmfService tmfBean = (tmfService) context.lookup("tmf-app/com.mentor.tmf.bean//tmfBean!com.mentor.tmf.api.internal.tmfService");
tmfRequest req = new tmfRequest("First test");
req.print();
tmfResponse resp = tmfBean.firstOperation(req);
resp.print();
}
这是我的豆子:
@Stateless
@Remote(tmfService.class)
@SecurityDomain("krb-remoting-domain")
@RolesAllowed("Users")
public class tmfBean implements tmfService {
public tmfBean() {
// nothing here
}
@Override
public tmfResponse firstOperation(tmfRequest req) {
System.out.println("tmfBean gets request <" + req.getMyData() + ">\n");
tmfResponse rval = new tmfResponse(req.getMyData() + " MODIFIED");
return rval;
}
}
我在客户端收到这些错误:(登录成功)
Exception in thread "main" javax.naming.AuthenticationException: Failed to connect to any server. Servers tried: [http-remoting://tmf-is3-sec.nsonet.com:8080 (Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication)] [Root exception is javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:238)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:149)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:130)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:272)
at org.jboss.naming.remote.client.RemoteContext.lookupInternal(RemoteContext.java:104)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:93)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:146)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mentor.tmf.client.tmfTest.main(tmfTest.java:154)
Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
我在服务器上收到此错误:
08:06:12,851 INFO [stdout] (default I/O-1) Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is C:\wildfly-10.0.0.Final\standalone\configuration\tmfkrbrem.keytab refreshKrb5Config is false principal is remote/tmf-is3-sec.nsonet.com@NSONET.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
08:06:12,853 INFO [stdout] (default I/O-1) principal is remote/tmf-is3-sec.nsonet.com@NSONET.COM
08:06:12,853 INFO [stdout] (default I/O-1) Will use keytab
08:06:12,854 INFO [stdout] (default I/O-1) Commit Succeeded
08:06:12,854 INFO [stdout] (default I/O-1)
08:06:13,029 TRACE [org.jboss.remoting.remote.server] (default task-2) Server sending authentication rejected: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)]
at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(Unknown Source)
at org.jboss.sasl.gssapi.GssapiServer.run(GssapiServer.java:60)
at org.jboss.sasl.gssapi.GssapiServer.run(GssapiServer.java:56)
... 27 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
... 19 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128.decrypt(Unknown Source)
... 22 more
如有任何帮助,我们将不胜感激。我们找不到任何关于如何使用 Kerberos 验证客户端以访问 EJB 的文档。
谢谢, -汤姆
我找到了解决方案。基本上,服务主体需要在同一个帐户的名称中同时包含 remoting/... 和 remote/..。
我在一个帐户中只有 "remote/...",在另一个测试帐户中只有 "remoting/..."。我删除了重复的测试帐户并将 "remoting/..." 添加到服务帐户。
C:>setspn -a remoting/tmf-is3-sec.nsonet.com tmfkrbrem
Registering ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com
remoting/tmf-is3-sec.nsonet.com
Updated object
结果应如下所示:
C:>setspn -l tmfkrbrem
Registered ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com:
remoting/tmf-is3-sec.nsonet.com
remote/tmf-is3-sec.nsonet.com
然后我创建了一个新的密钥表,但这可能不需要。
C:>ktpass -princ remote/tmf-is3-sec.nsonet.com@NSONET.COM -pass Test1234 -mapuser NSONET\tmfkrbrem -
ptype KRB5_NT_PRINCIPAL -crypto AES128-SHA1 -kvno 0 -out C:\Users\Administrator\Desktop\tmfkrbrem.keytab
Targeting domain controller: nso-dc.nsonet.com
Using legacy password setting method
Successfully mapped remote/tmf-is3-sec.nsonet.com to tmfkrbrem.
Key created.
Output keytab to C:\Users\Administrator\Desktop\tmfkrbrem.keytab:
Keytab version: 0x502
keysize 75 remote/tmf-is3-sec.nsonet.com@NSONET.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x11 (AES128-SHA1) keylength
16 (0x9477d8bdfbf874ae5ad0b24fd611fb30)