Switch from XAML Provider from DependencyObject to Behavior

This commit is contained in:
michael-hawker 2019-10-19 14:39:34 -07:00
Родитель 91689f77de
Коммит 263119fb34
8 изменённых файлов: 88 добавлений и 113 удалений

Просмотреть файл

@ -7,9 +7,9 @@ using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Graph.Providers
{
/// <summary>
/// Properties for <see cref="CommonProviderWrapper"/>.
/// Properties for <see cref="CommonProviderBehaviorBase"/>.
/// </summary>
public partial class CommonProviderWrapper
public partial class CommonProviderBehaviorBase
{
/// <summary>
/// Gets or sets the Client ID (the unique application (client) ID assigned to your app by Azure AD when the app was registered).
@ -31,7 +31,7 @@ namespace Microsoft.Toolkit.Graph.Providers
/// The identifier for the <see cref="ClientId"/> dependency property.
/// </returns>
public static readonly DependencyProperty ClientIdProperty =
DependencyProperty.Register(nameof(ClientId), typeof(string), typeof(InteractiveProvider), new PropertyMetadata(string.Empty, ClientIdPropertyChanged));
DependencyProperty.Register(nameof(ClientId), typeof(string), typeof(CommonProviderBehaviorBase), new PropertyMetadata(string.Empty));
/// <summary>
/// Gets or sets the redirect URI (the URI the identity provider will send the security tokens back to).
@ -49,7 +49,7 @@ namespace Microsoft.Toolkit.Graph.Providers
/// The identifier for the <see cref="RedirectUri"/> dependency property.
/// </returns>
public static readonly DependencyProperty RedirectUriProperty =
DependencyProperty.Register(nameof(RedirectUri), typeof(string), typeof(CommonProviderWrapper), new PropertyMetadata("https://login.microsoftonline.com/common/oauth2/nativeclient"));
DependencyProperty.Register(nameof(RedirectUri), typeof(string), typeof(CommonProviderBehaviorBase), new PropertyMetadata("https://login.microsoftonline.com/common/oauth2/nativeclient"));
/// <summary>
/// Gets or sets the list of Scopes (permissions) to request on initial login.

Просмотреть файл

@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp.UI.Behaviors;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Graph.Providers
{
/// <summary>
/// Provides a common base class for UWP XAML based provider wrappers to the Microsoft.Graph.Auth SDK.
/// </summary>
public abstract partial class CommonProviderBehaviorBase : BehaviorBase<FrameworkElement>
{
}
}

Просмотреть файл

@ -1,62 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Graph;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Graph.Providers
{
/// <summary>
/// Provides a common base class for UWP XAML based provider wrappers to the Microsoft.Graph.Auth SDK.
/// </summary>
public abstract partial class CommonProviderWrapper : DependencyObject
{
private static async void ClientIdPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is CommonProviderWrapper provider)
{
await provider.InitializeAsync();
}
}
/// <summary>
/// Called by developers to easily initialize MSAL and a Provider when calling from WPF via XAML Islands.
/// </summary>
/// <typeparam name="T">CommonProvider type to initialize</typeparam>
/// <param name="clientId">Optional shortcut to initialize the ClientId parameter</param>
/// <param name="redirectUri">Optional shortcut to initialize the RedirectUri parameter</param>
/// <returns>New <see cref="CommonProviderWrapper"/> instance.</returns>
public static async Task<T> InitializeAsync<T>(string clientId = null, string redirectUri = null)
where T : CommonProviderWrapper, new()
{
var provider = new T
{
ClientId = clientId,
RedirectUri = redirectUri
};
await provider.InitializeAsync();
return provider;
}
/// <summary>
/// Used by controls to request the additional scopes they require.
/// </summary>
/// <param name="scopes">Scopes to request</param>
public void RequestAdditionalScopes(params string[] scopes)
{
Scopes.AddRange(scopes);
}
/// <summary>
/// Called when provider is initialized from XAML (UWP Only).
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
protected abstract Task InitializeAsync();
}
}

Просмотреть файл

@ -1,35 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Toolkit.Graph.Providers
{
/// <summary>
/// Put in app.xaml resources with ClientId
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively
/// </summary>
/// <example>
/// <code>
/// &lt;wgt:InteractiveProvider x:Key="MyProvider" ClientId="MyClientIdGuid"/%gt;
/// </code>
/// </example>
public class InteractiveProvider : CommonProviderWrapper
{
/// <summary>
/// Initializes a new instance of the <see cref="InteractiveProvider"/> class.
/// </summary>
public InteractiveProvider()
{
}
/// <inheritdoc/>
protected override async Task InitializeAsync()
{
ProviderManager.Instance.GlobalProvider =
await QuickCreate.CreateMsalProviderAsync(ClientId, RedirectUri, Scopes.ToArray());
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
using Windows.UI.Core;
namespace Microsoft.Toolkit.Graph.Providers
{
/// <summary>
/// Put in a xaml page with ClientId
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively
/// </summary>
/// <example>
/// <code>
/// &lt;Interactivity:Interaction.Behaviors&gt;
/// &lt;providers:InteractiveProviderBehavior ClientId = "MyClientIdGuid"/&gt;
/// &lt;/Interactivity:Interaction.Behaviors&gt;
/// </code>
/// </example>
public class InteractiveProviderBehavior : CommonProviderBehaviorBase
{
private object lock_sync = new object();
private bool initialized = false;
/// <inheritdoc/>
protected override bool Initialize()
{
lock (lock_sync)
{
if (!initialized)
{
_ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
ProviderManager.Instance.GlobalProvider =
await QuickCreate.CreateMsalProviderAsync(ClientId, RedirectUri, Scopes.ToArray());
});
}
}
return base.Initialize();
}
}
}

Просмотреть файл

@ -34,16 +34,17 @@ Install-Package Microsoft.Toolkit.Graph.Controls -IncludePrerelease
<!-- TODO: Update instructions later to single PMC line when https://github.com/NuGet/Home/issues/7189 is fixed. -->
Then open your `App.xaml` file and add the following resource:
Then open your `MainPage.xaml` file and add the following behavior:
```xml
<Application
<Page
...
xmlns:wgt="using:Microsoft.Toolkit.Graph.Providers">
<Application.Resources>
<wgt:InteractiveProvider x:Key="MyProvider" ClientId="YOUR_CLIENT_ID_HERE" Scopes="User.Read,User.ReadBasic.All,People.Read"/>
</Application.Resources>
</Application>
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:providers="using:Microsoft.Toolkit.Graph.Providers">
<Interactivity:Interaction.Behaviors>
<providers:InteractiveProviderBehavior ClientId="YOUR_CLIENT_ID_HERE" Scopes="User.Read,User.ReadBasic.All,People.Read"/>
</Interactivity:Interaction.Behaviors>
</Page>
```
You can use the `Scopes` property to preemptively request permissions from the user of your app for data your app needs to access from Microsoft Graph.

Просмотреть файл

@ -2,9 +2,6 @@
x:Class="SampleTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest"
xmlns:wgt="using:Microsoft.Toolkit.Graph.Providers">
<Application.Resources>
<wgt:InteractiveProvider x:Key="MyProvider" ClientId="YOUR_CLIENT_ID_HERE" Scopes="User.Read,User.ReadBasic.All,People.Read"/>
</Application.Resources>
xmlns:local="using:SampleTest">
</Application>

Просмотреть файл

@ -7,8 +7,21 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wgt="using:Microsoft.Toolkit.Graph.Controls"
xmlns:graph="using:Microsoft.Graph"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:providers="using:Microsoft.Toolkit.Graph.Providers"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!--
Initialize Graph Provider On Page Load
Register Client Id: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
After finishing the initial registration page, you will also need to add an additional redirect URI.
Click on "Add a Redirect URI" and check the https://login.microsoftonline.com/common/oauth2/nativeclient checkbox on that page. Then click "Save".
-->
<Interactivity:Interaction.Behaviors>
<providers:InteractiveProviderBehavior ClientId="YOUR_CLIENT_ID_HERE" Scopes="User.Read,User.ReadBasic.All,People.Read,Calendars.Read"/>
</Interactivity:Interaction.Behaviors>
<Grid>
<wgt:LoginButton VerticalAlignment="Top" HorizontalAlignment="Right"/>