gpt4 book ai didi

java - Java8 中的 Kerberos/SPNEGO 服务器端身份验证更改

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:25:39 26 4
gpt4 key购买 nike

我正在尝试将应用程序从使用 java7u51 更改为 java8u40,但 SSO 身份验证失败。客户端未更改,它使用 JNA 窗口调用 (Secur32.INSTANCE.InitializeSecurityContext),但服务器不再接受票证。服务器代码没有改变,但它使用的是似乎已经改变的标准 java 库。服务器在linux下运行。

服务器代码如下。在我的 Windows 机器上,我编写了一个包含票证的文件,以便我可以运行下面的代码进行测试。我有一个非常高的时钟偏移设置,这样我就可以根据票证进行测试。为了以防万一,我已经使用 java7u51 编写了客户端票证,但这并没有帮助。当我在 java7 中运行以下服务器代码时,同一张票正常工作。

失败的一点是 isEstablished 返回 false。没有有用的调试信息。 isEstablished 返回 false 意味着需要更多回合,但过去并非如此,我认为不应该如此。

有谁知道这在 java8 中现在会失败的原因吗?这不仅仅是一个更新 40 问题,它在早期的 Java 8 版本中失败。

谢谢

Properties.setProp("sun.security.krb5.debug", "true")
Properties.setProp("java.security.krb5.realm", "xxxx")
Properties.setProp("java.security.krb5.kdc", "xxxx")
Properties.setProp("java.security.krb5.conf", url(getClass, "/krb5.conf.auth").toExternalForm)
Properties.setProp("java.security.auth.login.config", url(getClass, "/jaas.conf.auth").toExternalForm)
Properties.setProp("javax.security.auth.useSubjectCredsOnly", "true")

val loginCtx: LoginContext = new LoginContext("Server", new LoginCallbackHandler(password))
loginCtx.login()
val subject = loginCtx.getSubject
val ticket = StringIO.readStringFromFile(new File("/tmp/ticket"))
val decoder: BASE64Decoder = new BASE64Decoder
val serviceTicket = decoder.decodeBuffer(ticket)

val user = Subject.doAs(subject, new PrivilegedAction[Option[String]]() {
def run = {
try {
val manager = GSSManager.getInstance
val context: GSSContext = manager.createContext(null: GSSCredential)
val arrayOfBytes = context.acceptSecContext(serviceTicket, 0, serviceTicket.length)
// we ignore arrayOfBytes
assert(context.isEstablished, "Failed to establish context: " + context)
val username = context.getSrcName.toString
Some(username)
} catch {
case e: Exception =>
println("failed: " + e.getMessage)
None
}
}
})

krb5.conf.auth
[libdefaults]
default_realm = XXX
allow_weak_crypto=true
default_tkt_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
default_tgs_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
permitted_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
default_checksum = rsa-md5
kdc_timesync = 0
kdc_default_options = 0x40000010
clockskew = 30000
check_delegate = 0
ccache_type = 3
kdc_timeout = 60000
forwardable = true
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h

#excluding realms and domain_realm

jaas.conf.auth (server section)

Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
debug=true
isInitiator=false
storeKey=true
useTicketCache=false
principal="XXX";
};

更新:以防万一。我认为客户端正在发送 SPNEGO 票证,因为如果我尝试强制上下文仅接受 Kerberos(1.2.840.113554.1.2.2),我会收到错误 failed: No credential found for: 1.3.6.1.5.5 .2 用法:接受

更新 2:这并不是真正的答案,但如果我改变 Windows 客户端创建票证的方式,它就会起作用。因此,如果不是创建 SPNEGO 包装票证,而是创建 Kerberos only 票证,它会被 Java8 接受。因此,将下面的“协商”更改为“Kerberos”可以解决问题。

Secur32.INSTANCE.AcquireCredentialsHandle(
servicePrincipalName,
"Negotiate", // Change to "Kerberos"
new NativeLong(Sspi.SECPKG_CRED_OUTBOUND),
null,
authIdentity.getPointer,
null,
null,
phClientCredential,
ptsClientExpiry)

最佳答案

Kerberos/SPNEGO 是一个垃圾域..

根据我的想法,下面是一个快速检查列表,希望对您有所帮助。

  1. 你重新生成你的 key 表了吗?使用您在服务器端使用的相同 JDK?
  2. 您的服务器是否在正确的用户(在您的 key 选项卡中定义)下运行?
  3. 您是否选择了“永不过期”选项来生成它们?
  4. 您需要 256 位加密吗?可以看到打字(key type 18 = AES-256):

    %JAVA_HOME%\bin\klist -e -f -a -k XX.keytab

    %JAVA_HOME%\bin\klist -e -f -a -k XX.keytab]

    如果是这样,您是否添加了 unrestricted policy files local_policy.jarUS_export_policy.jar 在 %JAVA_HOME%\jre\lib\security 下?确保 KVNO 值与您获得的列表中的值相同。理想情况下,您应该只看到一个输出。

  5. 您的 SPN 是否可 ping 通?

  6. 您的 KDC 服务器列表是否正确?
  7. 注意 krb5.conf。有问题。即使在 Windows 环境中似乎也是区分大小写的。

Kerberos 可能很难设置。祝你好运。

关于java - Java8 中的 Kerberos/SPNEGO 服务器端身份验证更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28898333/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com