private Credentials GetUserCredentials(string workspaceName, CancellationToken cancellationToken) { var credui = new CREDUI_INFO { cbSize = Marshal.SizeOf(typeof(CREDUI_INFO)), hwndParent = _coreShell.AppConstants.ApplicationWindowHandle, pszCaptionText = Resources.Info_ConnectingTo.FormatInvariant(workspaceName) }; uint authPkg = 0; IntPtr credStorage = IntPtr.Zero; uint credSize; bool save = true; CredUIWinFlags flags = CredUIWinFlags.CREDUIWIN_CHECKBOX; // For password, use native memory so it can be securely freed. IntPtr passwordStorage = SecurityUtilities.CreatePasswordBuffer(); int inCredSize = 1024; IntPtr inCredBuffer = Marshal.AllocCoTaskMem(inCredSize); try { if (!CredPackAuthenticationBuffer(0, WindowsIdentity.GetCurrent().Name, "", inCredBuffer, ref inCredSize)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error); } var err = CredUIPromptForWindowsCredentials(ref credui, 0, ref authPkg, inCredBuffer, (uint)inCredSize, out credStorage, out credSize, ref save, flags); if (err != 0) { throw new OperationCanceledException(); } StringBuilder userNameBuilder = new StringBuilder(CRED_MAX_USERNAME_LENGTH); int userNameLen = CRED_MAX_USERNAME_LENGTH; StringBuilder domainBuilder = new StringBuilder(CRED_MAX_USERNAME_LENGTH); int domainLen = CRED_MAX_USERNAME_LENGTH; int passLen = CREDUI_MAX_PASSWORD_LENGTH; if (!CredUnPackAuthenticationBuffer(CRED_PACK_PROTECTED_CREDENTIALS, credStorage, credSize, userNameBuilder, ref userNameLen, domainBuilder, ref domainLen, passwordStorage, ref passLen)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(Credentials.CreateCredentials(userNameBuilder.ToString(), SecurityUtilities.SecureStringFromNativeBuffer(passwordStorage), save)); } finally { if (inCredBuffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(inCredBuffer); } if (credStorage != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemUnicode(credStorage); } if (passwordStorage != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemUnicode(passwordStorage); } } }
public async Task <Credentials> GetUserCredentialsAsync(string authority, bool invalidateStoredCredentials) { var showDialog = invalidateStoredCredentials; var credentials = new Credentials(); var passwordStorage = IntPtr.Zero; try { var userNameBuilder = new StringBuilder(CREDUI_MAX_USERNAME_LENGTH + 1); var save = false; var flags = CREDUI_FLAGS_EXCLUDE_CERTIFICATES | CREDUI_FLAGS_PERSIST | CREDUI_FLAGS_EXPECT_CONFIRMATION | CREDUI_FLAGS_GENERIC_CREDENTIALS; if (showDialog) { flags |= CREDUI_FLAGS_ALWAYS_SHOW_UI; } await _coreShellLazy.Value.SwitchToMainThreadAsync(); var credui = new CREDUI_INFO { cbSize = Marshal.SizeOf(typeof(CREDUI_INFO)), hwndParent = _coreShellLazy.Value.AppConstants.ApplicationWindowHandle }; // For password, use native memory so it can be securely freed. passwordStorage = SecurityUtilities.CreatePasswordBuffer(); var err = CredUIPromptForCredentials(ref credui, authority, IntPtr.Zero, 0, userNameBuilder, userNameBuilder.Capacity, passwordStorage, CREDUI_MAX_PASSWORD_LENGTH, ref save, flags); if (err != 0) { throw new OperationCanceledException(); } credentials.UserName = userNameBuilder.ToString(); credentials.Password = SecurityUtilities.SecureStringFromNativeBuffer(passwordStorage); credentials.Password.MakeReadOnly(); } finally { if (passwordStorage != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(passwordStorage); } } return(credentials); }