2 Replies Latest reply: Jan 25, 2016 1:44 AM by Konrad Mattheis RSS

    .NET SDK authentication from Non-Domain Computer

    Lucas Blancher

      Hello,

      I am trying to determine the best method for authenticating the .NET SDK to a Qlik Sense server from a computer that is not on the same domain as the Qlik Sense server.

       

      From my understanding the AsNtlmUserViaProxy() method of ILocation does not allow me to change who my user is, it uses the currently logged in user information.  Is their a way to change the userId/password for this call, prior to it being issued?

       

      I have looked at the AsStaticHeaderUserViaProxy(), however I don't understand how I can secure this method of access from external hackers.  Should someone guess my chosen header name they would then have complete access to my Qlik Sense server.

       

      I know the external API's are configured so that they can use certificates for authentication, is their an .NET SDK method to allow for authenitcation based on certificates?

       

      What is the best method to securely authenticate the .NET SDK against a Qlik Sense server, without having it tied to the current user credentials of the computer I am using the SDK from a?

       

      Regards,

      Lucas

        • Re: .NET SDK authentication from Non-Domain Computer
          Lars-Goran Book

          Hi,

          You could use impersonation se example below.

           

          Best regards

          Lars-Göran Book

           

          Example:

          class Program
          {
            static void Main(string[] args)
            {
             //http://stackoverflow.com/questions/9021414/dynamic-impersonation-in-asp-net
             if (Impersonation.impersonateValidUser("lars", "mydomain", "myPwd"))
             {
              var location = Location.FromUri(new Uri("wss://myserver.domain.com"));
              location.AsNtlmUserViaProxy();
              using (var hub = location.Hub(noVersionCheck: true))
              {
               Console.WriteLine(hub.GetAuthenticatedUser());
              }
              Console.WriteLine(location.IsAlive(noVersionCheck:true));
             }
             else
             {
              Console.WriteLine("not a valid user");
             }
             Console.Read();
            }
          }

          public class Impersonation
          {
            public static int LOGON32_LOGON_INTERACTIVE = 2;
            public static int LOGON32_PROVIDER_DEFAULT = 0;

            [DllImport("advapi32.dll")]
            public static extern int LogonUserA(string lpxzUsername, string lpzDomain, string lpzPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
            [DllImport("advapi32.dll")]
            public static extern int DuplicateToken(IntPtr ExistingTokenHandle, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
            [DllImport("advapi32.dll")]
            public static extern long RevertToSelf();

            [DllImport("Kernel32.dll")]
            public static extern long CloseHandle(IntPtr handle);

            public static WindowsImpersonationContext impersonationContext;

            public static bool impersonateValidUser(string userName, string domain, string password)
            {
             WindowsIdentity tempWindowsIdentity;
             IntPtr token = IntPtr.Zero;
             IntPtr tokenDuplicate = IntPtr.Zero;
             bool ValidUser = false;

             if (RevertToSelf() != 0)
             {
              if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
              {
               if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
               {
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                impersonationContext = tempWindowsIdentity.Impersonate();
                if (impersonationContext != null)
                {
                 ValidUser = true;
                }
               }
              }
             }

             if (!tokenDuplicate.Equals(IntPtr.Zero))
             {
              CloseHandle(tokenDuplicate);
             }
             if (!token.Equals(IntPtr.Zero))
             {
              CloseHandle(token);
             }
             return ValidUser;

            }

            public static void undoImpersonation()
            {
             try
             {
              impersonationContext.Undo();
             }
             catch
             {
             }
            }
          }

            • Re: .NET SDK authentication from Non-Domain Computer
              Konrad Mattheis

              Hi,

               

              you can use also this nuget package PM> Install-Package SimpleImpersonation

               

              What you have to take care is that everything behind Impersonation.impersonateValidUser(... is running as a other user, so if you other things like Console.WriteLine it can run into problems. So don't forget to make a undoImpersonation after you have a valid connection to the hub. I don't know if it is easy working just to take the valid hub variable in the not impersonated context. I will test this in the next two weeks and come back with an info.

               

              bye

              Konrad