如何解决如何针对Microsoft Graph验证“ Live SDK” UWP应用程序
我将UWP应用程序从OneDrive SDK升级到了Microsoft Graph SDK。该应用程序已经在https://apps.dev.microsoft.com/(“ Live SDK应用程序”下)中进行了注册。
我已经使用MSAL.NET(NuGet包Microsoft.Identity.Client)实现了新的身份验证。这是我用于身份验证的代码:
public class AuthenticationService
{
private const string Tenant = "common";
private const string Authority = "https://login.microsoftonline.com/" + Tenant;
private const string MSGraphURL = "https://graph.microsoft.com/v1.0/";
private const string RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient";
private readonly string[] scopes;
private readonly IPublicClientApplication publicClientApp;
private GraphServiceClient graphClient;
private AuthenticationResult authResult;
public AuthenticationService(string clientId,string[] scopes)
{
this.scopes = scopes;
this.publicClientApp = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(Authority)
.WithUseCorporateNetwork(false)
.WithRedirectUri(RedirectUri)
.WithLogging((level,message,containsPii) =>
{
Debug.WriteLine($"MSAL: {level} {message} ");
},Microsoft.Identity.Client.LogLevel.Warning,enablePiiLogging: false,enableDefaultPlatformLogging: true)
.Build();
}
public string TokenForUser => authResult?.AccessToken;
public DateTimeOffset? TokenExpireOn => authResult?.ExpiresOn;
public GraphServiceClient SignIn()
{
if (graphClient == null)
{
graphClient = new GraphServiceClient(MSGraphURL,new DelegateAuthenticationProvider(async (requestMessage) =>
{
if (string.IsNullOrEmpty(TokenForUser))
{
authResult = await AuthenticateAsync();
}
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer",TokenForUser);
}));
}
return graphClient;
}
public async Task SignOutAsync()
{
try
{
authResult = null;
graphClient = null;
foreach (IAccount account in await publicClientApp.GetAccountsAsync().ConfigureAwait(false))
{
await publicClientApp.RemoveAsync(account).ConfigureAwait(false);
}
}
catch (MsalException ex)
{
Log.Exception(ex);
}
}
private async Task<AuthenticationResult> AuthenticateAsync()
{
IEnumerable<IAccount> accounts = await publicClientApp.GetAccountsAsync().ConfigureAwait(false);
IAccount firstAccount = accounts.FirstOrDefault();
AuthenticationResult authResult;
try
{
authResult = await publicClientApp.AcquireTokenSilent(scopes,firstAccount)
.ExecuteAsync().ConfigureAwait(false);
}
catch (MsalUiRequiredException ex)
{
Log.Exception(ex);
authResult = await publicClientApp.AcquireTokenInteractive(scopes)
.ExecuteAsync()
.ConfigureAwait(false);
}
return authResult;
}
}
仅当我在Azure门户中注册我的应用并从那里获取新的clientId
时,以上代码才有效。尝试使用旧的应用程序ID会导致以下异常:
Microsoft.Identity.Client.MsalClientException: 'Error: ClientId is not a Guid.'
由于应用程序正在使用应用程序文件夹(Files.ReadWrite.AppFolder
),因此我无法续订我的应用程序注册,并且再次注册该应用程序将导致现有用户失去其数据。
那么我该如何使用旧的“ Live SDK应用程序”应用程序ID并最好使用当前的Windows帐户(无需登录UI)针对Microsoft Graph API对我的应用程序进行身份验证?
解决方法
您需要在Azure Portal中创建新的应用注册。另外,您还需要通过supported MSAL flows之一使用工作或学校帐户或个人(Microsoft)帐户登录。 Files.ReadWrite.AppFolder 是权限。将其添加到新的应用程序不会删除或丢失任何内容。
,终于找到了解决办法:
-
确保您的应用与应用商店相关联。
-
使用以下代码查找系统分配的应用程序的重定向 URI:
string URI = string.Format("ms-appx-web://Microsoft.AAD.BrokerPlugIn/{0}",WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper());
-
在 Azure 门户中注册您的应用,并将您在上一步中获得的重定向 URI 添加到您的应用注册中。在您的应用注册页面下,从菜单“身份验证”中选择并将 URI 添加到“重定向 URI”列表中。
-
从 https://github.com/CommunityToolkit/Graph-Controls 将这些包添加到您的解决方案中:
- CommunityToolkit.Authentication
- CommunityToolkit.Authentication.Uwp
- CommunityTokit.Graph
- CommunityToolkit.Graph.Uwp
- 用于访问 OneDrive 的示例实用程序类(从您的应用注册页面获取 clientId):
public class OneDriveClient
{
private readonly static string[] DefaultScopes = new string[] { "Files.ReadWrite.AppFolder","offline_access","openid" };
private GraphServiceClient client;
public OneDriveClient(string clientId,string[] scopes)
{
var webAccountProviderConfig =
new WebAccountProviderConfig(WebAccountProviderType.Local,clientId);
ProviderManager.Instance.GlobalProvider =
new WindowsProvider(scopes ?? DefaultScopes,webAccountProviderConfig);
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderStateChanged(object sender,ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
this.client = ProviderManager.Instance.GlobalProvider.GetClient();
}
}
public bool IsAuthenticated => ProviderManager.Instance.State == ProviderState.SignedIn;
public Task SignInAsync() => ProviderManager.Instance.GlobalProvider.SignInAsync();
public Task SignOutAsync() => ProviderManager.Instance.GlobalProvider.SignOutAsync();
public Task<Drive> GetDriveAsync() => this.client.Drive.Request().GetAsync();
}
现在您可以访问使用旧版 OneDrive SDK 创建的同一个应用程序文件夹。详情另见this sample.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。