[英]User.Identity.Name always null and claims count 0 after PasswordSignInAsync MVC .Net Core 3.0
I have an issue that I cannot solve with ASP.NET MVC Core 3.0.我有一个无法使用 ASP.NET MVC Core 3.0 解决的问题。 After login, the result is succeed and returns successfully to the page I want if signed in, and when I check cookies or session I can see that the API added them successfully.登录后,结果成功并成功返回到我想要登录的页面,当我检查cookies或session时,我可以看到API成功添加了它们。 But when I try to get User.Identity.Name it always null, and isAuthenticated always equals false.但是当我尝试获取 User.Identity.Name 时,它始终为 null,并且 isAuthenticated 始终等于 false。 It is like app.UseAuthentication() don't read cookies or sessions.这就像 app.UseAuthentication() 不读取 cookie 或会话。
my startup.cs我的启动.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<AnisubsDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("AnisubsDBConnection")));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<AnisubsDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
services.AddControllersWithViews();
services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = "353222242210621";
facebookOptions.AppSecret = "XXXX";
facebookOptions.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/Login/Callback");
})
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = "1093176997632-ug4j2h7m9f1nl9rg8nucecpf9np0isro.apps.googleusercontent.com";
googleOptions.ClientSecret = "XXXX";
googleOptions.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/Login/Callback");
})
.AddTwitter(twitterOptions =>
{
twitterOptions.ConsumerKey = "lZ2ugpLuKpDOlmdSuyw1hVJLU";
twitterOptions.ConsumerSecret = "XXXX";
twitterOptions.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/Login/Callback");
})
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = "22f501ab-70c9-4054-8f33-2b35af3a64ba";
microsoftOptions.ClientSecret = "XXXX";
microsoftOptions.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/Login/Callback");
})
.AddCookie();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
LoginController.cs登录控制器.cs
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel loginViewModel)
{
if (ModelState.IsValid)
{
var user = await userManager.FindByEmailAsync(loginViewModel.Email);
if (user != null)
{
var result = await signInManager.PasswordSignInAsync(user.UserName, loginViewModel.Password, loginViewModel.RememberMe, false);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError(string.Empty, "Invalid Login Attempt");
}
return View(loginViewModel);
}
Sessions after redirect to home page重定向到主页后的会话
Razor page Shared _navbarlayout.cshtml (partial view inside _layout.cshtml) Razor 页面共享 _navbarlayout.cshtml(_layout.cshtml 内的部分视图)
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> signInManager;
<nav class="navbar fixed-top">
<a class="navbar-logo" href="Dashboard.Default.html">
<span class="logo d-none d-xs-block"></span>
<span class="logo-mobile d-block d-xs-none"></span>
</a>
<div class="navbar-right">
<div class="header-icons d-inline-block align-middle">
<div class="user d-inline-block">
<button class="btn btn-empty p-0" type="button" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
@if (signInManager.IsSignedIn(User))
{
<span class="name">@User.Identity.Name</span>
}
else
{
<span class="name">Not Registered</span>
}
<span>
<img alt="Profile Picture" src="img/profile-pic-l.jpg" />
</span>
</button>
<div class="dropdown-menu dropdown-menu-right mt-3">
@if (signInManager.IsSignedIn(User))
{
<a class="dropdown-item" href="#">Account</a>
<a class="dropdown-item" href="#">Features</a>
<a class="dropdown-item" href="#">History</a>
<a class="dropdown-item" href="#">Support</a>
<a class="dropdown-item" asp-action="logout" asp-controller="account">Sign out</a>
}
else
{
<a class="dropdown-item" asp-action="login" asp-controller="account">Login</a>
<a class="dropdown-item" asp-action="register" asp-controller="account">Register</a>
}
</div>
</div>
</div>
</nav>
From the razor code above, signInManager.IsSignedIn(User) always false, User.identity claims always count zero.从上面的剃刀代码中,signInManager.IsSignedIn(User) 始终为 false,User.identity 声称始终计数为零。
Changed the order of startup middlewares like below and the issue still the same更改了如下启动中间件的顺序,问题还是一样
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Below is a GIF picture of how it looks when quickwatch User下面是一个 GIF 图片,显示当 quickwatch 用户
ASP.NET Core Identity creates a cookie (shown in the screenshot as .AspNetCore.Identity.Application
), which gets set after a successful call to PasswordSignInAsync
. ASP.NET Core Identity 创建一个 cookie(在屏幕截图中显示为.AspNetCore.Identity.Application
),它在成功调用PasswordSignInAsync
后设置。 The call to AddIdentity
in Startup.ConfigureServices
sets this up: it registers an authentication scheme named Identity.Application
and sets it as the default authentication scheme for the application. Startup.ConfigureServices
对AddIdentity
的调用设置了这一点:它注册一个名为Identity.Application
的身份验证方案,并将其设置为应用程序的默认身份验证方案。
Now, with that in mind, take the following code from the question:现在,考虑到这一点,从问题中获取以下代码:
services.AddAuthentication(options => { options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; })
As is clear above, this call to AddAuthentication
overrides the default authentication scheme to be CookieAuthenticationDefaults.AuthenticationScheme
.如上所述,对AddAuthentication
调用将默认身份验证方案覆盖为CookieAuthenticationDefaults.AuthenticationScheme
。 This ends up with PasswordSignInAsync
correctly signing in the user with the Identity.Application
scheme, but the application is using the Cookies
scheme when trying to load in the current user.这最终会导致PasswordSignInAsync
使用Identity.Application
方案正确登录用户,但应用程序在尝试加载当前用户时使用的是Cookies
方案。 Naturally, this means the user is never loaded.自然,这意味着用户永远不会被加载。
In terms of a solution, just remove the callback from AddAuthentication
:就解决方案而言,只需从AddAuthentication
删除回调:
services.AddAuthentication()
.AddFacebook(facebookOptions =>
{
// ...
})
.AddGoogle(googleOptions =>
{
// ...
})
.AddTwitter(twitterOptions =>
{
// ...
})
.AddMicrosoftAccount(microsoftOptions =>
{
// ...
});
I've also removed the call to AddCookie
, which is redundant.我还删除了对AddCookie
的调用,这是多余的。 This adds the Cookies
authentication scheme, but your application is using Identity.Application
, as already described.这会添加Cookies
身份验证方案,但您的应用程序正在使用Identity.Application
,如前所述。
Try to changing the order of middlewares in the "startup.cs".尝试更改“startup.cs”中中间件的顺序。 So you should use app.UseHttpsRedirection()
before app.UseAuthentication()
like this:所以,你应该用app.UseHttpsRedirection()
之前app.UseAuthentication()
是这样的:
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.