2013-04-10 4 views
7

포리스트 구조의 LDAP (모든 서버와 서버가 창)로 작업하고 있습니다. 나는 NTLM 인증을 사용하여 광고에 바인딩하고있다.GSSException : 메시지 스트림이 수정 됨 (41)

LDAP 서버에 대해 작업을 수행하는 Java 코드가 있습니다.

코드는 tomcat 서블릿으로 포장됩니다.

(응용 프로그램으로 LDAP 인증 코드를 실행하는 것만으로) Java 코드를 직접 실행하면 바인드가 로컬 도메인 (로컬 도메인 = Windows에 로그인 한 상태에서이 도메인의 사용자와이 프로세스를 실행 함)) 및 외국 도메인.

자바 스크립트를 서블릿으로 실행하면 바인드가 작동하여 하나의 도메인에서 사용자를 인증하지만 다른 도메인의 사용자를 인증하려고 시도하면 작동하지 않습니다. 작동하지 않습니다. tomcat을 다시 시작합니다).

나는 예외를 받고 있어요 :

GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]] 

나는 그것이 같은 구성과 같은 KRB5 파일과 같은 코드라고 말할 수 있습니다.

편집 : 더 많은 정보 :

public void func(String realm, String kdc) { 
    try { 
     URL configURL = getClass().getResource("jaas_ntlm_configuration.txt"); 
     System.setProperty("java.security.auth.login.config", configURL.toString()); 

      System.setProperty("java.security.krb5.realm", realm); 
      System.setProperty("java.security.krb5.kdc",kdc); 

     // If the application is run on NT rather than Unix, use this name 
     String loginAppName = "MyConfig"; 

     // Create login context 
     LoginContext lc = new LoginContext(loginAppName, new SampleCallbackHandler()); 

     // Retrieve the information on the logged-in user 
     lc.login(); 

     // Get the authenticated subject 
     Subject subject = lc.getSubject(); 

     System.out.println(subject.toString()); 

     Subject.doAs(subject, new JndiAction(new String[] { "" })); 
    } 
    catch (LoginException e) { 
     e.printStackTrace(); 
    } 
} 

class JndiAction implements java.security.PrivilegedAction { 
    private String[] args; 

    public JndiAction(String[] origArgs) { 
     this.args = (String[])origArgs.clone(); 
    } 

    public Object run() { 
     performJndiOperation(args); 
     return null; 
    } 

