【发布时间】:2020-08-18 16:00:21
【问题描述】:
在我们的应用程序中,我想使用胖客户端的用户管理。为此,我编写了一个自定义 AuthenticationStateProvider:
public class MyAuthenticationStateProvider : ServerAuthenticationStateProvider, IAuthentorizationService, IDisposable
{
public MyAuthenticationStateProvider (IPermissionManager permissionManager)
{
//User management service of the fat client
_permissionManager = permissionManager;
}
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
if (_permissionManager.PermissionUser == null)
{
var emptyUser = new ClaimsPrincipal(new ClaimsIdentity(new Claim[0]));
return Task.FromResult(new AuthenticationState(emptyUser));
}
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, _permissionManager.PermissionUser.User.GetName())
}, "FatClientAuthentication");
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
public async Task<bool> LoginUser(string userName, string password)
{
//Login via WCF connection
var response = await _clientProxy.Login(new LoginRequest
{
LoginUserName = userName,
Password = password
});
response.LogExceptionIfFaulted(_logger);
if (response.Ok)
{
_permissionManager.Initialize(response.LoggedInUser);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
return response.Ok;
}
登录工作正常。出于测试目的,我总是使用固定的用户凭据登录。成功登录后,我触发 NotifyAuthenticationStateChanged 事件,这会导致正确调用 GetAuthenticationStateAsync 方法。现在登录的用户被正确地包装在 AuthenticationState 中。在调试代码时,我可以看到带有名称声明的 Identity 是正确的用户,并且 IsAuthenticated 属性为 true。
但是,当使用“AuthorizeView”组件时,我总是得到一个“空用户”(没有名称声明,没有用户名,IsAuthenticated 为假)
我现在有一个小组件仅用于测试:
<AuthorizeView>
<Authorized>
<h2>User @context.User.Identity.Name</h2> is logged in!
Claims:
<ul>
@foreach (var claim in context.User.Claims)
{
<li>Type=@claim.Type; Value=@claim.Value</li>
}
</ul>
@context.User.Claims
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</Authorized>
<NotAuthorized>
<h2>User @context.User.Identity.Name</h2> @*this is an empty string*@
<h2>Authentication Type: @context.User.Identity.AuthenticationType</h2> @*empty*@
<h2>Authenticated: @context.User.Identity.IsAuthenticated</h2>@*false*@
No user is logged in!
</NotAuthorized>
我在 App.razor 中使用 AuthorizeRouteView 和 CascadingAuthenticationState 就像在https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.1中显示的官方示例中一样
通过 CascadingParameter 访问 AuthenticationState 也会导致相同的“空用户”。
感谢任何帮助,
tilt32
编辑 1
所以我再次查看了登录行为,确保调用了该事件。 然后我发现,我的 AuthenticationStateChanged 事件没有订阅者(为空)。我的印象是,框架中的某些内容在启动时附加到此事件。也许我在启动时忘记了一些配置方法调用?这就是我在配置服务中所做的:
services.AddScoped<AuthenticationStateProvider, MyAuthenticationStateProvider>();
services.AddScoped<ServerAuthenticationStateProvider, MyAuthenticationStateProvider>();
//Interface which I use in my LoginCompontent and at Startup to log in with the default user or some real user credentials
services.AddScoped<IAuthenticationService, MyAuthenticationStateProvider>();
我还尝试了用户 enet 建议的方法。可悲的是没有成功,结果是一样的。在登录期间,调用 NotifyAuthenticationStateChanged 并因此调用没有订阅者的事件。
我们在后台使用的 WCF 服务需要登录用户。因此,我创建了一个具有有限权限的来宾用户来解决这个问题。因此,应用程序进入 GetAuthenticationStateAsync 并尝试在启动后直接触发 AuthenticationStateEvent(在加载屏幕期间)。
编辑 2
所以我现在尝试了一些额外的设置步骤,微软在 Blazor 文档中写道,它们对于服务器端 blazor 来说不是必需的:
ConfigureServices 现在看起来像这样
//Authentication & Authorization setup
services.AddOptions();
services.AddAuthenticationCore();
services.AddAuthorizationCore();
services.AddScoped<IPermissionManager, SingleUserPermissionManager>();
services.AddScoped<AuthenticationStateProvider, MyAuthenticationStateProvider>();
services.AddScoped<ServerAuthenticationStateProvider, MyAuthenticationStateProvider>();
services.AddScoped<IAuthenticationService, MyAuthenticationStateProvider>();
在 Configure(IApplicationBuilder app, IWebHostEnvironment env) 方法中,我添加了以下调用:
app.UseAuthentication();
app.UseAuthorization();
这也没有任何效果。
【问题讨论】:
标签: authentication server-side blazor