2
votes

First I'm really new to Kerberos and also I have only limited knowledge of all the Domain stuff, but I have to connect to our SharePoint Server and use it's search api, as this will run on a unix Server I have to authenticate via Kerberos and Username Password. So here is what I do:

My Java Code

    public class MyExmapleService {

        public MyExmapleService () {
                connectDefault();
        }

        private void connectDefault() {
            try {
                Authenticator.setDefault(new SbHttpAuthenticator());
                System.setProperty("java.security.krb5.conf", "C:/ext/AFP-2.4.13/config/krb5.conf");
                System.setProperty("java.security.auth.useSubjectCredsOnly", "false");
                System.setProperty("http.auth.preference", "kerberos");
                System.setProperty("sun.security.krb5.debug", "true");
                System.setProperty("java.security.auth.login.config", "C:/ext/AFP-2.4.13/lgt_config/login.conf");



                URL url = new URL("https://something.mySharePoint.com/_api/search/query?");

                URLConnection conn = url.openConnection();
                InputStream ins = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
                String str;
                while((str = reader.readLine()) != null) {
                    System.out.println("blup: " + str);
                }

            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) throws Exception {
            new SbMyLgtService();
        }
    }

    public class SbHttpAuthenticator extends Authenticator {
        public PasswordAuthentication getPasswordAuthentication() {
          try {
            String kUser = "someUser";
            String kPassword = "somePassword";

            System.err.println("Feeding username and password for " + getRequestingScheme() + " " + kUser + " " + kPassword);
            return (new PasswordAuthentication(kUser, kPassword.toCharArray()));
          } catch (IOException e) {
            e.printStackTrace();
          }
          return null;
        }
    }

krb5.conf

    [libdefaults]
        default_realm = XX.LOC
        dns_lookup = false
    [realms]
        XX.LOC   = {
            kdc = xxxxxxxx2110.xx.loc
        }
    [domain_realm]
        .XX.loc = XX.LOC
        XX.loc = XX.LOC

Login.conf

    com.sun.security.jgss.krb5.initiate {
      com.sun.security.auth.module.Krb5LoginModule 
      required 
      doNotPrompt=false 
      useTicketCache=false
      allow_weak_crypto=true;
    };

The first Problem I had was that a2.loc return 20 Servers, so not always the right Server was taken, with the dns_lookup_kdc = false Parameter in the krb5.conf this is solved.

So if I rund this program this Java Exception: 'KrbException: Message stream modified (41)' To correct that Stackoverflow did advice to use the uppercase Version and that Domain-realm entries. Weirdly enough our Realm seems to XX.loc so a mixed upper-lower case Name... Is there a way to config this? here's the error Output:

    Loaded from Java config
    >>> KdcAccessibility: reset
    Using builtin default etypes for default_tkt_enctypes
    default etypes for default_tkt_enctypes: 17 16 23.
    >>> KrbAsReq creating message
    Feeding username and password for Negotiate someUser somePassword
    >>> KrbKdcReq send: kdc=xxxxx2110.xx.loc UDP:88, timeout=30000, number of retries =3, #bytes=140
    >>> KDCCommunication: kdc=xxxxxx2110.xx.loc UDP:88, timeout=30000,Attempt =1, #bytes=140
    >>> KrbKdcReq send: #bytes read=179
    >>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 17, salt = XX.LOCSA-XX-LLLL-htavro, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

    >>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
    >>>Pre-Authentication Data:
         PA-DATA type = 16

    >>>Pre-Authentication Data:
         PA-DATA type = 15

    >>> KdcAccessibility: remove xxxxxx2110.xx.loc
    >>> KDCRep: init() encoding tag is 126 req type is 11
    >>>KRBError:
         sTime is Tue Feb 23 18:07:16 CET 2016 1456247236000
         suSec is 874332
         error code is 25
         error Message is Additional pre-authentication required
         sname is krbtgt/[email protected]
         eData provided.
         msgType is 30
    >>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 17, salt = XX.LOCSA-XX-LLLL-htavro, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

    >>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
    >>>Pre-Authentication Data:
         PA-DATA type = 16

    >>>Pre-Authentication Data:
         PA-DATA type = 15

    KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
    Using builtin default etypes for default_tkt_enctypes
    default etypes for default_tkt_enctypes: 17 16 23.
    Using builtin default etypes for default_tkt_enctypes
    default etypes for default_tkt_enctypes: 17 16 23.
    >>> EType: sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType
    >>> KrbAsReq creating message
    >>> KrbKdcReq send: kdc=xxxxxx2110.xx.loc UDP:88, timeout=30000, number of retries =3, #bytes=222
    >>> KDCCommunication: kdc=xxxxxx2110.xx.loc UDP:88, timeout=30000,Attempt =1, #bytes=222
    >>> KrbKdcReq send: #bytes read=1401
    >>> KdcAccessibility: remove xxxxxx2110.xx.loc
    >>> EType: sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType
    Negotiate support not initiated, will fallback to other scheme if allowed. Reason:
    GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new INITIATE credentials failed! (null))
        at sun.security.jgss.krb5.Krb5InitCredential.getTgt(Krb5InitCredential.java:343)
        at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:145)
        at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
        at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:187)
        at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
        at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
        at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
        at sun.net.www.protocol.http.spnego.NegotiatorImpl.init(NegotiatorImpl.java:108)
        at sun.net.www.protocol.http.spnego.NegotiatorImpl.<init>(NegotiatorImpl.java:117)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at sun.net.www.protocol.http.Negotiator.getNegotiator(Negotiator.java:63)
        at sun.net.www.protocol.http.NegotiateAuthentication.firstToken(NegotiateAuthentication.java:209)
        at sun.net.www.protocol.http.NegotiateAuthentication.setHeaders(NegotiateAuthentication.java:183)
        at sun.net.www.protocol.http.HttpURLConnection.getServerAuthentication(HttpURLConnection.java:2467)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1682)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
        at com.lgt.sb.service.fininfo.mylgt.SbMyLgtService.connectDefault(SbMyLgtService.java:49)
        at com.lgt.sb.service.fininfo.mylgt.SbMyLgtService.<init>(SbMyLgtService.java:27)
        at com.lgt.sb.service.fininfo.mylgt.SbMyLgtService.main(SbMyLgtService.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
    Caused by: javax.security.auth.login.LoginException: Message stream modified (41)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at sun.security.jgss.GSSUtil.login(GSSUtil.java:258)
        at sun.security.jgss.krb5.Krb5Util.getTicket(Krb5Util.java:158)
        at sun.security.jgss.krb5.Krb5InitCredential$1.run(Krb5InitCredential.java:335)
        at sun.security.jgss.krb5.Krb5InitCredential$1.run(Krb5InitCredential.java:331)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.jgss.krb5.Krb5InitCredential.getTgt(Krb5InitCredential.java:330)
        ... 27 more
    Caused by: KrbException: Message stream modified (41)
        at sun.security.krb5.KrbKdcRep.check(KrbKdcRep.java:45)
        at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:158)
        at sun.security.krb5.KrbAsRep.decryptUsingPassword(KrbAsRep.java:139)
        at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:287)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:766)
        ... 45 more
    java.io.IOException: Server returned HTTP response code: 401 for URL: https://something.mySharePoint.com/_api/search/query?
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1839)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
        at com.xxx.MyExampleService.connectDefault(SbMyLgtService.java:49)
        at com.xxx.MyExampleService.<init>(SbMyLgtService.java:27)
        at com.xxx.MyExampleService.main(SbMyLgtService.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
1
For theoretical background on Kerberos protocol, I highly recommend: kerberos.org/software/tutorial.html . That said, since the problem seems to be in the pre-authentication phase, which is optional, maybe you can ask your Kerberos guys to configure it to not use pre-authentication. - Yoav Gur
thank you for the link I'm working through the tutorial now. My Kerberos guys are a bit reluctant to Change a running System just for me, so I hope I can find a way around that, especially as it seems to cause no error in the Kerberos debug Statements when I connect to the right Server. But I'm also checking with the guys. - Chris
So I now tried it without the pre-authentication and it still has the same Problems. with Version 1 it still takes a random Server, but even if it takes the right Server by accident it also gets this 'stream modified (41)' error. - Chris
Another idea, is to use fiddler to monitor the traffic between the client and the KDC, and compare it to a working client (written in a different language). This may give a hint regarding what is missing / need to be changed. - Yoav Gur
I'm one step further, with the paramter dns_lookup_kdc = false I don't get random kdn Servers anymore - Chris

1 Answers

0
votes

This can happen if there are updates to Krb5 config but it is cached in your system, try adding below property to your jaasConfig

put("refreshKrb5Config", "true");