diff --git a/CommunityToolkit.Authentication.Uwp/AccountsSettingsPaneConfig.cs b/CommunityToolkit.Authentication.Uwp/AccountsSettingsPaneConfig.cs index 0a257fd..e55f5a0 100644 --- a/CommunityToolkit.Authentication.Uwp/AccountsSettingsPaneConfig.cs +++ b/CommunityToolkit.Authentication.Uwp/AccountsSettingsPaneConfig.cs @@ -30,7 +30,7 @@ public struct AccountsSettingsPaneConfig /// /// Gets or sets the WebAccountCommandParameter collection for the account settings pane. /// - public WebAccountCommandParameter AccountCommandParameter { get; set; } + public IList AccountCommandParameters { get; set; } /// /// Initializes a new instance of the struct. @@ -38,17 +38,17 @@ public struct AccountsSettingsPaneConfig /// The header text for the add accounts settings pane. /// The header text for the manage accounts settings pane. /// The SettingsCommand collection for the account settings pane. - /// The WebAccountCommandParameter for the account settings pane. + /// The WebAccountCommandParameter for the account settings pane. public AccountsSettingsPaneConfig( string addAccountHeaderText = null, string manageAccountHeaderText = null, IList commands = null, - WebAccountCommandParameter accountCommandParameter = null) + IList accountCommandParameters = null) { AddAccountHeaderText = addAccountHeaderText; ManageAccountHeaderText = manageAccountHeaderText; Commands = commands; - AccountCommandParameter = accountCommandParameter; + AccountCommandParameters = accountCommandParameters; } } } diff --git a/CommunityToolkit.Authentication.Uwp/WebAccountProviderType.cs b/CommunityToolkit.Authentication.Uwp/WebAccountProviderType.cs index 0efefb6..3f0a1bc 100644 --- a/CommunityToolkit.Authentication.Uwp/WebAccountProviderType.cs +++ b/CommunityToolkit.Authentication.Uwp/WebAccountProviderType.cs @@ -10,13 +10,27 @@ namespace CommunityToolkit.Authentication public enum WebAccountProviderType { /// - /// Authenticate all available accounts. + /// Authenticate any available accounts. + /// Store app association required to support consumer accounts. + /// Client ID required to support organizational accounts. /// - All, + Any, /// - /// Authenticate public/consumer MSA accounts. + /// Authenticate consumer MSA accounts. Store app association required. /// Msa, + + /// + /// Authenticate organizational AAD accounts. Client ID required. + /// + Aad, + + /// + /// Authenticate the active local account regardles of type (consumer/organizational). + /// Store app association required to support consumer accounts. + /// Client ID required to support organizational accounts. + /// + Local, } } diff --git a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs index b80e0ec..8b7ccca 100644 --- a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs +++ b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs @@ -23,7 +23,7 @@ public class WindowsProvider : BaseProvider { /// /// Gets the redirect uri value based on the current app callback uri. - /// Used for configuring in Azure app registration. + /// Used for configuring the Azure app registration. /// public static string RedirectUri => string.Format("ms-appx-web://Microsoft.AAD.BrokerPlugIn/{0}", WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper()); @@ -31,6 +31,8 @@ public class WindowsProvider : BaseProvider private const string GraphResourcePropertyKey = "resource"; private const string GraphResourcePropertyValue = "https://graph.microsoft.com"; private const string MicrosoftAccountAuthority = "consumers"; + private const string AadAuthority = "organizations"; + private const string LocalProviderId = "https://login.windows.local"; private const string MicrosoftProviderId = "https://login.microsoft.com"; private const string SettingsKeyAccountId = "WindowsProvider_AccountId"; private const string SettingsKeyProviderId = "WindowsProvider_ProviderId"; @@ -39,7 +41,8 @@ public class WindowsProvider : BaseProvider private static readonly string[] DefaultScopes = { "User.Read" }; // The default account providers available in the AccountsSettingsPane. - private static readonly WebAccountProviderType DefaultWebAccountsProviderType = WebAccountProviderType.All; + // Default is Msa because it does not require any additional configuration + private static readonly WebAccountProviderType DefaultWebAccountsProviderType = WebAccountProviderType.Msa; /// public override string CurrentAccountId => _webAccount?.Id; @@ -75,7 +78,7 @@ public class WindowsProvider : BaseProvider /// List of Scopes to initially request. /// Configuration values for the AccountsSettingsPane. /// Configuration value for determining the available web account providers. - /// Determines whether the provider attempts to silently log in upon instantionation. + /// Determines whether the provider attempts to silently log in upon construction. public WindowsProvider(string[] scopes = null, WebAccountProviderConfig? webAccountProviderConfig = null, AccountsSettingsPaneConfig? accountsSettingsPaneConfig = null, bool autoSignIn = true) { _scopes = scopes ?? DefaultScopes; @@ -218,14 +221,15 @@ public override async Task GetTokenAsync(bool silentOnly = false, string else { // Authentication response was not successful or cancelled, but is also missing a ResponseError. - throw new Exception("Authentication response was not successful, but is also missing a ResponseError."); + throw new Exception("Token request was not successful, but is also missing an error message."); } } - catch + catch (Exception e) { + // TODO: Log failure + System.Diagnostics.Debug.WriteLine(e.Message); + throw e; } - - return null; } /// @@ -236,12 +240,7 @@ public async Task ShowAccountManagementPaneAsync() { if (_webAccount == null) { - throw new InvalidOperationException("Display account management pane requires at least one logged in account."); - } - - if (_accountsSettingsPaneConfig?.AccountCommandParameter == null) - { - throw new ArgumentNullException("At least one account command is required to display the account management pane."); + throw new InvalidOperationException("A logged in account is required to display the account management pane."); } // Build the AccountSettingsPane and configure it with available account commands. @@ -256,23 +255,28 @@ void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPan e.HeaderText = headerText; } - // Generate account command. - var commandParameter = _accountsSettingsPaneConfig?.AccountCommandParameter; - var webAccountCommand = new WebAccountCommand( + // Generate any account commands. + if (_accountsSettingsPaneConfig?.AccountCommandParameters != null) + { + foreach (var commandParameter in _accountsSettingsPaneConfig?.AccountCommandParameters) + { + var webAccountCommand = new WebAccountCommand( _webAccount, async (command, args) => { - commandParameter.Invoked?.Invoke(command, args); - // When the logout command is triggered, we also need to modify the state of the Provider. if (args.Action == WebAccountAction.Remove) { await SignOutAsync(); } + + commandParameter.Invoked?.Invoke(command, args); }, commandParameter.Actions); - e.WebAccountCommands.Add(webAccountCommand); + e.WebAccountCommands.Add(webAccountCommand); + } + } // Apply any configured setting commands. var commands = _accountsSettingsPaneConfig?.Commands; @@ -297,8 +301,10 @@ void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPan // Show the AccountSettingsPane and wait for the result. await AccountsSettingsPane.ShowManageAccountsAsync(); } - catch (Exception) + catch (Exception e) { + // TODO: Log exception + System.Diagnostics.Debug.WriteLine(e.Message); } finally { @@ -503,9 +509,9 @@ private WebTokenRequest GetWebTokenRequest(WebAccountProvider provider, string c { string scopesString = string.Join(',', scopes); - WebTokenRequest webTokenRequest = clientId != null - ? new WebTokenRequest(provider, scopesString, clientId) - : new WebTokenRequest(provider, scopesString); + WebTokenRequest webTokenRequest = string.IsNullOrWhiteSpace(clientId) + ? new WebTokenRequest(provider, scopesString) + : new WebTokenRequest(provider, scopesString, clientId); webTokenRequest.Properties.Add(GraphResourcePropertyKey, GraphResourcePropertyValue); @@ -517,12 +523,26 @@ private async Task> GetWebAccountProvidersAsync() var providers = new List(); // MSA - if (_webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.All || + if (_webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Any || _webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Msa) { providers.Add(await WebAuthenticationCoreManager.FindAccountProviderAsync(MicrosoftProviderId, MicrosoftAccountAuthority)); } + // AAD + if (_webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Any || + _webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Aad) + { + providers.Add(await WebAuthenticationCoreManager.FindAccountProviderAsync(MicrosoftProviderId, AadAuthority)); + } + + // Local + if (_webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Any || + _webAccountProviderConfig.WebAccountProviderType == WebAccountProviderType.Local) + { + providers.Add(await WebAuthenticationCoreManager.FindAccountProviderAsync(LocalProviderId)); + } + return providers; } } diff --git a/Samples/UwpWindowsProviderSample/App.xaml.cs b/Samples/UwpWindowsProviderSample/App.xaml.cs index eb650fb..8999918 100644 --- a/Samples/UwpWindowsProviderSample/App.xaml.cs +++ b/Samples/UwpWindowsProviderSample/App.xaml.cs @@ -51,16 +51,14 @@ void OnAccountCommandInvoked(WebAccountCommand command, WebAccountInvokedArgs ar var accountCommandParameter = new WebAccountCommandParameter( OnAccountCommandInvoked, - SupportedWebAccountActions.Remove | SupportedWebAccountActions.Manage); + SupportedWebAccountActions.Manage | SupportedWebAccountActions.Remove); var addAccountHeaderText = "Login account"; var manageAccountHeaderText = "Account management"; - return new AccountsSettingsPaneConfig(addAccountHeaderText, manageAccountHeaderText, accountCommandParameter: accountCommandParameter); + return new AccountsSettingsPaneConfig(addAccountHeaderText, manageAccountHeaderText, accountCommandParameters: new List() { accountCommandParameter }); } - - protected override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame;