KrbException:S4U2self 需要一张可转发的票
KrbException: S4U2self needs a FORWARDABLE ticket
我正在尝试通过我的 java 代码执行 kerberos 约束委派。
我有一个密钥表文件、附加到用户的 SPN,以及为该用户启用的 SPN 委派。
当我尝试使用 Keytab 登录时,我得到了 SPN 的 TGT。但是,"forwardable" 标志在此票证上设置为 false。
为了冒充其他用户,我需要将此标志设置为 true。
注意:ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 标志在 SPN 用户上设置。
非常感谢任何帮助。
private void tryKrb5Module() throws LoginException {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","true");//has no impact
final Subject subject = new Subject();
final Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
final Map<String,String> optionMap = new HashMap<String,String>();
optionMap.put("keyTab", "c:\ticket\delegationUser.keytab");
optionMap.put("principal", "TEST/TEST"); // default realm
optionMap.put("doNotPrompt", "true");
optionMap.put("refreshKrb5Config", "true");
optionMap.put("useTicketCache", "true");
optionMap.put("renewTGT", "true");
optionMap.put("useKeyTab", "true");
optionMap.put("storeKey", "true");
optionMap.put("isInitiator", "true");
krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap);
boolean loginOk = krb5LoginModule.login();
System.out.println("======= login: " + loginOk);
boolean commitOk = krb5LoginModule.commit();
System.out.println("======= commit: " + commitOk);
System.out.println("======= Principal from subject: " + subject.getPrincipals());
}
我想出了解决办法。您需要在系统路径中设置 krb 配置文件。那么只有从keytab得到的ticket是"forwardaable"。
令人惊讶的是,这在任何地方都没有明确提及。
System.setProperty("java.security.krb5.conf", "path_to_krb_config");
还要确保您在 krb 配置文件中提到了 "forwardable = true"。
在下面粘贴示例 krb 配置文件:
[libdefaults]
default_realm = DOMAIN.COM
default_tkt_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
default_tgs_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
permitted_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
dns_lookup_kdc = true
dns_lookup_realm = false
forwardable = true
[realms]
DOMAIN.COM = {
kdc = KDC_HOST.DOMAIN.COM
admin_server = KDC_HOST.DOMAIN.COM
default_domain = DOMAIN.COM
}
[domain_realms]
domain.com = DOMAIN.COM
.domain.com = DOMAIN.COM
服务帐户 "TEST" 及其密钥表仅用于与 KDC 建立 "trust" 并授予服务代码以调用方法 S4U2Self 和 S4U2Proxy。因此服务帐户 TGT 预计不可转发。
除了您为 Krb5LoginModule
创建的 Map
JAAS 登录配置之外,不需要 krb5.conf
文件。另一种选择是简单地添加 optionMap.put("forwardable", "true");
并且您的服务帐户 "TEST" TGT 将是可转发的。
顺便说一句,对于 kerberos 约束委托,仅要求使用 S4U2Self 生成的模拟用户票证 TGT 是可转发的,这仅取决于 "TEST" 服务帐户上的 ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
标志。 S4U2Self生成代码为:https://github.com/ymartin59/java-kerberos-sfudemo/blob/master/src/main/java/sfudemo/KerberosDemo.java#L120
参考文献:
我正在尝试通过我的 java 代码执行 kerberos 约束委派。 我有一个密钥表文件、附加到用户的 SPN,以及为该用户启用的 SPN 委派。 当我尝试使用 Keytab 登录时,我得到了 SPN 的 TGT。但是,"forwardable" 标志在此票证上设置为 false。
为了冒充其他用户,我需要将此标志设置为 true。
注意:ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 标志在 SPN 用户上设置。
非常感谢任何帮助。
private void tryKrb5Module() throws LoginException {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","true");//has no impact
final Subject subject = new Subject();
final Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
final Map<String,String> optionMap = new HashMap<String,String>();
optionMap.put("keyTab", "c:\ticket\delegationUser.keytab");
optionMap.put("principal", "TEST/TEST"); // default realm
optionMap.put("doNotPrompt", "true");
optionMap.put("refreshKrb5Config", "true");
optionMap.put("useTicketCache", "true");
optionMap.put("renewTGT", "true");
optionMap.put("useKeyTab", "true");
optionMap.put("storeKey", "true");
optionMap.put("isInitiator", "true");
krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap);
boolean loginOk = krb5LoginModule.login();
System.out.println("======= login: " + loginOk);
boolean commitOk = krb5LoginModule.commit();
System.out.println("======= commit: " + commitOk);
System.out.println("======= Principal from subject: " + subject.getPrincipals());
}
我想出了解决办法。您需要在系统路径中设置 krb 配置文件。那么只有从keytab得到的ticket是"forwardaable"。 令人惊讶的是,这在任何地方都没有明确提及。
System.setProperty("java.security.krb5.conf", "path_to_krb_config");
还要确保您在 krb 配置文件中提到了 "forwardable = true"。 在下面粘贴示例 krb 配置文件:
[libdefaults]
default_realm = DOMAIN.COM
default_tkt_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
default_tgs_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
permitted_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
dns_lookup_kdc = true
dns_lookup_realm = false
forwardable = true
[realms]
DOMAIN.COM = {
kdc = KDC_HOST.DOMAIN.COM
admin_server = KDC_HOST.DOMAIN.COM
default_domain = DOMAIN.COM
}
[domain_realms]
domain.com = DOMAIN.COM
.domain.com = DOMAIN.COM
服务帐户 "TEST" 及其密钥表仅用于与 KDC 建立 "trust" 并授予服务代码以调用方法 S4U2Self 和 S4U2Proxy。因此服务帐户 TGT 预计不可转发。
除了您为 Krb5LoginModule
创建的 Map
JAAS 登录配置之外,不需要 krb5.conf
文件。另一种选择是简单地添加 optionMap.put("forwardable", "true");
并且您的服务帐户 "TEST" TGT 将是可转发的。
顺便说一句,对于 kerberos 约束委托,仅要求使用 S4U2Self 生成的模拟用户票证 TGT 是可转发的,这仅取决于 "TEST" 服务帐户上的 ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
标志。 S4U2Self生成代码为:https://github.com/ymartin59/java-kerberos-sfudemo/blob/master/src/main/java/sfudemo/KerberosDemo.java#L120
参考文献: