Removed Graph Auth reference and moved Msal to own package

This commit is contained in:
Shane Weaver 2021-03-18 12:46:51 -07:00
Родитель 17a4673649
Коммит cb9c2a6414
10 изменённых файлов: 140 добавлений и 57 удалений

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

@ -0,0 +1,26 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Title>Community Toolkit .NET Standard Auth Services</Title>
<Description>
This package includes .NET Standard authentication helpers such as:
- MsalProvider:
</Description>
<PackageTags>Community Toolkit Provider Authentication Auth Msal</PackageTags>
<!-- This is a temporary workaround for https://github.com/dotnet/sdk/issues/955 -->
<DebugType>Full</DebugType>
<Configurations>Debug;Release;CI</Configurations>
<Platforms>AnyCPU;ARM;ARM64;x64;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Identity.Client" Version="4.28.0" />
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="2.18.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Net.Authentication\CommunityToolkit.Net.Authentication.csproj" />
</ItemGroup>
</Project>

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

@ -3,18 +3,18 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
namespace CommunityToolkit.Net.Authentication
namespace CommunityToolkit.Net.Authentication.Msal
{
/// <summary>
/// <a href="https://github.com/AzureAD/microsoft-authentication-library-for-dotnet">MSAL.NET</a> provider helper for tracking authentication state using an <see cref="IAuthenticationProvider"/> class.
/// <a href="https://github.com/AzureAD/microsoft-authentication-library-for-dotnet">MSAL.NET</a> provider helper for tracking authentication state.
/// </summary>
public class MsalProvider : BaseProvider
{
@ -24,32 +24,28 @@ namespace CommunityToolkit.Net.Authentication
protected IPublicClientApplication Client { get; private set; }
/// <summary>
/// Gets the provider used by the graph to manage requests.
/// Gets an array of scopes to use for accessing Graph resources.
/// </summary>
protected IAuthenticationProvider Provider { get; private set; }
protected string[] Scopes { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="MsalProvider"/> class.
/// </summary>
/// <param name="clientid">Registered ClientId.</param>
/// <param name="clientId">Registered ClientId.</param>
/// <param name="redirectUri">RedirectUri for auth response.</param>
/// <param name="scopes">List of Scopes to initially request.</param>
public MsalProvider(string clientid, string redirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient", string[] scopes = null)
public MsalProvider(string clientId, string redirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient", string[] scopes = null)
{
var client = PublicClientApplicationBuilder.Create(clientid)
var client = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount)
.WithRedirectUri(redirectUri)
.WithClientName(ProviderManager.ClientName)
.WithClientVersion(Assembly.GetExecutingAssembly().GetName().Version.ToString())
.Build();
if (scopes == null)
{
scopes = new string[] { string.Empty };
}
Scopes = scopes ?? new string[] { string.Empty };
Client = client;
Provider = new InteractiveAuthenticationProvider(client, scopes);
_ = TrySilentSignInAsync();
}
@ -57,19 +53,23 @@ namespace CommunityToolkit.Net.Authentication
/// <inheritdoc/>
public override async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
AddSdkVersion(request);
IEnumerable<IAccount> accounts = await Client.GetAccountsAsync();
AuthenticationResult authResult;
try
{
await Provider.AuthenticateRequestAsync(request);
authResult = await Client.AcquireTokenSilent(Scopes, accounts.FirstOrDefault()).ExecuteAsync();
}
catch (Exception)
catch (MsalUiRequiredException)
{
// TODO: Catch different types of errors and try and re-auth? Should be handled by Graph Auth Providers.
// Assume we're signed-out on error?
State = ProviderState.SignedOut;
authResult = await Client.AcquireTokenInteractive(Scopes).ExecuteAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
}
return;
if (authResult != null)
{
AddSdkVersion(request);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
}
// Check state after request to see if we're now signed-in.

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

@ -22,8 +22,4 @@
<Configurations>Debug;Release;CI</Configurations>
<Platforms>AnyCPU;ARM;ARM64;x64;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.6" />
</ItemGroup>
</Project>

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

@ -3,15 +3,15 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Graph;
namespace CommunityToolkit.Net.Authentication
{
/// <summary>
/// <see cref="IAuthenticationProvider"/> helper wrapper to expose more states around the authentication process for graph controls.
/// Authentication provider to expose more states around the authentication process for graph controls.
/// </summary>
public interface IProvider : IAuthenticationProvider
public interface IProvider
{
/// <summary>
/// Gets the current login state of the provider.
@ -23,6 +23,13 @@ namespace CommunityToolkit.Net.Authentication
/// </summary>
event EventHandler<ProviderStateChangedEventArgs> StateChanged;
/// <summary>
/// Authenticate an outgoing request.
/// </summary>
/// <param name="request">The request to authenticate.</param>
/// <returns>A task upon completion.</returns>
Task AuthenticateRequestAsync(HttpRequestMessage request);
/// <summary>
/// Login the user.
/// </summary>

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

@ -36,9 +36,12 @@ namespace CommunityToolkit.Net.Graph.Extensions
/// <returns>A GraphServiceClient instance.</returns>
public static GraphServiceClient Graph(this IProvider provider)
{
if (_client == null && provider.State == ProviderState.SignedIn)
if (_client == null && provider?.State == ProviderState.SignedIn)
{
_client = provider != null ? new GraphServiceClient(provider) : null;
_client = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
await provider.AuthenticateRequestAsync(requestMessage);
}));
}
return _client;

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

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Net.Authentication;
using CommunityToolkit.Net.Authentication.Msal;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel;
@ -51,7 +52,6 @@ namespace SampleTest
// Provider config
string clientId = "YOUR_CLIENT_ID_HERE";
string redirectUri = null;
string[] scopes = { "User.Read", "User.ReadBasic.All", "People.Read", "Calendars.Read", "Mail.Read", "Group.Read.All", "ChannelMessage.Read.All" };
switch(_providerType)
@ -63,7 +63,7 @@ namespace SampleTest
//Msal provider
case ProviderType.Msal:
ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId, redirectUri, scopes);
ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId: clientId, scopes: scopes);
break;
}
}

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

@ -78,7 +78,7 @@
<wgt:GraphPresenter Grid.Row="1"
IsCollection="True"
OrderBy="start/dateTime"
RequestBuilder="{x:Bind local:MainPage.GetCalendarViewBuilder(), Mode=OneWay}"
RequestBuilder="{x:Bind CalendarViewBuilder, Mode=OneWay}"
ResponseType="graph:Event">
<wgt:GraphPresenter.QueryOptions>
<!-- Need to create separate Properties as multiple functions not supported in x:Bind see https://github.com/microsoft/microsoft-ui-xaml/issues/2407 -->
@ -139,7 +139,7 @@
</StackPanel>
<wgt:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind local:MainPage.GetMessagesBuilder(), Mode=OneWay}"
RequestBuilder="{x:Bind MessagesBuilder, Mode=OneWay}"
ResponseType="graph:Message">
<wgt:GraphPresenter.ContentTemplate>
<DataTemplate>
@ -187,7 +187,7 @@
</StackPanel>
<wgt:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind local:MainPage.GetPlannerTasksBuilder(), Mode=OneWay}"
RequestBuilder="{x:Bind PlannerTasksBuilder, Mode=OneWay}"
ResponseType="graph:PlannerTask">
<wgt:GraphPresenter.ContentTemplate>
<DataTemplate>
@ -264,7 +264,7 @@
</StackPanel>
<wgt:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind local:MainPage.GetTeamsChannelMessagesBuilder('02bd9fd6-8f93-4758-87c3-1fb73740a315', '19:d0bba23c2fc8413991125a43a54cc30e@thread.skype'), Mode=OneWay}"
RequestBuilder="{x:Bind TeamsChannelMessagesBuilder, Mode=OneWay}"
ResponseType="graph:ChatMessage">
<wgt:GraphPresenter.ContentTemplate>
<DataTemplate>

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

@ -23,9 +23,35 @@ namespace SampleTest
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
public DateTime ThreeDaysFromNow => Today.AddDays(3);
public IBaseRequestBuilder CalendarViewBuilder;
public IBaseRequestBuilder MessagesBuilder;
public IBaseRequestBuilder PlannerTasksBuilder;
public IBaseRequestBuilder TeamsChannelMessagesBuilder;
public MainPage()
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += this.OnProviderUpdated;
}
private void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
{
if (e.Reason == ProviderManagerChangedState.ProviderStateChanged
&& sender is ProviderManager pm
&& pm.GlobalProvider.State == ProviderState.SignedIn)
{
CalendarViewBuilder = ProviderManager.Instance.GlobalProvider.Graph().Me.CalendarView;
MessagesBuilder = ProviderManager.Instance.GlobalProvider.Graph().Me.Messages;
PlannerTasksBuilder = ProviderManager.Instance.GlobalProvider.Graph().Me.Planner.Tasks;
TeamsChannelMessagesBuilder = ProviderManager.Instance.GlobalProvider.Graph().Teams["02bd9fd6-8f93-4758-87c3-1fb73740a315"].Channels["19:d0bba23c2fc8413991125a43a54cc30e@thread.skype"].Messages;
}
else
{
CalendarViewBuilder = null;
MessagesBuilder = null;
PlannerTasksBuilder = null;
}
}
public static string ToLocalTime(DateTimeTimeZone value)
@ -50,26 +76,5 @@ namespace SampleTest
{
return percentCompleted == 100;
}
public static IBaseRequestBuilder GetCalendarViewBuilder()
{
return ProviderManager.Instance.GlobalProvider.Graph().Me.CalendarView;
}
public static IBaseRequestBuilder GetMessagesBuilder()
{
return ProviderManager.Instance.GlobalProvider.Graph().Me.Messages;
}
public static IBaseRequestBuilder GetPlannerTasksBuilder()
{
return ProviderManager.Instance.GlobalProvider.Graph().Me.Planner.Tasks;
}
public static IBaseRequestBuilder GetTeamsChannelMessagesBuilder(string team, string channel)
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/3064
return ProviderManager.Instance.GlobalProvider.Graph().Teams[team].Channels[channel].Messages;
}
}
}

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

@ -156,6 +156,10 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Net.Authentication.Msal\CommunityToolkit.Net.Authentication.Msal.csproj">
<Project>{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}</Project>
<Name>CommunityToolkit.Net.Authentication.Msal</Name>
</ProjectReference>
<ProjectReference Include="..\CommunityToolkit.Net.Authentication\CommunityToolkit.Net.Authentication.csproj">
<Project>{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}</Project>
<Name>CommunityToolkit.Net.Authentication</Name>

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

@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleTest", "SampleTest\Sa
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Net.Authentication", "CommunityToolkit.Net.Authentication\CommunityToolkit.Net.Authentication.csproj", "{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Net.Authentication.Msal", "CommunityToolkit.Net.Authentication.Msal\CommunityToolkit.Net.Authentication.Msal.csproj", "{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CI|Any CPU = CI|Any CPU
@ -210,6 +212,46 @@ Global
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.Release|x64.Build.0 = Release|x64
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.Release|x86.ActiveCfg = Release|x86
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.Release|x86.Build.0 = Release|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|Any CPU.ActiveCfg = CI|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|Any CPU.Build.0 = CI|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|ARM.ActiveCfg = CI|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|ARM.Build.0 = CI|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|ARM64.ActiveCfg = CI|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|ARM64.Build.0 = CI|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|x64.ActiveCfg = CI|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|x64.Build.0 = CI|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|x86.ActiveCfg = CI|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.CI|x86.Build.0 = CI|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|ARM.ActiveCfg = Debug|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|ARM.Build.0 = Debug|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|ARM64.Build.0 = Debug|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|x64.ActiveCfg = Debug|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|x64.Build.0 = Debug|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|x86.ActiveCfg = Debug|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Debug|x86.Build.0 = Debug|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|Any CPU.ActiveCfg = Debug|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|Any CPU.Build.0 = Debug|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|ARM.ActiveCfg = Debug|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|ARM.Build.0 = Debug|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|ARM64.ActiveCfg = Debug|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|ARM64.Build.0 = Debug|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|x64.ActiveCfg = Debug|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|x64.Build.0 = Debug|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|x86.ActiveCfg = Debug|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Native|x86.Build.0 = Debug|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|Any CPU.Build.0 = Release|Any CPU
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|ARM.ActiveCfg = Release|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|ARM.Build.0 = Release|ARM
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|ARM64.ActiveCfg = Release|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|ARM64.Build.0 = Release|ARM64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|x64.ActiveCfg = Release|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|x64.Build.0 = Release|x64
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|x86.ActiveCfg = Release|x86
{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE