我有一个新的 Blazor 服务器应用程序 - 使用默认的 VS2019 模板(计数器应用程序示例)。 我已经在应用程序上启用了Windows身份验证。 当应用程序加载到我的服务器上时,它会在屏幕右上角显示域/用户名,这很棒。 我想在我的 c# 代码 sop 中获取用户名,我可以围绕此构建逻辑,例如如果用户是 X do Y。
所以我把它添加到我的启动文件中 服务业。AddSingleton<IHttpContextAccessor,>();
并尝试通过以下方式访问用户名: 字符串用户名 = _httpContextAccessor.HttpContext.User.Identity.Name;
但是,我不断收到405错误。 请参阅随附的代码、错误和设置屏幕截图
任何帮助将不胜感激
蒂亚
屏幕截图
无法访问 Blazor Server 应用中的 HttpContext 对象,因为使用的协议是 SignalR,但始终为 HTTP 的初始请求除外,在这种情况下,可以获取 HttpContext 对象(在实例化 Blazor 应用之前),提取值,并将其传递给 Blazor 应用。看到这个答案如何做到这一点...
但是,您可以将AuthenticationStateProvider
服务注入到组件中,并访问声明的 ClaimPrincipal(神奇地从WindowsPrincipal
转换而来)对象,如下面的代码所示。
复制、运行和测试...
@page "/"
@using System.Security.Claims;
<div>@output</div>
@if (claims.Count() > 0)
{
<table class="table">
@foreach (var claim in claims)
{
<tr>
<td>@claim.Type</td>
<td>@claim.Value</td>
</tr>
}
</table>
}
@code{
private string output;
private IList<Claim> claims;
[Inject] AuthenticationStateProvider AuthenticationStateProvider { get; set; }
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
output = $"{user.Identity.Name} is authenticated.";
claims = user.Claims.ToList();
}
else
{
output = "The user is not authenticated.";
}
}
}
更新:
实际上,有三种方法可以做到这一点。上面的第一个,不建议这样做,因为 AuthenticationState 在被访问后永远不会更新。您需要刷新页面才能访问它的新实例。
第二种方法是将 AuthenticationState 的任务级联到组件中,等待该任务,然后访问 AuthenticationState。以下是您可以做到这一点的方法:
@page "/"
@code {
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask { get;
set; }
private string UserName {get; set;}
protected async override Task OnInitializedAsync()
{
// Await Task<AuthenticationState>
// and then retrieve the ClaimsPrincipal
var user = (await authenticationStateTask).User;
if (user.Identity.IsAuthenticated)
{
// Assign the user name to the
UserName = user.Identity.Name;
}
}
}
请注意,Task<AuthenticationState>
由驻留在应用程序组件 (App.razor) 中的CascadingAuthenticationState
组件级联。CascadingAuthenticationState
组件 包含每当新更改的身份验证状态发生更改时向式传输的代码。
第三种方法是创建类服务,如下所示:
public class UsertService
{
private readonly AuthenticationStateProvider authProvider;
public UserService (AuthenticationStateProvider authProvider)
{
this.authProvider = authProvider;
}
public async Task<string> GetUserName()
{
var authenticationStateTask = await
authProvider.GetAuthenticationStateAsync();
var user = authenticationStateTask.User;
if (user.Identity.IsAuthenticated)
{
// Executed only when the user is authenticated
return user.Identity.Name;
}
return "User not authenticated";
}
}
请注意,您可以扩展该类以提供其他值等。
现在,您必须将此服务添加为 Scoped 在 Startup 类中,如下所示:
public void ConfigureServices(IServiceCollection services)
{
// Code removed...
services.AddScoped<UserService>();
}
这就是您在组件中使用它的方式:
@page "/"
@inject UserService UserService
<div>Your user name: @name</div>
@code
{
private string name;
protected override async Task OnInitializedAsync()
{
name = await UserService.GetUserName();
}
}
注意:如果您需要更多帮助,可以通过我的电子邮件与我联系。在个人资料中查看...