Tôi đang cố gắng thay đổi một ứng dụng từ việc sử dụng java7u51 sang java8u40 nhưng xác thực SSO không thành công. Khách hàng không thay đổi, nó sử dụng các cuộc gọi Windows JNA (Secur32.INSTANCE.InitializeSecurityContext
) nhưng máy chủ không còn chấp nhận vé nữa. Mã máy chủ không thay đổi nhưng nó đang sử dụng các thư viện java chuẩn dường như đã thay đổi. Máy chủ chạy dưới Linux.Thay đổi xác thực phía máy chủ Kerberos/SPNEGO trong Java8
Mã máy chủ bên dưới. Trên máy tính cửa sổ của tôi, tôi viết một tệp chứa vé để tôi có thể chạy mã bên dưới để thử nghiệm. Tôi có một bộ đồng hồ rất cao để tôi có thể kiểm tra vé. Tôi đã viết các khách hàng vé bằng cách sử dụng java7u51 chỉ trong trường hợp nhưng điều đó đã không giúp đỡ. Cùng một vé hoạt động tốt khi tôi chạy mã máy chủ dưới đây trong java7.
Lỗi không thành công là isEstablished
trả về giá trị sai. Không có thông tin gỡ lỗi hữu ích. isEstablished
trả về false ngụ ý rằng có nhiều vòng cần thiết hơn nhưng đó không phải là trường hợp, và tôi không nghĩ rằng nó nên được.
Có ai biết lý do điều này hiện không thành công trong java8 không? Nó không chỉ là một vấn đề cập nhật 40, nó không thành công với phiên bản java 8 trước đó.
nhờ
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";
};
Cập nhật: Trong trường hợp này giúp. Tôi nghĩ rằng khách hàng đang gửi một vé SPNEGO, bởi vì nếu tôi cố gắng buộc bối cảnh chỉ chấp nhận Kerberos (1.2.840.113554.1.2.2) tôi nhận được lỗi failed: No credential found for: 1.3.6.1.5.5.2 usage: Accept
Cập nhật 2: Đây không thực sự là câu trả lời , nhưng nếu tôi thay đổi cách cửa sổ máy khách tạo ra vé nó hoạt động. Vì vậy, nếu thay vì tạo ra một vé SPNEGO bọc bạn tạo một vé chỉ Kerberos nó được chấp nhận bởi Java8. Vì vậy, việc thay đổi "Thương lượng" thành "Kerberos" bên dưới sẽ khắc phục được sự cố.
Secur32.INSTANCE.AcquireCredentialsHandle(
servicePrincipalName,
"Negotiate", // Change to "Kerberos"
new NativeLong(Sspi.SECPKG_CRED_OUTBOUND),
null,
authIdentity.getPointer,
null,
null,
phClientCredential,
ptsClientExpiry)
Hãy thử sử dụng "NTLM" thay vì "Thương lượng" và cho tôi biết liệu nó có hoạt động hay không. Tôi đã có vấn đề tương tự. – kukis
Có phải java8 có thể thả hỗ trợ cho 'allow_weak_crypto = true' không? –
Java 8 đã thay đổi mặc định cho allow_weak_crypto thành false, vì vậy bạn không thể sử dụng DES trừ khi được chỉ định rõ ràng là đúng: https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8 .html –