2015-12-16 19 views
5

Tôi đang làm việc một ứng dụng web với SSO dựa trên đăng nhập tên miền Windows, cho mục đích này tôi đã chọn để xác nhận vé Kerberos. Nhưng bây giờ tôi đang đối mặt với một vấn đề mà tôi không thể tìm thấy một giải pháp. Tôi quản lý để xác nhận một vé mà không có ngoại lệ, nhưng khi tôi đang cố gắng để có được userName, NullPointerException được ném, bởi vì tên người dùng là null và tôi không biết vấn đề ở đâu.GSSContext with null SrcName

Tại sao tên người dùng lại trống nếu tôi không nhận được bất kỳ ngoại lệ nào trong quá trình xác thực?

Làm thế nào tôi có được userName: String clientName = gssContext.getSrcName().toString();

tôi tạo khách hàng của tôi dựa trên này:

Using GSSManager to validate a Kerberos ticket

How to obtain a kerberos service ticket via GSS-API?

http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/single-signon.html

Cập nhật 1:

Làm thế nào tôi thiết lập nội dung, chỉ cần sao chép-dán mẫu ở đây https://stackoverflow.com/a/25450862/1646082:

final Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); 

GSSManager gssmgr = GSSManager.getInstance(); 

// tell the GSSManager the Kerberos name of the service 
GSSName serviceName = gssmgr.createName(this.servicePrincipal, GSSName.NT_USER_NAME); 

// get the service's credentials. note that this run() method was called by Subject.doAs(), 
// so the service's credentials (Service Principal Name and password) are already 
// available in the Subject 
GSSCredential serviceCredentials = gssmgr.createCredential(serviceName, 
     GSSCredential.INDEFINITE_LIFETIME, spnegoOid, GSSCredential.ACCEPT_ONLY); 

// create a security context for decrypting the service ticket 
GSSContext gssContext = gssmgr.createContext(serviceCredentials); 

// decrypt the service ticket 
System.out.println("Entering accpetSecContext..."); 
System.out.println(new String (Base64.encodeBase64(gssContext.acceptSecContext(this.kerberosTicket, 0, 
     this.kerberosTicket.length)))); 

// get the client name from the decrypted service ticket 
// note that Active Directory created the service ticket, so we can trust it 
String clientName = gssContext.getSrcName().toString(); 

Cập nhật 2:

Nếu tôi an ninh thiết lập mùa xuân dựa trên https://spring.io/blog/2009/09/28/spring-security-kerberos-spnego-extension này tôi cũng đã giống nhau lỗi:

java.lang.NullPointerException at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136) at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:125) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422)

private static class KerberosValidateAction implements PrivilegedExceptionAction<String> { 
    byte[] kerberosTicket; 

    public KerberosValidateAction(byte[] kerberosTicket) { 
     this.kerberosTicket = kerberosTicket; 
    } 

    @Override 
    public String run() throws Exception { 
     GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null); 
     context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length); 
     String user = context.getSrcName().toString(); // ERROR! 
     context.dispose(); 
     return user; 
    } 

} 

Cập nhật 3:

Cũng đã cố gắng thay đổi phiên bản Java 1,8-1,7 như đề xuất ở đây Domain authentication with Kerberos fails. Không kết quả.

Cập nhật 4:

Trước hết. Không sử dụng Java 1.8 b40 và b45, cả hai đều bị hỏng. Và không kiểm tra nó trên máy tính địa phương, nó không hoạt động (tôi không biết tại sao).

Sau khi thay đổi phiên bản Java mới nhất (b65), tôi có ngoại lệ về việc đăng ký (Không thể tìm thấy khóa thích hợp để giải mã AP REP - AES256 ...). Này, tôi đã cố định bởi Java Cryptography Extension (JCE) cho Java 1.8 và tái tạo keytab với /crypto AES256-SHA1 sau khi tất cả điều này tôi đã nhận ngoại lệ:

GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed) at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source) at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) at GssServer$GssServerAction.run(GssServer.java:159) ... 4 more Caused by: KrbException: Checksum failed at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) at sun.security.krb5.EncryptedData.decrypt(Unknown Source) at sun.security.krb5.KrbApReq.authenticate(Unknown Source) at sun.security.krb5.KrbApReq.(Unknown Source) at sun.security.jgss.krb5.InitSecContextToken.(Unknown Source) ... 8 more Caused by: java.security.GeneralSecurityException: Checksum failed at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(Unknown Source) at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(Unknown Source) ... 14 more

tôi đã cố gắng this tutorial và cách nào khác để tạo keytabfile, nhưng tôi vẫn don' t có giải pháp.

+0

Xin vui lòng, hiển thị mã bạn sử dụng để thiết lập bối cảnh –

+1

Tôi biết đây là một chủ đề cũ nhưng gần đây tôi đã có vấn đề chính xác cùng và trong trường hợp của tôi đó là một vấn đề với các spn. Tôi đã gọi dịch vụ của mình và sau đó nhập 'klist' vào cmd để tìm kiếm dịch vụ của tôi. sau khi tôi tìm thấy nó, tôi thấy một cái gì đó như thế này: HTTP/[email protected] Những gì bạn phải làm là xác minh rằng một SPN cho điều này được tạo ra. Tạo một tài khoản dịch vụ và tạo spn với 'setspn -a HTTP/service.domain.com domain \ serviceAccout' và sau đó tạo một keytab với' ktab -k FILE: your_filename.ktab -a miền HTTP/service.domain.com \ password_of_service_account'. – Nico

