使用个人用户帐户在blazor服务器端应用程序上访问MS Graph数据的正确方法
我在Blazor(ASP.NET核心)服务器端构建了一个web应用程序。应用程序是多租户的,我需要控制谁有访问权,因此我使用存储在SQL数据库中的自己的用户数据库(DefaultIdentity) 现在我需要访问Microsoft Graph(对于某些用户)。我通过使用应用程序级访问来实现这一点,但我希望避免让本地IT管理员在他们的Azure广告中设置这一点,我希望遵守“最低特权原则” 因此,我希望能够添加一个登录页面/功能,在该页面/功能中,特定用户(在使用我的本地用户数据库登录后)可以向我的应用程序自动化+同意检索日历。通过Microsoft Graph读取权限 我该怎么做 我想我学到的是使用个人用户帐户在blazor服务器端应用程序上访问MS Graph数据的正确方法,blazor,msal,Blazor,Msal,我在Blazor(ASP.NET核心)服务器端构建了一个web应用程序。应用程序是多租户的,我需要控制谁有访问权,因此我使用存储在SQL数据库中的自己的用户数据库(DefaultIdentity) 现在我需要访问Microsoft Graph(对于某些用户)。我通过使用应用程序级访问来实现这一点,但我希望避免让本地IT管理员在他们的Azure广告中设置这一点,我希望遵守“最低特权原则” 因此,我希望能够添加一个登录页面/功能,在该页面/功能中,特定用户(在使用我的本地用户数据库登录后)可以向我的
- 我应该使用OAuth2.0授权代码流
- 我的应用程序是一个机密应用程序(我有一个安全的服务器端)-但这阻止我使用AquireTokenInteractive!?那么我应该使用IPublicClient应用程序吗
我能找到的所有示例都使用Azure AD登录用户。是否有一个“手动”实现授权代码流的示例,我可以看一下?我现在有了一个可行的解决方案,但我想听听你们中的一些人是否有任何意见-我没有看到的任何警告或陷阱 我的解决方案如下: 我正在使用“标准流”获取PublicClientApplication
IPublicClientApplication app = PublicClientApplicationBuilder
.Create(publicAppClientId)
.WithRedirectUri("http://localhost")
.Build();
TokenCacheHelper.EnableSerialization(app.UserTokenCache);
var accounts = await app.GetAccountsAsync();
IAccount firstAccount = accounts.FirstOrDefault();
AuthenticationResult authResult = null;
try
{
authResult = await app.AcquireTokenSilent(scopesList, firstAccount)
.ExecuteAsync();
}
catch (MsalUiRequiredException)
{
try
{
authResult = await app.AcquireTokenInteractive(scopesList)
.ExecuteAsync();
}
catch (MsalException msalex)
{
System.Diagnostics.Debug.WriteLine($"Error acquiring Token:{System.Environment.NewLine}{msalex}");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error acquiring token silently:{System.Environment.NewLine}{ex}");
return;
}
if (authResult != null)
{
System.Diagnostics.Debug.WriteLine($"Access token:{System.Environment.NewLine}{authResult.AccessToken}");
// Use the token
InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(app, scopesList);
GraphServiceClient = new GraphServiceClient(authProvider);
}
}
我已经使用TokenCacheHelper添加了一个分布式SQL缓存
public class TokenCacheHelper
{
private IDistributedCache _cache;
private string lookUpAccount = string.Empty;
private byte[] token = null;
public TokenCacheHelper(IDistributedCache cache, string user)
{
_cache = cache;
lookUpAccount = user;
}
public void EnableSerialization(ITokenCache tokenCache)
{
tokenCache.SetBeforeAccess(BeforeAccessNotification);
tokenCache.SetAfterAccess(AfterAccessNotification);
}
private void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
if (token == null)
{
token = _cache.Get(lookUpAccount);
}
args.TokenCache.DeserializeMsalV3(token);
}
private void AfterAccessNotification(TokenCacheNotificationArgs args)
{
if (args.HasStateChanged)
{
token = args.TokenCache.SerializeMsalV3();
_cache.Set(lookUpAccount, token);
}
}
}
在startup.cs中添加DistributedSqlServerCache,标记上有“无限”超时
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = Configuration.GetConnectionString("TestDbContext");
options.SchemaName = "dbo";
options.TableName = "TestCache";
options.DefaultSlidingExpiration = TimeSpan.FromDays(300);
options.ExpiredItemsDeletionInterval = TimeSpan.FromDays(300);
});
所有这些似乎都在起作用。有什么想法吗?我正在使用类似的客户机/服务器系统。问题:如何获取传递给
AcquireTokenSilent
的firstAccount
?通过这个var accounts=wait app.GetAccountsAsync();IAccount firstAccount=accounts.FirstOrDefault();非常感谢。尝试过-GetAccountsAsync()为我提供了一个空列表:(-但是,当我使用“AcquireTokenInteractive()时),然后我在rutime的UI中得到一个列表。我想知道如何以编程方式访问此列表?它也为我这样做,直到我实现了TokenCaching,然后它为我提供了我的帐户。也就是说,在我运行了第一个AcquireTokenInteractive并将我的令牌保存在TokenCache中之后。我使用了一个SQL TokenCache,具有非常高的性能长期到期,到目前为止,MSAL已经能够自动更新令牌,使用只需登录/确认一次。