我有一个 Blazor WASM 应用程序。我使用身份框架登录:
SignInResult signInResult = await signInManager<ApplicationUser>.PasswordSignInAsync(parameters.UserName, parameters.Password, parameters.RememberMe, true);
signInResult
总是Succeeded
。
在WebAssembly的StateProvider中,我得到一个UserInfo对象,该对象除其他外,该对象告诉用户是否经过身份验证:
[HttpGet]
public UserInfoDto UserInfo()
{
return BuildUserInfo();
}
private UserInfoDto BuildUserInfo()
{
var userInfo = new UserInfoDto
{
IsAuthenticated = User.Identity.IsAuthenticated,
UserName = User.Identity.Name
};
foreach (var claim in User.Claims)
{
userInfo.ExposedClaims.Add(claim.Type, claim.Value);
}
if (userInfo.IsAuthenticated)
{
userInfo.Id = Guid.Parse(identityService.GetUserId(User));
}
return userInfo;
}
在这里User.Identity.IsAuthenticated
总是假的。我也在密码登录异步之后立即检查了它,但它也是一样的。
我的启动是这样设置的:
services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
.AddEntityFrameworkStores<SupportToolContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = false;
options.Password.RequiredLength = MIN_PASSWORD_LENGTH;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(LOCKOUT_DURATION);
options.Lockout.MaxFailedAccessAttempts = MAX_TRIES_BEFORE_LOCKOUT;
options.Lockout.AllowedForNewUsers = true;
// Email Settings
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedEmail = true;
});
// Configure LifeSpan of Identity email tokens
services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromDays(3);
});
services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = false;
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = context =>
{
context.Response.StatusCode = UNAUTHORIZED_STATUS_CODE;
return Task.CompletedTask;
}
};
});
配置方法包含:
app.UseAuthentication();
app.UseAuthorization();
AuthenticationStateProvider:
public class IdentityAuthenticationStateProvider : AuthenticationStateProvider { private UserInfoDto userInfoCache; 私有只读 IServiceProvider serviceProvider;
public IdentityAuthenticationStateProvider(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
..
private async Task<UserInfoDto> GetUserInfoAsync()
{
var authorizeApi = serviceProvider.GetRequiredService<IAuthorizeApi>();
if (userInfoCache != null && userInfoCache.IsAuthenticated) return userInfoCache;
userInfoCache = await authorizeApi.GetUserInfoAsync();
return userInfoCache;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity();
try
{
UserInfoDto userInfo = await GetUserInfoAsync();
if (userInfo.IsAuthenticated)
{
IEnumerable<Claim> claims = new[] {new Claim(ClaimTypes.Name, userInfoCache.UserName)}.Concat(
userInfoCache.ExposedClaims.Select(c => new Claim(c.Key, c.Value)));
identity = new ClaimsIdentity(claims, "Server authentication");
}
}
catch (HttpRequestException ex)
{
Console.WriteLine("Request failed:" + ex);
}
return new AuthenticationState(new ClaimsPrincipal(identity));
}
}
一般来说,整个过程与此示例相同:https://github.com/stavroskasidis/BlazorWithIdentity (在本地也停止工作(
让我感到困惑的是,它以前工作过,现在仍然在服务器上工作,如果我在部署到服务器时签出该历史记录,它在本地不起作用。我错过了什么?
好吧,这很令人沮丧。解决方案是重新启动我所有的电脑。似乎问题出在 IIS Express 左右的某个地方 - 同时在我的两台计算机上。