Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show authentication dialog in C# .Net 3.5 SP1

I'd like to access network shared files. How do I show the system authentication dialog box so that user can enter username and password?

ps: Through UNC, In WinForm.

I'm writing a explore control, I'd like to show the dialog after the user double click on a network shared folder.

like image 898
zunyite Avatar asked Oct 20 '09 17:10

zunyite


2 Answers

Not sure if I understand you correctly, you want to show the windows authentication dialog?

Try this:

    /// <summary>
/// Leverages the windows UI to prompt for a password
/// </summary>
internal static class Authentication
{
    public struct CREDUI_INFO
    {
        public int cbSize;
        public IntPtr hwndParent;
        public string pszMessageText;
        public string pszCaptionText;
        public IntPtr hbmBanner;
    }

    [DllImport("credui")]
    private static extern CredUIReturnCodes CredUIPromptForCredentials(ref CREDUI_INFO creditUR,
          string targetName,
          IntPtr reserved1,
          int iError,
          StringBuilder userName,
          int maxUserName,
          StringBuilder password,
          int maxPassword,
          [MarshalAs(UnmanagedType.Bool)] ref bool pfSave,
          CREDUI_FLAGS flags);

    [Flags]
    enum CREDUI_FLAGS
    {
        INCORRECT_PASSWORD = 0x1,
        DO_NOT_PERSIST = 0x2,
        REQUEST_ADMINISTRATOR = 0x4,
        EXCLUDE_CERTIFICATES = 0x8,
        REQUIRE_CERTIFICATE = 0x10,
        SHOW_SAVE_CHECK_BOX = 0x40,
        ALWAYS_SHOW_UI = 0x80,
        REQUIRE_SMARTCARD = 0x100,
        PASSWORD_ONLY_OK = 0x200,
        VALIDATE_USERNAME = 0x400,
        COMPLETE_USERNAME = 0x800,
        PERSIST = 0x1000,
        SERVER_CREDENTIAL = 0x4000,
        EXPECT_CONFIRMATION = 0x20000,
        GENERIC_CREDENTIALS = 0x40000,
        USERNAME_TARGET_CREDENTIALS = 0x80000,
        KEEP_USERNAME = 0x100000,
    }

    public enum CredUIReturnCodes
    {
        NO_ERROR = 0,
        ERROR_CANCELLED = 1223,
        ERROR_NO_SUCH_LOGON_SESSION = 1312,
        ERROR_NOT_FOUND = 1168,
        ERROR_INVALID_ACCOUNT_NAME = 1315,
        ERROR_INSUFFICIENT_BUFFER = 122,
        ERROR_INVALID_PARAMETER = 87,
        ERROR_INVALID_FLAGS = 1004,
    }

    /// <summary>
    /// Prompts for password.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <param name="password">The password.</param>
    /// <returns>True if no errors.</returns>
    internal static bool PromptForPassword(out string user, out string password)
    {
        // Setup the flags and variables
        StringBuilder userPassword = new StringBuilder(), userID = new StringBuilder();
        CREDUI_INFO credUI = new CREDUI_INFO();
        credUI.cbSize = Marshal.SizeOf(credUI);
        bool save = false;
        CREDUI_FLAGS flags = CREDUI_FLAGS.ALWAYS_SHOW_UI | CREDUI_FLAGS.GENERIC_CREDENTIALS;

        // Prompt the user
        CredUIReturnCodes returnCode = CredUIPromptForCredentials(ref credUI, Application.ProductName, IntPtr.Zero, 0, userID, 100, userPassword, 100, ref save, flags);

        user = userID.ToString();
        password = userPassword.ToString();

        return (returnCode == CredUIReturnCodes.NO_ERROR);
    }
}

Using the credentials obtained with this dialog, you could then call LogonUser as explained by Phil Harding here.

like image 166
Philip Wallace Avatar answered Sep 30 '22 10:09

Philip Wallace


How do you currently access the share? Through a UNC or do you first map it to a drive letter? One idea is to map it with the wnetaddconnection2 api call with the CONNECT_INTERACTIVE and CONNECT_PROMPT flags.

like image 45
Mark Avatar answered Sep 30 '22 11:09

Mark