Trả lời

1

Dường như ngữ cảnh không được thiết lập đầy đủ khi bạn đang cố gắng lấy SrcName. Nó có vẻ là lý do ScrName được null. Theo https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.security.api.doc/jgss/org/ietf/jgss/GSSContext.html, acceptSecContext() tạo ra một mã thông báo và nếu nó không phải là null, mã thông báo này sẽ được gửi đến peer. Sau cuộc gọi acceptSecContext(), bạn nên kiểm tra nếu isEstablished() trả về false.Nếu đó là như vậy,

If this method returns false it indicates that a token is needed from its peer in order to continue the context establishment phase. A return value of true signals that the local end of the context is established. This may still require that a token be sent to the peer, if one is produced by GSS-API. During the context establishment phase, the isProtReady() method may be called to determine if the context can be used for the per-message operations. This allows applications to use per-message operations on contexts which aren't fully established.

Cùng được giải thích chi tiết hơn trong hướng dẫn http://www.cs.mun.ca/java-api-1.5/guide/security/jgss/tutorials/BasicClientServer.html:

The acceptSecContext method may in turn return a token. If it does, the acceptor should send that token to the initiator, which should then call initSecContext again and pass it this token. Each time initSecContext or acceptSecContext returns a token, the application that called the method should send the token to its peer and that peer should pass the token to its appropriate method (acceptSecContext or initSecContext). This continues until the context is fully established (which is the case when the context's isEstablished method returns true).

+1

Thật không may, nó không giúp được gì. – Vartlok

1

tôi phải đối mặt với cùng một lỗi Checksum failed khi thực hiện bản demo ổ cắm GSSAPI của tôi đó là một biến thể của Oracle GSSAPI tutorial mã. Tôi đã thực thi mã của mình trên máy Linux được đăng ký vào một lĩnh vực Kerberos FreeIPA. Tôi đã sử dụng tệp vani krb5.conf của hệ thống Linux của mình. Không có ràng buộc nào trên vé etype có:

... 
[libdefaults] 
    default_realm = AUTHDEMO.IT 
    dns_lookup_realm = true 
    dns_lookup_kdc = true 
    rdns = false 
    ticket_lifetime = 24h 
    forwardable = true 
    udp_preference_limit = 0 
... 

Mặc định FreeIPA mặc định là sử dụng loại vé 18 (AES-256).

Về ứng dụng của tôi, nó có tập tin chính sách này cấu hình:

grant CodeBase "file:./app.jar" { 
     permission java.security.AllPermission; 
}; 

grant CodeBase "file:./app.jar" 
    Principal javax.security.auth.kerberos.KerberosPrincipal 
     "[email protected]" { 

    permission java.net.SocketPermission "*", "accept"; 

    permission javax.security.auth.kerberos.ServicePermission 
     "[email protected]", "accept"; 
}; 

Khi thực hiện ứng dụng tôi đã nhận lỗi này ở phía bên chấp nhận:

GSSException: Failure unspecified at GSS-API level (Mechanism level: Encryption type AES256CTS mode with HMAC SHA1-96 is not supported/enabled)

Trong trường hợp của tôi lỗi phát sinh trong Bên nhận GSS. Trong ứng dụng của tôi, tôi tạo cấu hình Jaas theo lập trình (tôi sẽ tham khảo tại đây là DConfig) và tôi không sử dụng tệp cấu hình. Giải pháp đầu tiên, tôi thấy, là sử dụng tập tin cấu hình thay vì DConfig và vấn đề biến mất, nó hoạt động tốt. Các giải pháp tạm thời, JAAS Config file:

DemoServer { 
    com.sun.security.auth.module.Krb5LoginModule required 
    principal="[email protected]" 
    storeKey=true 
    debug=true; #not mandatory 
}; 

Với cấu hình này, không có vấn đề xuất phát từ phía chấp nhận và ứng dụng có thể kiểm tra tính hợp lệ vé dịch vụ và chấp nhận các kết nối.

Tôi tự hỏi mình .. TẠI SAO?

Tôi đã kiểm tra sự khác biệt trong (các) Chủ đề có được với hai cấu hình. Trong trường hợp làm việc, với tệp cấu hình, chủ đề chứa, trong các thông tin cá nhân, cả thông tin đăng nhập mật khẩu và thẻ TGT chính. Với DConfig, tôi nhận được một Chủ đề chỉ có băm mật khẩu nhưng không có vé TGT chính trong thông tin đăng nhập cá nhân.

sửa chữa của tôi

DConfig chứa các thiết lập tương tự của tập tin cấu hình và các tùy chọn khác là bản sao của Krb5LoginModule giá trị mặc định, lúc đầu tôi không thể nhìn thấy một lý do cho hành vi sai trái.

Đặt isInitiator = true, vào DConfig bên chấp nhận, đã giải quyết được sự cố. `isInitiator = true đã buộc sự tồn tại của vé TGT vào đối tượng.

Với giải pháp này, lỗi đã biến mất mà không có thay đổi trong krb5.conf hệ thống.

Xu của tôi là ... sau khi đăng nhập Jaas, hãy kiểm tra thông tin cá nhân của chủ thể của bạn vì thiếu tín dụng (Bạn cần TGT chính của dịch vụ vào chủ thể chấp nhận!) Và trong trường hợp cố gắng đặt isInitiator = true cho bên chấp nhận.

Trân