locked
Calling ValidateCredentials always causes an exception to be thrown on Windows XP but not on e.g. Win 7 RRS feed

  • Question

  • Calling ValidateCredentials always causes an exception to be thrown on Windows XP but not on e.g. Win 7, when the ContextType of the PrincipalContext is defined as ContextType.Machine.

    I have not verified if this is the case for other .NET runtime versions as all my projects are currently compiled against the .NET 4.0 runtime.

    Have enyone else experinced this problem?

    ------------------------------------------------------

    NOTE: Below code has been modified, based on below feedback, however the code still need to be further modified if it is intended to be used to support exception free authentication of local users on XP based machines.

    /// <summary>
    /// Authenticates windows credentials
    /// </summary>
    private static bool AuthenticateWindowsCredentials(
            ContextType contextType, 
            string domainName, 
            string userName, 
            string userPassword,  
            out string statusMessage)
    {
        var isAuthenticated = false;
     
        try
        {
            using (var pc = new PrincipalContext(
                    contextType, 
                    domainName, 
                    String.Format(@"{0}\{1}", domainName, userName), 
                    userPassword))
            {
                ContextOptions contextOptions;
     
                switch (contextType)
                {
                    case ContextType.ApplicationDirectory:
                    case ContextType.Domain:
                        contextOptions = ContextOptions.SimpleBind;
                        isAuthenticated = pc.ValidateCredentials(
                                String.Format(@"{0}\{1}", domainName, userName), 
                                userPassword, 
                                contextOptions);
                        break;
                    case ContextType.Machine:
                        contextOptions = ContextOptions.Negotiate;
                        isAuthenticated = pc.ValidateCredentials(userName, userPassword, contextOptions);
                        break;
                }
     
                statusMessage = isAuthenticated ? "Credentials validation succeeded." : "Credentials validation failed.";
            }
        }
        catch (Exception ex)
        {
            statusMessage = string.Format("Exception occurred while authenticating user. Message: {0}", ex.Message);
            return false;
        }
     
        return isAuthenticated;
    }

    great_scandinavian





    Thursday, October 25, 2012 7:10 PM

Answers

  • I did test it and the changes made a big difference in the way the code ran.  When I stepped through the code originally I couldn't get past the exception.  After the change, I was able to continue to step past the exception.  I'm not saying you have to put the change into your code exactly the way I did.  All I'm saying is that you need to add a general exception along with the arguement exception to fix you problem.  How you put the new exception handle into the code is your choice.

    jdweng

    • Marked as answer by Mike Feng Monday, October 29, 2012 12:04 PM
    Friday, October 26, 2012 12:24 AM

All replies

  • It seems your excemption handle (try/catch)  was not trapping all exceptions.  I added two more exception handlers in the code and now it seems to be working properly.  I thinkit is due to the fact you were only trapping ArgumentException and not general exceptions.

            static void Main(string[] args)
            {
                string statusMessage = "";
                AuthenticateWindowsCredentials(
                    ContextType.Machine,
                    "xyz",
                    "abc",
                    "def",
                    out statusMessage);
            }
            /// <summary>
            /// Authenticates windows credentials
            /// </summary>
            private static bool AuthenticateWindowsCredentials(
                    ContextType contextType,
                    string domainName,
                    string userName,
                    string userPassword,
                    out string statusMessage)
            {
                var isAuthenticated = false;
                statusMessage = String.Empty;
                try
                {
                    using (var pc = new PrincipalContext(
                            contextType,
                            domainName,
                            String.Format(@"{0}\{1}", domainName, userName),
                            userPassword))
                    {
                        ContextOptions contextOptions;
                        switch (contextType)
                        {
                            case ContextType.ApplicationDirectory:
                            case ContextType.Domain:
                                try
                                {
                                    contextOptions = ContextOptions.SimpleBind;
                                    isAuthenticated = pc.ValidateCredentials(
                                            String.Format(@"{0}\{1}", domainName, userName),
                                            userPassword,
                                            contextOptions);
                                }
                                catch(Exception e)
                                {
                                    Console.WriteLine(e.Message);
                                }
                                break;
                            case ContextType.Machine:
                                try
                                {
                                   contextOptions = ContextOptions.Negotiate;
                                   isAuthenticated = pc.ValidateCredentials(userName, userPassword, contextOptions);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine(e.Message);
                                }
                                break;
                        }
                        statusMessage = isAuthenticated ? "Credentials validation succeeded." : "Credentials validation failed.";
                    }
                }
                catch (ArgumentException ex)
                {
                    statusMessage = "Exception occurred while authenticating user. Message: " + ex.Message;
                    return true;
                }
                return isAuthenticated;
            }


    jdweng

    Thursday, October 25, 2012 9:14 PM
  • I did test it and the changes made a big difference in the way the code ran.  When I stepped through the code originally I couldn't get past the exception.  After the change, I was able to continue to step past the exception.  I'm not saying you have to put the change into your code exactly the way I did.  All I'm saying is that you need to add a general exception along with the arguement exception to fix you problem.  How you put the new exception handle into the code is your choice.

    jdweng

    • Marked as answer by Mike Feng Monday, October 29, 2012 12:04 PM
    Friday, October 26, 2012 12:24 AM
  • jdweng,

    Thank you for your recommendations. Based on your feedback I updated my initially posted code to handle any exception and in the exception handler to return 'false' instead of 'true', which latter I realize was a coding error of mine.

    However the updated code does not solve the issue with XP throwing an exception when authenticating a local machine user, where as the same code does not cause any exceptions when executed on for example Win 7. Will have to look into the reason for the XP based exception.

    Note: You may want to remove your above feedback code as someone may copy it with the mentioned error in the return value.


    great_scandinavian




    Friday, October 26, 2012 2:39 AM