    private static void performJndiOperation(String[] args) { 

     // Set up environment for creating initial context 
     Hashtable env = new Hashtable(11); 

     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 

     // Must use fully qualified hostname 
     env.put(Context.PROVIDER_URL, "ldap://server:389"); 

     // Request the use of the "GSSAPI" SASL mechanism 
     // Authenticate by using already established Kerberos credentials 
     env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI"); 

     try { 
      // Create the initial context 
      DirContext ctx = new InitialLdapContext(env, null); 


      // Close the context when we're done 
      ctx.close(); 
     } catch (NamingException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

그리고 내 jaas_ntlm_configuration.txt 파일이 포함되어 있습니다 : 이것은 내 코드

입니다

MyConfig { com.sun.security.auth.module.Krb5LoginModule required 
useTicketCache=true 
doNotPrompt=false; 
}; 

내 krb5.conf 파일은 다음과 같습니다

# 
# All rights reserved. 
# 
#pragma ident @(#)krb5.conf 1.1 00/12/08 

[libdefaults] 
    default_tkt_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc 
    default_tgs_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc 
    forwardable = true 
    renewable = true 
    noaddresses = true 
    clockskew = 300 

[realms] 
     SUB1.DOMAIN.COM = { 
       kdc = DDC.SUB1.DOMAIN.COM 
     default_domain=DOMAIN.COM 
     } 
    SUB2.DOMAIN.COM = { 
       kdc = DDC.SUB.DOMAIN.COM 
     default_domain=DOMAIN.COM 
     } 
    SUB3.DOMAIN.COM = { 
       kdc = DDC.SUB3.DOMAIN.COM 
     default_domain=DOMAIN.COM 
     } 

[domain_realm] 
    .DOMAIN.COM = SUB1.DOMAIN.COM 
    .DOMAIN.COM = SUB2.DOMAIN.COM 
    .DOMAIN.COM = SUB3.DOMAIN.COM 

[logging] 
     default = FILE:/var/krb5/kdc.log 
     kdc = FILE:/var/krb5/kdc.log 
    kdc_rotate = { 

# How often to rotate kdc.log. Logs will get rotated no more 
# often than the period, and less often if the KDC is not used 
# frequently. 

     period = 1d 

# how many versions of kdc.log to keep around (kdc.log.0, kdc.log.1, ...) 

     versions = 10 
    } 

[appdefaults] 
    kinit = { 
     renewable = true 
     forwardable= true 
    } 
    rlogin = { 
     forwardable= true 
    } 
    rsh = { 
     forwardable= true 
    } 
    telnet = { 
      autologin = true 
     forwardable= true 
    } 
012 3,516,

나는 자바 매개 변수로 다음과 같은 추가 :

-Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true 

내가 호출하면 FUNC ("SUB * .domain.com에", "DDC.SUB * .domain.com에") 항상 같은 하위 도메인에 -을 작동하지만, 하나의 하위 도메인을 호출 한 다음 다른 도메인을 호출하면 두 번째 도메인이 실패합니다.

더 많은 정보 :

java -Xmx100m -cp gssapi_test.jar -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true gssapitest.myTest my_config.txt 
2 users provided. Performing authentication #1 
Reading configuration file my_config.txt 
kdc: DDC.SUB1.DOMAIN.COM, realm: SUB1.DOMAIN.COM 
>>>KinitOptions cache name is C:\Users\user1\krb5cc_user1 
>> Acquire default native Credentials 
>>> Obtained TGT from LSA: Credentials: 
[email protected] 
server=krbtgt/[email protected] 
authTime=20130422075139Z 
startTime=20130422075139Z 
endTime=20130422175139Z 
renewTill=20130429075139Z 
flags: FORWARDABLE;RENEWABLE;INITIAL;PRE-AUTHENT 
EType (int): 23 
Subject: 
    Principal: [email protected] 
    Private Credential: Ticket (hex) = 
..... 

Client Principal = [email protected] 
Server Principal = krbtgt/[email protected] 
Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)= 
0000: 2B 8C 97 3C 8E 83 66 F1 6D 58 6C 37 20 0E 1F 53 +..<..f.mXl7 ..S 


Forwardable Ticket true 
Forwarded Ticket false 
Proxiable Ticket false 
Proxy Ticket false 
Postdated Ticket false 
Renewable Ticket true 
Initial Ticket true 
Auth Time = Mon Apr 22 15:51:39 2013 
Start Time = Mon Apr 22 15:51:39 2013 
End Time = Tue Apr 23 01:51:39 2013 
Renew Till = Mon Apr 29 15:51:39 2013 
Client Addresses Null 

Connecting to LDAP 
Config name: krb5.conf 
Found ticket for [email protected] to go to krbtgt/[email protected] expiring on Tue Apr 23 01:51:39 2013 
Entered Krb5Context.initSecContext with state=STATE_NEW 
Service ticket not found in the subject 
>>> Credentials acquireServiceCreds: same realm 
default etypes for default_tgs_enctypes: 16 3 1. 
>>> CksumType: sun.security.krb5.internal.crypto.RsaMd5CksumType 
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType 
>>> KdcAccessibility: reset 
>>> KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000, number of retries =3, #bytes=1554 
>>> KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000,Attempt =1, #bytes=1554 
>>> KrbKdcReq send: #bytes read=107 
>>> KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000, number of retries =3, #bytes=1554 
>>> KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000,Attempt =1, #bytes=1554 
>>>DEBUG: TCPClient reading 1497 bytes 
>>> KrbKdcReq send: #bytes read=1497 
>>> KdcAccessibility: remove DDC.SUB1.DOMAIN.COM 
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType 
>>> KrbApReq: APOptions are 00000000 00000000 00000000 00000000 
>>> EType: sun.security.krb5.internal.crypto.DesCbcMd5EType 
Krb5Context setting mySeqNumber to: 1005735013 
Krb5Context setting peerSeqNumber to: 0 
Created InitSecContextToken: 
..... 

Krb5Context.unwrap: token=[60 33 06 09 2a 86 48 86 f7 12 01 02 02 02 01 00 00 ff ff ff ff 94 52 14 5b f6 02 28 1c a4 3c c5 8f 03 9c a2 d6 e5 f6 f1 18 ed 6f 16 ab 07 a0 00 00 04 04 04 04 ] 
Krb5Context.unwrap: data=[07 a0 00 00 ] 
Krb5Context.wrap: data=[01 01 00 00 ] 
Krb5Context.wrap: token=[60 33 06 09 2a 86 48 86 f7 12 01 02 02 02 01 00 00 ff ff ff ff 2d b6 92 0d d9 51 da aa ef 41 67 33 5c de b3 e6 ce 9a 46 31 a0 a8 0e 27 01 01 00 00 04 04 04 04 ] 
Connected 
Disconnected 
#1: Done 
Performing authentication #2 
Reading configuration file my_config.txt 
kdc: DDC.SUB2.DOMAIN.COM, realm: SUB2.DOMAIN.COM 
>>>KinitOptions cache name is C:\Users\user1\krb5cc_user1 
>> Acquire default native Credentials 
>>> Obtained TGT from LSA: Credentials: 
[email protected] 
server=krbtgt/[email protected] 
authTime=20130422075139Z 
startTime=20130422075139Z 
endTime=20130422175139Z 
renewTill=20130429075139Z 
flags: FORWARDABLE;RENEWABLE;INITIAL;PRE-AUTHENT 
EType (int): 23 
Subject: 
    Principal: [email protected] 
    Private Credential: Ticket (hex) = 
..... 

Client Principal = [email protected] 
Server Principal = krbtgt/[email protected] 
Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)= 
0000: 2B 8C 97 3C 8E 83 66 F1 6D 58 6C 37 20 0E 1F 53 +..<..f.mXl7 ..S 


Forwardable Ticket true 
Forwarded Ticket false 
Proxiable Ticket false 
Proxy Ticket false 
Postdated Ticket false 
Renewable Ticket true 
Initial Ticket true 
Auth Time = Mon Apr 22 15:51:39 2013 
Start Time = Mon Apr 22 15:51:39 2013 
End Time = Tue Apr 23 01:51:39 2013 
Renew Till = Mon Apr 29 15:51:39 2013 
Client Addresses Null 

Connecting to LDAP 
Found ticket for [email protected] to go to krbtgt/[email protected] expiring on Tue Apr 23 01:51:39 2013 
Entered Krb5Context.initSecContext with state=STATE_NEW 
Service ticket not found in the subject 
>>> Credentials acquireServiceCreds: same realm 
default etypes for default_tgs_enctypes: 16 3 1. 
>>> CksumType: sun.security.krb5.internal.crypto.RsaMd5CksumType 
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType 
>>> KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000, number of retries =3, #bytes=1554 
>>> KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM UDP:88, timeout=30000,Attempt =1, #bytes=1554 
>>> KrbKdcReq send: #bytes read=107 
>>> KrbKdcReq send: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000, number of retries =3, #bytes=1554 
>>> KDCCommunication: kdc=DDC.SUB1.DOMAIN.COM TCP:88, timeout=30000,Attempt =1, #bytes=1554 
>>>DEBUG: TCPClient reading 1482 bytes 
>>> KrbKdcReq send: #bytes read=1482 
>>> KdcAccessibility: remove DDC.SUB1.DOMAIN.COM 
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType 
KrbException: Message stream modified (41) 
    at sun.security.krb5.KrbKdcRep.check(Unknown Source) 
    at sun.security.krb5.KrbTgsRep.<init>(Unknown Source) 
    at sun.security.krb5.KrbTgsReq.getReply(Unknown Source) 
    at sun.security.krb5.KrbTgsReq.sendAndGetCreds(Unknown Source) 
    at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source) 
    at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source) 
    at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source) 
    at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source) 
    at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source) 
    at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source) 
    at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source) 
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source) 
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) 
    at javax.naming.InitialContext.init(Unknown Source) 
    at javax.naming.ldap.InitialLdapContext.<init>(Unknown Source) 
    at gssapitest.JndiAction.performJndiOperation(myTest.java:603) 
    at gssapitest.JndiAction.run(myTest.java:577) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Unknown Source) 
    at gssapitest.myTest.Do(myTest.java:59) 
    at gssapitest.myTest.main(myTest.java:513) 
javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]] 
    at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source) 
    at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source) 
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source) 
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) 
    at javax.naming.InitialContext.init(Unknown Source) 
    at javax.naming.ldap.InitialLdapContext.<init>(Unknown Source) 
    at gssapitest.JndiAction.performJndiOperation(myTest.java:603) 
    at gssapitest.JndiAction.run(myTest.java:577) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Unknown Source) 
    at gssapitest.myTest.Do(myTest.java:59) 
    at gssapitest.myTest.main(myTest.java:513) 
Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))] 
    at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source) 
    ... 18 more 
Caused by: GSSException: No valid credentials provided (Mechanism level: Message stream modified (41)) 
    at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source) 
    ... 19 more 
Caused by: KrbException: Message stream modified (41) 
    at sun.security.krb5.KrbKdcRep.check(Unknown Source) 
    at sun.security.krb5.KrbTgsRep.<init>(Unknown Source) 
    at sun.security.krb5.KrbTgsReq.getReply(Unknown Source) 
    at sun.security.krb5.KrbTgsReq.sendAndGetCreds(Unknown Source) 
    at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source) 
    at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source) 
    at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source) 
    ... 22 more 
FAILED 

내가 무엇을 할 수 있습니다 : 여기

사실 = krb5.debug로 출력? 내가 뭔가 잘못 했니?

