Wes*_*s H 25 asp.net-core blazor blazor-server-side .net-core-3.0 ef-core-3.0
我正在使用 Blazor 和 Windows 身份验证启动一个新站点,并且需要识别查看页面/组件的当前用户。
对于 Razor 页面,可以使用 访问当前用户名Context.User.Identity.Name
,但这在 Blazor 组件中似乎不起作用。我尝试将 HttpContext 注入组件,但 Context 在运行时为空。
作为奖励,我最终希望将其合并到 Startup.cs 中,因此我只需要获取一次用户名,就可以为我的应用程序利用企业用户类(使用 EF Core)。也将不胜感激针对该用例量身定制的答案。
Ric*_*res 38
在组件中获取用户有三种可能性(页面就是组件):
IHttpContextAccessor
并从中访问HttpContext
然后User
;需要注册IHttpContextAccessor
的Startup.ConfigureServices
,正常使用AddHttpContextAccessor
AuthenticationStateProvider
属性,调用GetAuthenticationStateAsync
并获得User
从中<CascadingAuthenticationState>
组件中,声明一个Task<AuthenticationState>
属性并调用它以获取User
(类似于#2)在此处查看更多信息:https : //docs.microsoft.com/en-us/aspnet/core/security/blazor。
fin*_*s10 19
对于blazor wasm
内net 5.0
及以上。这是我的做法,
<App>
将您的组件包裹在里面<CascadingAuthenticationState>
,如下所示,<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
...
</Found>
<NotFound>
...
</NotFound>
</Router>
</CascadingAuthenticationState>
Run Code Online (Sandbox Code Playgroud)
Task<AuthenticationState>
CascadingParameter
任何组件内,如下所示,<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
...
</Found>
<NotFound>
...
</NotFound>
</Router>
</CascadingAuthenticationState>
Run Code Online (Sandbox Code Playgroud)
Identity
和Claims
内部组件,如下所示,public class AppRootBase : ComponentBase
{
[CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是来自Microsoft 文档的参考。
Wes*_*s H 10
我现在已经能够让它与一个通用类以及一个组件一起工作。
访问HttpContext
用户;在ConfigureServices
,Startup.cs
加上
services.AddHttpContextAccessor();
Run Code Online (Sandbox Code Playgroud)
我有CorporateUserService
我的课CorporateUser
类。服务类DbContext
通过构造函数注入。
然后我创建了一个CurrentCorporateUserService
继承自CorporateUserService
. 它接受一个DbContext
和一个IHttpContextAccessor
通过构造函数注入
public class CurrentCorporateUserService : CorporateUserService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CurrentCorporateUserService(IHttpContextAccessor httpContextAccessor,
MyDbContext context) : base(context)
{
_httpContextAccessor = httpContextAccessor;
}
...
Run Code Online (Sandbox Code Playgroud)
基本服务类有一个方法GetUserByUsername(string username)
。Current 服务类添加了一个额外的方法
public CorporateUser GetCurrentUser()
{
return base.GetUserByUsername(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(8));
}
Run Code Online (Sandbox Code Playgroud)
当前服务类注册在 Startup.cs
services.AddScoped<CurrentCorporateUserService>();
Run Code Online (Sandbox Code Playgroud)
完成后,我可以CurrentCorporateUserService
在带有指令注入的组件中使用 。
[Inject]
private CurrentCorporateUserService CurrentCorporateUserService { get; set; } =
default!;
Run Code Online (Sandbox Code Playgroud)
或在任何类中,使用构造函数注入。
public MyDbContext(DbContextOptions<MyDbContext> options,
CurrentCorporateUserService CurrentCorporateUserService)
: base(options)
{
_currentUser = CurrentCorporateUserService.GetCurrentUser();
}
Run Code Online (Sandbox Code Playgroud)
使其成为项目范围的服务意味着我所有的开发人员都不必关心如何获取当前用户,他们只需要将服务注入到他们的类中。
例如,使用它MyDbContext
使当前用户可用于每个保存事件。在下面的代码中,任何继承BaseReport
该类的类都将在保存记录时自动更新报表元数据。
public override Int32 SaveChanges()
{
var entries = ChangeTracker.Entries().Where(e => e.Entity is BaseReport
&& (e.State == EntityState.Added || e.State == EntityState.Modified));
foreach (var entityEntry in entries)
{
((BaseReport)entityEntry.Entity).ModifiedDate = DateTime.Now;
((BaseReport)entityEntry.Entity).ModifiedByUser = _currentUser.Username;
}
return base.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
小智 10
我有类似的要求并一直在使用:
var authstate = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authstate.User;
var name = user.Identity.Name;
Run Code Online (Sandbox Code Playgroud)
我已经AuthenticationStateProvider
在我的startup.cs中有一个并将其添加到我的自定义类的构造函数中。
Shared\LoginDisplay.razor
如果您创建一个新项目并选择使用 Windows 身份验证的 Blazor,您将获得一个包含以下内容的文件:
<AuthorizeView>
Hello, @context.User.Identity.Name!
</AuthorizeView>
Run Code Online (Sandbox Code Playgroud)
使用我们可以在任何页面上无需任何修改<AuthorizeView>
即可访问。@context.User.Identity.Name
小智 7
在 App.razor 中,确保该元素封装在 CascadingAuthenticationState 元素内。这是如果您创建具有身份验证支持的 Blazor 项目时默认生成的内容。
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Run Code Online (Sandbox Code Playgroud)
在您的组件中,您可以使用 AuthenticationStateProvider 来访问当前用户,如以下示例所示:
@page "/"
@layout MainLayout
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject SignInManager<IdentityUser> SignInManager
@code
{
override protected async Task OnInitializedAsync()
{
var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (SignInManager.IsSignedIn(authenticationState.User))
{
//Do something...
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
For me the solution mentioned in the first answer 2. option worked perfect: I am using Blazor server side on .Net Core 5.0 . I injected
@inject AuthenticationStateProvider GetAuthenticationStateAsync
Run Code Online (Sandbox Code Playgroud)
in my Blazor page and added the following in the code section:
protected async override Task OnInitializedAsync()
{
var authstate = await GetAuthenticationStateAsync.GetAuthenticationStateAsync();
var user = authstate.User;
var name = user.Identity.Name;
}
Run Code Online (Sandbox Code Playgroud)
In my startup.cs, I have the following lines:
services.AddScoped<ApiAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(p =>
p.GetRequiredService<ApiAuthenticationStateProvider>());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
29678 次 |
最近记录: |