8 Replies Latest reply: Feb 9, 2010 6:17 PM by 843810 RSS

    Consume a .NET kerberized web service

    800435
      Hi!

      I'm trying to create a java client to access a .NET kerberized web service. Right now I have two pieces of code but I I don't know how to integrate them. The scenario is: I have a web application in WebLogic server and this application needs to access a .NET kerberized web service. I'm using SSO.
      In one hand I developed all that stubs that make the client code to invoke the service.
      On the other hand I have:
      try {
                     LoginContext lc = new LoginContext("com.sun.security.jgss.initiate");
                     lc.login();
                     Subject subject = lc.getSubject();
                     logger.info("PRINCIPALS-->" + subject.getPrincipals());
                     Subject.doAs(lc.getSubject(), new PrivilegedAction() {
      
                      public Object run() {
                          try {
                               Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
                              Oid krb5PrincipalNameType = new Oid("1.2.840.113554.1.2.2.1");
      
                               GSSManager manager = GSSManager.getInstance();
                               // Identify who the client wishes to be
                              GSSName clientName = manager.createName("suapps208", GSSName.NT_USER_NAME);
                              logger.info("CLIENT NAME -->"  + clientName.toString());
                              logger.info("CLIENT NAME TYPE -->"  + clientName.getStringNameType().toString());
                              // Identify the name of the server. This uses a Kerberos specific
                              // name format.
                              GSSName serverName = manager.createName("suapps208@RITTA.LOCAL", krb5PrincipalNameType);
                              GSSCredential clientCred = manager.createCredential(clientName,
                                                                                  GSSCredential.DEFAULT_LIFETIME,
                                                                                  krb5Mechanism,
                                                                                  GSSCredential.INITIATE_ONLY);
                              logger.info("CLIENT CREDENTIALS OK");
                              // Instantiate and initialize a security context that will be
                              // established with the server
                              GSSContext context = manager.createContext(serverName,
                                                                                     krb5Mechanism,
                                                                                     clientCred,
                                                                                     GSSContext.DEFAULT_LIFETIME);
                              byte[] outToken = context.initSecContext(new byte[0], 0, 0);
                              logger.info("OUT TOKEN-->" + new BASE64Encoder().encode(outToken));
                              context.dispose();
      
                                    return null;
                               } catch (GSSException e) {
                                    System.err.println("GSSException-->" + e.getMessage());
                                    e.printStackTrace();
                               }
                               return null;
                      }
                  });
                } catch (LoginException le) {
                     System.err.println("LoginException-->" + le.getMessage());
                     le.printStackTrace();
                     throw(le);
                } catch (SecurityException se) {
                     System.err.println("SecurityException-->" + se.getMessage());
                     se.printStackTrace();
                     throw(se);
                } catch (Exception e) {
                     System.err.println("General Exception-->" + e.getMessage());
                     e.printStackTrace();
                     throw e;
                }
      
                
      
                try {
                             //This is the code developed by the wizard in netbeans using Metro
                             //it blows up in the next line
                     pt.min_financas.dgita.Profiles service = new pt.min_financas.dgita.Profiles();
                     pt.min_financas.dgita.ProfilesSoap port = service.getProfilesSoap();
      
                } catch (Exception ex) {
                     logger.severe("ERRO NA INVOCACAO DO WEB SERVICE-->" + ex.getMessage());
                     ex.printStackTrace();
                }
      I've downloaded the wsdl and generated using Metro the client code. One doubt arises here: in the wsdl there's no security entry. Is it supposed to have?
      Onother doubt: who is the client and who is the server? As far as I know, there are 3 entities: the person who's using the application; the weblogic server (the suapps208) and the web service.

      I can login and get the TGT. I just don't know how to obtain the ticket for the webservice and how to use ti to access th service.

      I know, this is a mess but my brain is completely kerberized. Anyway, you can ask me questions and I'll answer. I've read a lot of stuff but I'm having problems in putting all together.

      Thanks in advance,
      Manuel Leiria
        • 1. Re: Consume a .NET kerberized web service
          800435
          Hello,

          I have new info on the subject.
          The wsdl file doesn't have any security entry because the web service is not using WS-Security. The security is implemented at the web server level. Given this new info, my question is: is there some java class where I can pass the url of the wsdl file and the credentials?

          The generated classes (using wsimport) gave me something like this:
          pt.min_financas.dgita.Profiles service = new pt.min_financas.dgita.Profiles();
          and the Profiles class extends javax.xml.ws.Service

          If I invoke Profiles service = new Profiles(), I get a 401 Unauthorized. My guess is that priori to create new Profiles() I must pass (some how) the credentials or ticket or something like that.

          Any help is highly appreciated!!

          Manuel Leiria
          • 2. Re: Consume a .NET kerberized web service
            843810
            Perhaps your first step should be to create a simple "hello world" command-line client that can connect to your protected web service.

            This might help with your understanding of what all needs to happen.

            This open source library, [http://spnego.sourceforge.net/protected_soap_service.html|http://spnego.sourceforge.net/protected_soap_service.html] , has a working example and instructions on how to create such a client.

            The library is actually an SPNEGO HTTP Servlet Filter but you will not be using that piece of it.

            Just read through the example on how to connect to a protected web service.

            The example code is pretty simple and straightforward.
            • 3. Re: Consume a .NET kerberized web service
              800435
              I've already been there and it sounds nice but I'm using Java 5.

              In the mean while I've tried to contact the wsdl file using HttpClient with httpclient-auth-spnego extension. Now with this I can call the wsdl file with no problem. First I receive the 401 but the httpclient makes all the negotiation and in the end I can receive the wsdl. Now, I just don't know how can I put this 2 pieces together : the HttpClient and the generated stubs.
              To be honest, I'm not sure if this HttpClient soves the problem.

              thanks for your help!

              Manuel Leiria
              • 4. Re: Consume a .NET kerberized web service
                800435
                Ok. I've moved to Java 6 and I'm using the spnego open source library.

                Now the problem: I have one WebLogic server that needs to access a web service in one iis server and this web server is protected by Kerberos. My code works fine in the development environment where kerberos and ntlm are both activated (but the mechanism choosen is kerberos). In production environment, ntlm is disabled (I was told that this is the main difference beetween the two environments). Now, what happens is that, in production mode instead of getting an Authorization Header: Negociate, I receive an Authorization Header: Kerberos and, of course, I receive from the code one

                java.lang.UnsupportedOperationException: Negotiate or Basic Only:Kerberos

                from this method:

                public static SpnegoAuthScheme getAuthScheme(final String header) {
                          System.out.println("HEADER-->" + header);
                if (null == header || header.isEmpty()) {
                LOGGER.finer("authorization header was missing/null");
                return null;

                } else if (header.startsWith(Constants.NEGOTIATE_HEADER) ) {
                final String token = header.substring(Constants.NEGOTIATE_HEADER.length() + 1);
                System.out.println("TOKEN-->" + token);
                return new SpnegoAuthScheme(Constants.NEGOTIATE_HEADER, token);
                }
                else if (header.startsWith(Constants.BASIC_HEADER)) {
                final String token = header.substring(Constants.BASIC_HEADER.length() + 1);
                return new SpnegoAuthScheme(Constants.BASIC_HEADER, token);

                } else {
                throw new UnsupportedOperationException("Negotiate or Basic Only:" + header);
                }
                }

                in the SpnegoProvider class.

                Now, the guys here in my company (the iis administrators) know nothing about kerberos (I think the've configured the iis/kerberos/AD following some kind of next, next, next install, if you know what I mean).
                The final question is: How can I workaround this exception??

                Thanks in advance,
                Manuel Leiria
                • 5. Re: Consume a .NET kerberized web service
                  800435
                  Shi_t man, this problem is kerberizing my brains!!
                  Just adding some more info on the subject

                  In the code posted above,
                  Development env:
                  System.out.println("HEADER-->" header);  
                  gives
                  HEADER-->Negotiate oYGLMIGIoAMKAQChCwYJKoZIhvcSAQIConQEcmBwBgkqhkiG9xIBAgICAG9hMF+gAwIBBaEDAgEPolMwUaADAgEBokoESLvSJHwvhCjn0DcANiuuv2sFr+Q4wbFPuRjfnyRnzFpjMTS5UpYEcrT9iySt5QjdptKsUiFK8W8y1W2MNIUUtPQkZ35//8UjOA==
                  and
                  System.out.println("TOKEN-->" token); 
                  gives
                  TOKEN-->oYGLMIGIoAMKAQChCwYJKoZIhvcSAQIConQEcmBwBgkqhkiG9xIBAgICAG9hMF+gAwIBBaEDAgEPolMwUaADAgEBokoESLvSJHwvhCjn0DcANiuuv2sFr+Q4wbFPuRjfnyRnzFpjMTS5UpYEcrT9iySt5QjdptKsUiFK8W8y1W2MNIUUtPQkZ35//8UjOA==
                  In Production env.,
                  System.out.println("HEADER-->" header);  
                  gives
                  HEADER-->Kerberos
                  and
                  there's no f*** token!!!

                  thanks for any light!!!

                  ML

                  Edited by: manuel.leiria on Feb 3, 2010 3:22 PM

                  Edited by: manuel.leiria on Feb 3, 2010 3:39 PM
                  • 6. Re: Consume a .NET kerberized web service
                    843810
                    Something is definitely gimped with your Production IIS server.

                    It's not even returning the right HEADER--> value!

                    I'm guessing it has something to do with your statement...

                    In production environment, ntlm is disabled (I was told that
                    this is the main difference beetween the two environments).

                    Who ever disabled ntlm on your IIS server screwed something up.

                    I did not even realize you can disable ntlm.

                    You should ask your IIS administrators exactly what they did to disable ntlm.
                    • 7. Re: Consume a .NET kerberized web service
                      800435
                      Thanks for the reply.

                      I talked to the guys from iis and they told me that (I'm quoting) " iis only accept kerberos and returns only the kerberos header because if it returns Negotiate it will end up to revert to ntlm and we don't want that".

                      Now, I'm far from being an iis admin expert but I never read anything like this!!

                      According to MSDN:

                      "When Internet Explorer attempts to access a protected resource, IIS sends two WWW-Authenticate headers, Negotiate and NTLM."

                      Meaning, IIS should NOT be returning "Kerberos".

                      So, is this kind of "deactivation" of ntlm" a normal procedure?

                      thanks,
                      ML
                      • 8. Re: Consume a .NET kerberized web service
                        843810
                        So, is this kind of "deactivation" of ntlm" a normal procedure?

                        This is not normal.