감사합니다.

답변

0

NTLM! = Kerberos. Java SASL은 NTLM을 지원하지 않습니다. Kerberos를 올바르게 구성하면 제대로 작동합니다.

+0

제대로 구성했다고 생각합니다. 내 코드와 구성을 게시했는데 무엇이 잘못되었는지 이해할 수 있으면 기꺼이 도와 드리겠습니다. 감사. – Matan

+0

무엇을 사용 하시겠습니까? NTLM 또는 Kerberos? –

+0

1. 앱에서'System.setProperty'를 모두 제거하고 시작시'-D'를 제공하십시오. 2. 연결하려는 위치에 샘플 호스트 이름 (SPN)과 UPN을 제공하십시오. 전체 경로를 확인해야합니다. 포리스트의 교차 영역은 JGSS의 문제가 아닙니다. 여기 매력과 함께 작동합니다. 이 [library] (http://dirctxsrc.sourceforge.net/)를 사용하면 보일러 플레이트의 고통을 덜어 줄 수 있습니다. –

9

감사합니다. 참고로, 영역의 대문자 (예 : 영역이 100 % 정확하고 대문자 여야 함)는 "예외 : krb_error 41 Message stream modified (41)"을 피하기 위해 매우 중요합니다.

[libdefaults] 
default_realm = EXAMPLE.COM 

[realms] 
EXAMPLE.COM = { 
kdc = domaincontroller.example.com 
admin_server = domaincontroller.example.com 
default_domain = EXAMPLE.COM 
} 

[domain_realm] 
.example.com = EXAMPLE.COM 
example.com = EXAMPLE.COM 

감사합니다,

니카 :

여기에 올바른 표기법의 예입니다.

+0

시기 적절하게 수정 - 이는 내 구성에 대한 잘못된 내용이었습니다. 직관적 인 오류는 아니지만 대문자로 도메인을 지정하면 내 문제가 해결됩니다. – Justin