private string GetUserPrincipalName(int nameFormat) { if (DesktopOsHelper.IsWindows()) { uint userNameSize = 0; WindowsNativeMethods.GetUserNameEx(nameFormat, null, ref userNameSize); if (userNameSize == 0) { throw new MsalClientException( MsalError.GetUserNameFailed, MsalErrorMessage.GetUserNameFailed, new Win32Exception(Marshal.GetLastWin32Error())); } var sb = new StringBuilder((int)userNameSize); if (!WindowsNativeMethods.GetUserNameEx(nameFormat, sb, ref userNameSize)) { throw new MsalClientException( MsalError.GetUserNameFailed, MsalErrorMessage.GetUserNameFailed, new Win32Exception(Marshal.GetLastWin32Error())); } return(sb.ToString()); } throw new PlatformNotSupportedException( "MSAL cannot determine the username (UPN) of the currently logged in user." + "For Integrated Windows Authentication and Username/Password flows, please use .WithUsername() before calling ExecuteAsync(). " + "For more details see https://aka.ms/msal-net-iwa"); }
public bool IsBrokerInstalledAndInvokable() { #if NET_CORE if (!DesktopOsHelper.IsWindows()) { return(false); } #endif // WAM is present on Win 10 only return(ApiInformation.IsMethodPresent( "Windows.Security.Authentication.Web.Core.WebAuthenticationCoreManager", "GetTokenSilentlyAsync")); }
public SspiSecurityContext( Credential credential, string package, long logonId = 0, InitContextFlag clientFlags = _defaultRequiredFlags) { if (!DesktopOsHelper.IsWindows()) { throw new PlatformNotSupportedException("Ticket Cache interface is not supported for this OS platform."); } _credential = credential; _clientFlags = clientFlags; Package = package; _logonId = logonId; }
/// <summary> /// Reads a Kerberos Service Ticket associated with given service principal name from /// current user's Ticket Cache. /// </summary> /// <param name="servicePrincipalName">Service principal name to find associated Kerberos Ticket.</param> /// <param name="logonId">The Logon Id of the user owning the ticket cache. /// The default of 0 represents the currently logged on user.</param> /// <returns>Byte stream of searched Kerberos Ticket information if exists. Null, otherwise.</returns> /// <remarks> /// Can throws <see cref="Win32Exception"/> if error occurs while searching ticket information from Ticket Cache. /// </remarks> public static byte[] GetKerberosTicketFromWindowsTicketCache(string servicePrincipalName, long logonId) { #if !SUPPORTS_WIN32 throw new PlatformNotSupportedException("Ticket Cache interface is not supported for this .NET platform. It is supported on .NET Classic, .NET Core and NetStandadrd"); #else if (!DesktopOsHelper.IsWindows()) { throw new PlatformNotSupportedException("Ticket Cache interface is not supported on this OS. It is supported on Windows only."); } using (var reader = new Platforms.Features.DesktopOs.Kerberos.TicketCacheReader(servicePrincipalName, logonId)) { return(reader.RequestToken()); } #endif }
/// <summary> /// Brokers enable Single-Sign-On, device identification, /// and application identification verification. To enable one of these features, /// you need to set the WithBroker() parameters to true. See https://aka.ms/msal-net-brokers /// for more information on platform specific settings required to enable the broker. /// /// On iOS and Android, Authenticator and Company Portal serve as brokers. /// On Windows, WAM (Windows Account Manager) serves as broker. See https://aka.ms/msal-net-wam /// </summary> /// <param name="enableBroker">Determines whether or not to use broker with the default set to true.</param> /// <returns>A <see cref="PublicClientApplicationBuilder"/> from which to set more /// parameters, and to create a public client application instance</returns> /// <remarks>If your app uses .NET classic or .NET Core 3.x, and you wish to use the Windows broker, /// please install the nuget package Microsoft.Identity.Client.Desktop and call .WithDesktopFeatures()</remarks> public PublicClientApplicationBuilder WithBroker(bool enableBroker = true) { #pragma warning disable CS0162 // Unreachable code detected #if NET45 throw new PlatformNotSupportedException( "The Windows broker is not available on .NET Framework 4.5, please use at least .NET Framework 4.6.2"); #endif #if NET461 if (Config.BrokerCreatorFunc == null) { throw new PlatformNotSupportedException( "The Windows broker is not directly available on MSAL for .NET Framework" + " To use it, please install the nuget package named Microsoft.Identity.Client.Desktop " + "and call the extension method .WithWindowsBroker() first."); } #endif #if NET_CORE if (Config.BrokerCreatorFunc == null && DesktopOsHelper.IsWindows()) { throw new PlatformNotSupportedException( "If you have a Windows application which targets net5 or net5-windows, please change the target to net5-windows10.0.17763.0. \nYour app can still run on earlier versions of Windows such as Win7 if you add <SupportedOSPlatformVersion>7</SupportedOSPlatformVersion> in the csproj.\n The broker (WAM) is available only on Win10 and this library will fallback to a browser on older systems. " + "\n\r\n\rIf you have a NET5 cross-platform (Windows, Mac, Linux) application, please dual target net5 and net5-windows10.0.17763.0. Your installer should deploy the net5 version on Mac and Linux and the net5-window10.0.17763.0 on Windows." + "\n\r\n\rIf you have a .NET Core 3.1 application, please install the nuget package named Microsoft.Identity.Client.Desktop and call the extension method .WithWindowsBroker() first. " + "\n\rFor details see https://aka.ms/msal-net-wam and https://github.com/dotnet/designs/blob/main/accepted/2020/platform-checks/platform-checks.md "); } #endif #if NET461 || WINDOWS_APP || NET5_WIN if (!Config.ExperimentalFeaturesEnabled) { throw new MsalClientException( MsalError.ExperimentalFeature, MsalErrorMessage.ExperimentalFeature(nameof(WithBroker))); } #endif Config.IsBrokerEnabled = enableBroker; return(this); #pragma warning restore CS0162 // Unreachable code detected }
/// <summary> /// Brokers enable Single-Sign-On, device identification, /// and application identification verification. To enable one of these features, /// you need to set the WithBroker() parameters to true. See https://aka.ms/msal-net-brokers /// for more information on platform specific settings required to enable the broker. /// /// On iOS and Android, Authenticator and Company Portal serve as brokers. /// On Windows, WAM (Windows Account Manager) serves as broker. See https://aka.ms/msal-net-wam /// </summary> /// <param name="enableBroker">Determines whether or not to use broker with the default set to true.</param> /// <returns>A <see cref="PublicClientApplicationBuilder"/> from which to set more /// parameters, and to create a public client application instance</returns> /// <remarks>If your app uses .NET classic or .NET Core 3.x, and you wish to use the Windows broker, /// please install the nuget package Microsoft.Identity.Client.Desktop and call .WithDesktopFeatures()</remarks> public PublicClientApplicationBuilder WithBroker(bool enableBroker = true) { #pragma warning disable CS0162 // Unreachable code detected #if NET45 throw new PlatformNotSupportedException( "The Windows broker is not available on .NET Framework 4.5, please use at least .NET Framework 4.6.2"); #endif #if NET461 if (Config.BrokerCreatorFunc == null) { throw new PlatformNotSupportedException( "The Windows broker is not directly available on MSAL for .NET Framework" + " To use it, please install the nuget package named Microsoft.Identity.Client.Desktop " + "and call the extension method .WithDesktopFeatures() first."); } #endif #if NET_CORE if (Config.BrokerCreatorFunc == null && DesktopOsHelper.IsWindows()) { throw new PlatformNotSupportedException( "If you have a Windows application which targets net5 or net5-windows, please change the target to net5-windows10.0.17763.0, which provides support from Win7 to Win10. For details see https://github.com/dotnet/designs/blob/main/accepted/2020/platform-checks/platform-checks.md" + "If you have a cross-platform (Windows, Mac, Linux) application which targets net5, please dual target net5 and net5-windows10.0.17763.0. Your installer should deploy the net5 version on Mac and Linux and the net5-window10.0.17763.0 on Win7-Win10. For details see https://github.com/dotnet/designs/blob/main/accepted/2020/platform-checks/platform-checks.md" + "If you have a .NET Core 3.1 application, please install the nuget package named Microsoft.Identity.Client.Desktop and call the extension method .WithDesktopFeatures() first."); } #endif #if NET461 || WINDOWS_APP || NET5_WIN if (!Config.ExperimentalFeaturesEnabled) { throw new MsalClientException( MsalError.ExperimentalFeature, MsalErrorMessage.ExperimentalFeature(nameof(WithBroker))); } #endif Config.IsBrokerEnabled = enableBroker; return(this); #pragma warning restore CS0162 // Unreachable code detected }
/// <summary> /// Save current Kerberos Ticket to current user's Ticket Cache. Windows only. /// </summary> /// <param name="ticket">Kerberos ticket object to save.</param> /// <param name="logonId">The Logon Id of the user owning the ticket cache. /// The default of 0 represents the currently logged on user.</param> /// <remarks>Can throw <see cref="ArgumentException"/> when given ticket parameter is not a valid Kerberos Supplemental Ticket. /// Can throw <see cref="Win32Exception"/> if error occurs while saving ticket information into Ticket Cache. /// </remarks> public static void SaveToWindowsTicketCache(KerberosSupplementalTicket ticket, long logonId) { #if !SUPPORTS_WIN32 throw new PlatformNotSupportedException("Ticket Cache interface is not supported for this .NET platform. It is supported on .NET Classic, .NET Core and NetStandadrd"); #else if (!DesktopOsHelper.IsWindows()) { throw new PlatformNotSupportedException("Ticket Cache interface is not supported on this OS. It is supported on Windows only."); } if (ticket == null || string.IsNullOrEmpty(ticket.KerberosMessageBuffer)) { throw new ArgumentException("Kerberos Ticket information is not valid"); } using (var cache = Platforms.Features.DesktopOs.Kerberos.TicketCacheWriter.Connect()) { byte[] krbCred = Convert.FromBase64String(ticket.KerberosMessageBuffer); cache.ImportCredential(krbCred, logonId); } #endif }
public bool IsBrokerInstalledAndInvokable(AuthorityType authorityType) { #if NET_CORE if (!DesktopOsHelper.IsWindows()) { _logger.Info("[WAM Broker] Not a Windows operating system. WAM broker is not available. "); return(false); } #endif // WAM does not work on pure ADFS environments if (authorityType == AuthorityType.Adfs) { _logger.Info("[WAM Broker] WAM does not work in pure ADFS environments. Falling back to browser for an ADFS authority. "); return(false); } _logger.Info("[WAM Broker] Authority is AAD. Using WAM Broker. "); // WAM is present on Win 10 only return(ApiInformation.IsMethodPresent( "Windows.Security.Authentication.Web.Core.WebAuthenticationCoreManager", "GetTokenSilentlyAsync")); }
/// <summary> /// Validates Windows Ticket Cache interface for the given <see cref="KerberosSupplementalTicket"/> Kerberos Ticket. /// </summary> /// <param name="ticket">A <see cref="KerberosSupplementalTicket"/> object to be checked.</param> public static void ValidateKerberosWindowsTicketCacheOperation(KerberosSupplementalTicket ticket) { if (DesktopOsHelper.IsWindows()) { // First, save the given Kerberos Ticket (with KRB-CRED format) into the Windows Ticket Cache. // Windows Ticket Cache decrypts the given Kerberos Ticket with KRB-CRED format, re-encrypt with it's // credential and save it as AP-REQ format. KerberosSupplementalTicketManager.SaveToWindowsTicketCache(ticket); // Read-back saved Ticket data. byte[] ticketBytes = KerberosSupplementalTicketManager.GetKerberosTicketFromWindowsTicketCache(ticket.ServicePrincipalName); Assert.IsNotNull(ticketBytes); // To validate public field of AP-REQ format Kerberos Ticket, convert binary ticket data as a printable string format. StringBuilder sb = new StringBuilder(); foreach (byte ch in ticketBytes) { if (ch >= 32 && ch < 127) { sb.Append((char)ch); } else { sb.Append('*'); } } string ticketAsString = sb.ToString(); // Check the Azure AD Kerberos Realm string exists. Assert.IsTrue(ticketAsString.IndexOf(TestConstants.AzureADKerberosRealmName) >= 0); // Check the ticket has matched Kerberos Service Principal Name. Assert.IsTrue(ticketAsString.IndexOf(TestConstants.KerberosServicePrincipalNameEscaped, StringComparison.OrdinalIgnoreCase) >= 0); } }
public override Task StartDefaultOsBrowserAsync(string url) { if (DesktopOsHelper.IsWindows()) { try { var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; Process.Start(psi); } catch { // hack because of this: https://github.com/dotnet/corefx/issues/10361 url = url.Replace("&", "^&"); Process.Start(new ProcessStartInfo("cmd", $"/c start msedge {url}") { CreateNoWindow = true }); } } else if (DesktopOsHelper.IsLinux()) { try { ProcessStartInfo psi = null; foreach (string openTool in new[] { "xdg-open", "gnome-open", "kfmclient" }) { if (TryGetExecutablePath(openTool, out string openToolPath)) { psi = new ProcessStartInfo(openToolPath, url) { RedirectStandardOutput = true, RedirectStandardError = true }; Process.Start(psi); break; } } if (psi == null) { throw new Exception("Failed to locate a utility to launch the default web browser."); } } catch (Exception ex) { throw new MsalClientException( MsalError.LinuxXdgOpen, MsalErrorMessage.LinuxOpenToolFailed, ex); } } else if (DesktopOsHelper.IsMac()) { Process.Start("/usr/bin/open", url); } else { throw new PlatformNotSupportedException(RuntimeInformation.OSDescription); } return(Task.FromResult(0)); }
protected override string InternalGetProcessorArchitecture() { return(DesktopOsHelper.IsWindows() ? WindowsNativeMethods.GetProcessorArchitecture() : null); }
public override Task StartDefaultOsBrowserAsync(string url, bool isBrokerConfigured) { if (DesktopOsHelper.IsWindows()) { try { var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; Process.Start(psi); } catch { // hack because of this: https://github.com/dotnet/corefx/issues/10361 url = url.Replace("&", "^&"); Process.Start(new ProcessStartInfo("cmd", $"/c start msedge {url}") { CreateNoWindow = true }); } } else if (DesktopOsHelper.IsLinux()) { string sudoUser = Environment.GetEnvironmentVariable("SUDO_USER"); if (!string.IsNullOrWhiteSpace(sudoUser)) { throw new MsalClientException( MsalError.LinuxXdgOpen, MsalErrorMessage.LinuxOpenAsSudoNotSupported); } try { bool opened = false; foreach (string openTool in GetOpenToolsLinux(isBrokerConfigured)) { if (TryGetExecutablePath(openTool, out string openToolPath)) { OpenLinuxBrowser(openToolPath, url); opened = true; break; } } if (!opened) { throw new MsalClientException( MsalError.LinuxXdgOpen, MsalErrorMessage.LinuxOpenToolFailed); } } catch (Exception ex) { throw new MsalClientException( MsalError.LinuxXdgOpen, MsalErrorMessage.LinuxOpenToolFailed, ex); } } else if (DesktopOsHelper.IsMac()) { Process.Start("/usr/bin/open", url); } else { throw new PlatformNotSupportedException(RuntimeInformation.OSDescription); } return(Task.FromResult(0)); }