简体   繁体   English

User.Identity.Name 在 PasswordSignInAsync MVC .Net Core 3.0 之后始终为 null 并声明计数为 0

[英]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.ConfigureServicesAddIdentity的调用设置了这一点:它注册一个名为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.

相关问题 User.Identity.Name 在 ASP.NET Core MVC 应用程序中返回 null - User.Identity.Name returns null in ASP.NET Core MVC application User.Identity.Name 是 null 在我的 ASP.NET 核心 Web ZDB974238714CA8A14A7CE1D0 - User.Identity.Name is null in my ASP.NET Core Web API 对于托管在 asp.net core 中的 Blazor Wasm,User.Identity.Name 为 null - User.Identity.Name is null for Blazor Wasm hosted in asp.net core User.Identity.Name 在 asp.net core + angular 客户端应用程序中为空 - User.Identity.Name is null in asp.net core + angular client app 登录后 'User.Identity.Name' 为 null,但使用 Sustainsys.Saml2.Mvc 集成时 'IsAuthenticated' 为 true - After logging in 'User.Identity.Name' is null, but 'IsAuthenticated' is true when using Sustainsys.Saml2.Mvc integration 在AspNet OpenAuth登录MVC之后获取User.Identity.Name - Getting User.Identity.Name after AspNet OpenAuth Login MVC User.Identity.Name被模拟后返回null - User.Identity.Name returns null after being mocked 即使在使用asp.net core 2.2中的PasswordSignInAsync成功登录后,User.Identity.IsAuthenticated也始终返回false - User.Identity.IsAuthenticated always returns false even after successfully logged in using PasswordSignInAsync in asp.net core 2.2 在MVC4中模拟User.Identity.Name - mocking User.Identity.Name in MVC4 User.Identity.Name或GetUserName在MVC 5上不起作用 - User.Identity.Name or GetUserName not working on MVC 5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM