![](/img/trans.png)
[英]Is it possible in Blazor Server to inject scoped service in middleware and inject that same instance in component?
[英]In a Blazor Server app, is it possible to inject a GraphServiceClient into a scoped service?
我一直在试验新的 Blazor 功能,并试图将用户数据从 Azure AD 提取到测试应用程序中。 这些是相关的片段:
我的服务
public class UserService
{
GraphServiceClient _graphClient { get; set; }
protected User _user = null;
public UserService(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public string GetUserName()
{
return User()?.DisplayName ?? "";
}
启动
public void ConfigureServices(IServiceCollection services)
{
var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
// Add sign-in with Microsoft
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
// Add the possibility of acquiring a token to call a protected web API
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
// Enables controllers and pages to get GraphServiceClient by dependency injection
// And use an in memory token cache
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
services.AddRazorPages()
.AddMicrosoftIdentityUI();
services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
services.AddSingleton<WeatherForecastService>();
services.AddScoped<UserService>();
GraphServiceClient 确实在 my.cs 脚本中初始化,但我收到错误消息:
错误:没有帐户或登录提示传递给 AcquireTokenSilent 调用
任何 azure 配置都不是问题(我认为),因为如果我使用 Microsoft 示例并制作 ComponentBase,一切正常。
public class UserProfileBase : ComponentBase
{
[Inject]
GraphServiceClient GraphClient { get; set; }
protected User _user = new User();
protected override async Task OnInitializedAsync()
{
await GetUserProfile();
}
/// <summary>
/// Retrieves user information from Microsoft Graph /me endpoint.
/// </summary>
/// <returns></returns>
private async Task GetUserProfile()
{
try
{
var request = GraphClient.Me.Request();
_user = await request.GetAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
我目前的想法是,即使我已经通过身份验证,配置文件组件使用的 Authorize 标记(以及 ComponentBase?)正在使用访问令牌在幕后做一些事情?
@page "/profile"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inherits UserProfileBase
public class UserAccount
{
public int Id {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Email {get; set;}
}
public class UserService
{
GraphServiceClient _graphClient;
protected UserAccount _user {get; set;}
public UserService(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<string> GetUserName()
{
UserAccount = await GetUserAsync();
return $"{UserAccount.FirstName} {UserAccount.LastName}";
}
public async Task<UserAccount> GetUserAsync()
{
var user = awiat __graphClient.Me.Request.Select( e => new
{
e.Id,
e.GivenName,
e.Surname,
e.Identities,
}).GetAsync();
if(user != null)
{
var email = user.Identities.ToList().FirstOrDefault(x => x.SignInType == "emailAddress")?.IssuerAssignedId;
return new UserAccount
{
Id= user.Id,
FirstName= user.GivenName,
LastName= user.Surname,
Email= email
};
}
else {return null;}
}
}
抱歉,这个答案晚了一年多 - 希望这会在未来对其他人有所帮助。 我今天也试图解决这个确切的问题,我从这个演示项目中得到了这个难题的缺失部分。
除了ConfigureServices
方法之外,您还需要确保在端点中映射了控制器,以便身份 UI 可以 map 响应。
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Important for Microsoft Identity UI
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
然后你需要对你的作用域服务进行一些异常处理。 我很确定这是因为 Blazor 的预渲染功能最初并未在第一次渲染中对用户进行身份验证。 但不要引用我的话
我看不到 OP 的服务,所以这是我的:
using Microsoft.Graph;
using Microsoft.Identity.Web;
namespace MyProject.Services
{
public class UserService
{
private readonly GraphServiceClient _graphServiceClient;
private readonly MicrosoftIdentityConsentAndConditionalAccessHandler _consentHandler;
public UserService(
GraphServiceClient graphServiceClient,
MicrosoftIdentityConsentAndConditionalAccessHandler consentHandler)
{
_graphServiceClient = graphServiceClient;
_consentHandler = consentHandler;
}
public async Task<User?> GetUserAsync()
{
try
{
return await _graphServiceClient.Me.Request().GetAsync();
}
catch (Exception ex)
{
_consentHandler.HandleException(ex);
return null;
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.