Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@ public struct AccountsSettingsPaneConfig
/// <summary>
/// Gets or sets the WebAccountCommandParameter collection for the account settings pane.
/// </summary>
public WebAccountCommandParameter AccountCommandParameter { get; set; }
public IList<WebAccountCommandParameter> AccountCommandParameters { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="AccountsSettingsPaneConfig"/> struct.
/// </summary>
/// <param name="addAccountHeaderText">The header text for the add accounts settings pane.</param>
/// <param name="manageAccountHeaderText">The header text for the manage accounts settings pane.</param>
/// <param name="commands">The SettingsCommand collection for the account settings pane.</param>
/// <param name="accountCommandParameter">The WebAccountCommandParameter for the account settings pane.</param>
/// <param name="accountCommandParameters">The WebAccountCommandParameter for the account settings pane.</param>
public AccountsSettingsPaneConfig(
string addAccountHeaderText = null,
string manageAccountHeaderText = null,
IList<SettingsCommand> commands = null,
WebAccountCommandParameter accountCommandParameter = null)
IList<WebAccountCommandParameter> accountCommandParameters = null)
{
AddAccountHeaderText = addAccountHeaderText;
ManageAccountHeaderText = manageAccountHeaderText;
Commands = commands;
AccountCommandParameter = accountCommandParameter;
AccountCommandParameters = accountCommandParameters;
}
}
}
20 changes: 17 additions & 3 deletions CommunityToolkit.Authentication.Uwp/WebAccountProviderType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,27 @@ namespace CommunityToolkit.Authentication
public enum WebAccountProviderType
{
/// <summary>
/// Authenticate all available accounts.
/// Authenticate any available accounts.
/// Store app association required to support consumer accounts.
/// Client ID required to support organizational accounts.
/// </summary>
All,
Any,

/// <summary>
/// Authenticate public/consumer MSA accounts.
/// Authenticate consumer MSA accounts. Store app association required.
/// </summary>
Msa,

/// <summary>
/// Authenticate organizational AAD accounts. Client ID required.
/// </summary>
Aad,

/// <summary>
/// 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.
/// </summary>
Local,
}
}
68 changes: 44 additions & 24 deletions CommunityToolkit.Authentication.Uwp/WindowsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ public class WindowsProvider : BaseProvider
{
/// <summary>
/// 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.
/// </summary>
public static string RedirectUri => string.Format("ms-appx-web://Microsoft.AAD.BrokerPlugIn/{0}", WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper());

private const string AuthenticationHeaderScheme = "Bearer";
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";
Expand All @@ -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;

/// <inheritdoc />
public override string CurrentAccountId => _webAccount?.Id;
Expand Down Expand Up @@ -75,7 +78,7 @@ public class WindowsProvider : BaseProvider
/// <param name="scopes">List of Scopes to initially request.</param>
/// <param name="accountsSettingsPaneConfig">Configuration values for the AccountsSettingsPane.</param>
/// <param name="webAccountProviderConfig">Configuration value for determining the available web account providers.</param>
/// <param name="autoSignIn">Determines whether the provider attempts to silently log in upon instantionation.</param>
/// <param name="autoSignIn">Determines whether the provider attempts to silently log in upon construction.</param>
public WindowsProvider(string[] scopes = null, WebAccountProviderConfig? webAccountProviderConfig = null, AccountsSettingsPaneConfig? accountsSettingsPaneConfig = null, bool autoSignIn = true)
{
_scopes = scopes ?? DefaultScopes;
Expand Down Expand Up @@ -218,14 +221,15 @@ public override async Task<string> 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;
}

/// <summary>
Expand All @@ -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.
Expand All @@ -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;
Expand All @@ -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
{
Expand Down Expand Up @@ -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);

Expand All @@ -517,12 +523,26 @@ private async Task<List<WebAccountProvider>> GetWebAccountProvidersAsync()
var providers = new List<WebAccountProvider>();

// 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;
}
}
Expand Down
6 changes: 2 additions & 4 deletions Samples/UwpWindowsProviderSample/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebAccountCommandParameter>() { accountCommandParameter });
}



protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
Expand Down