c# - সক্রিয় ডিরেক্টরি বিরুদ্ধে একটি ব্যবহারকারীর নাম এবং পাসওয়ার্ড যাচাই?




authentication active-directory (8)

কিভাবে আমি সক্রিয় ডিরেক্টরি বিরুদ্ধে একটি ব্যবহারকারী নাম এবং পাসওয়ার্ড যাচাই করতে পারেন? আমি কেবল একটি ব্যবহারকারীর নাম এবং পাসওয়ার্ড সঠিক কিনা তা পরীক্ষা করতে চাই।


DirectoryServices ব্যবহার করে খুব সহজ সমাধান:

using System.DirectoryServices;

//srvr = ldap server, e.g. LDAP://domain.com
//usr = user name
//pwd = user password
public bool IsAuthenticated(string srvr, string usr, string pwd)
{
    bool authenticated = false;

    try
    {
        DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
        object nativeObject = entry.NativeObject;
        authenticated = true;
    }
    catch (DirectoryServicesCOMException cex)
    {
        //not authenticated; reason why is in cex
    }
    catch (Exception ex)
    {
        //not authenticated due to some other exception [this is optional]
    }

    return authenticated;
}

NativeObject অ্যাক্সেস একটি খারাপ ব্যবহারকারী / পাসওয়ার্ড সনাক্ত করার জন্য প্রয়োজন বোধ করা হয়


আমরা আমাদের ইন্ট্রানেট এই কাজ

আপনি System.DirectoryServices ব্যবহার করতে হবে;

এখানে কোড বিন্দু হয়

using (DirectoryEntry adsEntry = new DirectoryEntry(path, strAccountId, strPassword))
{
    using (DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry))
    {
        //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))";
        adsSearcher.Filter = "(sAMAccountName=" + strAccountId + ")";

        try
        {
            SearchResult adsSearchResult = adsSearcher.FindOne();
            bSucceeded = true;

            strAuthenticatedBy = "Active Directory";
            strError = "User has been authenticated by Active Directory.";
        }
        catch (Exception ex)
        {
            // Failed to authenticate. Most likely it is caused by unknown user
            // id or bad strPassword.
            strError = ex.Message;
        }
        finally
        {
            adsEntry.Close();
        }
    }
}

উইন্ডোজ প্রমাণীকরণ বিভিন্ন কারণে ব্যর্থ হতে পারে: একটি ভুল ব্যবহারকারী নাম বা পাসওয়ার্ড, একটি লক অ্যাকাউন্ট, একটি মেয়াদ শেষ হওয়া পাসওয়ার্ড, এবং আরও অনেক কিছু। এই ত্রুটিগুলির মধ্যে পার্থক্য করতে, P / Invoke এর মাধ্যমে LogonUser API ফাংশনটি কল করুন এবং ফাংশনটি false ফেরত দিলে ত্রুটির কোডটি পরীক্ষা করুন:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

using Microsoft.Win32.SafeHandles;

public static class Win32Authentication
{
    private class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle() // called by P/Invoke
            : base(true)
        {
        }

        protected override bool ReleaseHandle()
        {
            return CloseHandle(this.handle);
        }
    }

    private enum LogonType : uint
    {
        Network = 3, // LOGON32_LOGON_NETWORK
    }

    private enum LogonProvider : uint
    {
        WinNT50 = 3, // LOGON32_PROVIDER_WINNT50
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool LogonUser(
        string userName, string domain, string password,
        LogonType logonType, LogonProvider logonProvider,
        out SafeTokenHandle token);

    public static void AuthenticateUser(string userName, string password)
    {
        string domain = null;
        string[] parts = userName.Split('\\');
        if (parts.Length == 2)
        {
            domain = parts[0];
            userName = parts[1];
        }

        SafeTokenHandle token;
        if (LogonUser(userName, domain, password, LogonType.Network, LogonProvider.WinNT50, out token))
            token.Dispose();
        else
            throw new Win32Exception(); // calls Marshal.GetLastWin32Error()
    }
}

নমুনা ব্যবহার:

try
{
    Win32Authentication.AuthenticateUser("EXAMPLE\\user", "[email protected]");
    // Or: Win32Authentication.AuthenticateUser("[email protected]", "[email protected]");
}
catch (Win32Exception ex)
{
    switch (ex.NativeErrorCode)
    {
        case 1326: // ERROR_LOGON_FAILURE (incorrect user name or password)
            // ...
        case 1327: // ERROR_ACCOUNT_RESTRICTION
            // ...
        case 1330: // ERROR_PASSWORD_EXPIRED
            // ...
        case 1331: // ERROR_ACCOUNT_DISABLED
            // ...
        case 1907: // ERROR_PASSWORD_MUST_CHANGE
            // ...
        case 1909: // ERROR_ACCOUNT_LOCKED_OUT
            // ...
        default: // Other
            break;
    }
}

দ্রষ্টব্য: লগঅনউসারের পক্ষে আপনি যে ডোমেনের বিরুদ্ধে বৈধতা দিচ্ছেন তার সাথে একটি বিশ্বস্ত সম্পর্কের প্রয়োজন।


এই কোডটি চেষ্টা করুন (দ্রষ্টব্য: উইন্ডোজ সার্ভার 2000 তে কাজ না করার জন্য রিপোর্ট করা হয়েছে)

#region NTLogonUser
#region Direct OS LogonUser Code
[DllImport( "advapi32.dll")]
private static extern bool LogonUser(String lpszUsername, 
    String lpszDomain, String lpszPassword, int dwLogonType, 
    int dwLogonProvider, out int phToken);

[DllImport("Kernel32.dll")]
private static extern int GetLastError();

public static bool LogOnXP(String sDomain, String sUser, String sPassword)
{
   int token1, ret;
   int attmpts = 0;

   bool LoggedOn = false;

   while (!LoggedOn && attmpts < 2)
   {
      LoggedOn= LogonUser(sUser, sDomain, sPassword, 3, 0, out token1);
      if (LoggedOn) return (true);
      else
      {
         switch (ret = GetLastError())
         {
            case (126): ; 
               if (attmpts++ > 2)
                  throw new LogonException(
                      "Specified module could not be found. error code: " + 
                      ret.ToString());
               break;

            case (1314): 
               throw new LogonException(
                  "Specified module could not be found. error code: " + 
                      ret.ToString());

            case (1326): 
               // edited out based on comment
               //  throw new LogonException(
               //   "Unknown user name or bad password.");
            return false;

            default: 
               throw new LogonException(
                  "Unexpected Logon Failure. Contact Administrator");
              }
          }
       }
   return(false);
}
#endregion Direct Logon Code
#endregion NTLogonUser

ব্যতীত আপনাকে "LogonException" এর জন্য নিজের নিজস্ব কাস্টম ব্যতিক্রম তৈরি করতে হবে


এখানে উপস্থাপিত বেশ কয়েকটি সমাধান একটি ভুল ব্যবহারকারী / পাসওয়ার্ডের মধ্যে পার্থক্য করার ক্ষমতা, এবং একটি পাসওয়ার্ড যা পরিবর্তন করতে হবে তার অভাব রয়েছে। যে নিম্নলিখিত ভাবে সম্পন্ন করা যেতে পারে:

using System;
using System.DirectoryServices.Protocols;
using System.Net;

namespace ProtocolTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                LdapConnection connection = new LdapConnection("ldap.fabrikam.com");
                NetworkCredential credential = new NetworkCredential("user", "password");
                connection.Credential = credential;
                connection.Bind();
                Console.WriteLine("logged in");
            }
            catch (LdapException lexc)
            {
                String error = lexc.ServerErrorMessage;
                Console.WriteLine(lexc);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
            }
        }
    }
}

ব্যবহারকারীর পাসওয়ার্ড ভুল হলে, অথবা ব্যবহারকারী বিদ্যমান নেই, ত্রুটি থাকবে

"8009030C: LdapErr: DSID-0C0904DC, মন্তব্য: AcceptSecurityContext ত্রুটি, তথ্য 52e, v1db1",

ব্যবহারকারীর পাসওয়ার্ড পরিবর্তন করা প্রয়োজন, এটা থাকবে

"8009030C: LdapErr: DSID-0C0904DC, মন্তব্য: AcceptSecurityContext ত্রুটি, তথ্য 773, v1db1"

lexc.ServerErrorMessage ডেটা মান Win32 ত্রুটি কোডের হেক্স উপস্থাপনা। এটি একই ত্রুটির কোড যা অন্যথায় Win32 LogonUser API কলটি আমন্ত্রিত করে ফেরত পাঠানো হবে। নিচের তালিকাটি হ্যাক এবং দশমিক মানগুলির সাথে সাধারণ মানগুলির একটি পরিসর সংক্ষেপ করে:

525 user not found ​(1317)
52e invalid credentials ​(1326)
530 not permitted to logon at this time (1328)
531 not permitted to logon at this workstation (1329)
532 password expired ​(1330)
533 account disabled ​(1331) 
701 account expired ​(1793)
773 user must reset password (1907)
775 user account locked (1909)

তবুও অন্য একটি .NET কল দ্রুত LDAP শংসাপত্র প্রমাণীকরণ:

using System.DirectoryServices;

using(var DE = new DirectoryEntry(path, username, password)
{
    try
    {
        DE.RefreshCache(); // This will force credentials validation
    }
    catch (COMException ex)
    {
        // Validation failed - handle how you want
    }
}

যদি আপনি .NET 2.0 এবং পরিচালিত কোডের সাথে আটকে থাকেন তবে এখানে অন্য একটি উপায় রয়েছে যা স্থানীয় এবং ডোমেন অ্যাকাউন্টগুলির সাথে কাজ করে:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Diagnostics;

static public bool Validate(string domain, string username, string password)
{
    try
    {
        Process proc = new Process();
        proc.StartInfo = new ProcessStartInfo()
        {
            FileName = "no_matter.xyz",
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
            UseShellExecute = false,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            LoadUserProfile = true,
            Domain = String.IsNullOrEmpty(domain) ? "" : domain,
            UserName = username,
            Password = Credentials.ToSecureString(password)
        };
        proc.Start();
        proc.WaitForExit();
    }
    catch (System.ComponentModel.Win32Exception ex)
    {
        switch (ex.NativeErrorCode)
        {
            case 1326: return false;
            case 2: return true;
            default: throw ex;
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }

    return false;
}   

সম্ভবত সহজ উপায় PInvoke LogonUser Win32 API.eg হয়

http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html

এখানে এমএসডিএন রেফারেন্স ...

http://msdn.microsoft.com/en-us/library/aa378184.aspx

নিশ্চিতভাবে লগন টাইপ ব্যবহার করতে চান

LOGON32_LOGON_NETWORK (3)

এটি শুধুমাত্র একটি লাইটওয়েট টোকেন তৈরি করে - AuthN চেকগুলির জন্য উপযুক্ত। (অন্যান্য ধরনের ইন্টারেক্টিভ সেশন ইত্যাদি নির্মাণ করতে ব্যবহার করা যেতে পারে)





active-directory