ASP.NET Core MVC 身份登录问题

问题描述

我在使用 ASP.NET Core 3.1 MVC 时遇到 Microsoft Identity 问题。

登录成功时,它表示用户登录,但它不会重定向认主页。我认为它不重定向到主页的原因是因为没有设置 cookie,因为即使我成功登录它也会重定向到再次登录而不是主页并有一个 cookie。 PD:我只在http上运行,我没有使用https,因为我没有钱买证书,我觉得没关系吗?

哪里说用户登录了?

在控制台中:

enter image description here

但没有任何反应,只是重定向到再次登录并且其他控制器视图被阻止:

enter image description here

控制器

public class AccountController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    // private readonly IEmailSender _emailSender;
    // private readonly ISmsSender _smsSender;
    private readonly ILogger _logger;

    public AccountController(
        UserManager<ApplicationUser> userManager,SignInManager<ApplicationUser> signInManager,// IEmailSender emailSender,// ISmsSender smsSender,ILoggerFactory loggerFactory)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        // _emailSender = emailSender;
        // _smsSender = smsSender;
        _logger = loggerFactory.CreateLogger<AccountController>();
    }

    //
    // GET: /Account/Login
    [HttpGet]
    [AllowAnonymous]
    public IActionResult Login(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

    //
    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(Loginviewmodel model,string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;

        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout,set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(model.Email,model.Password,model.RememberMe,lockoutOnFailure: false);

            if (result.Succeeded)
            {
                _logger.Loginformation(1,"User logged in.");
                return RedirectToLocal(returnUrl);
            }

            // if (result.RequiresTwoFactor)
            // {
            //     return RedirectToAction(nameof(SendCode),new { ReturnUrl = returnUrl,RememberMe = model.RememberMe });
            // }

            if (result.IsLockedOut)
            {
                _logger.LogWarning(2,"User account locked out.");
                return View("Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty,"Invalid login attempt.");
                return View(model);
            }
        }

        // If we got this far,something Failed,redisplay form
        return View(model);
    }

    //
    // GET: /Account/Register
    [HttpGet]
    [AllowAnonymous]
    public IActionResult Register(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

    //
    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Register(Registerviewmodel model,string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;

        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email,Email = model.Email };
            var result = await _userManager.CreateAsync(user,model.Password);

            if (result.Succeeded)
            {
                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
                // Send an email with this link
                //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                //var callbackUrl = Url.Action("ConfirmEmail","Account",new { userId = user.Id,code = code },protocol: HttpContext.Request.Scheme);
                //await _emailSender.SendEmailAsync(model.Email,"Confirm your account",//    "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");
                await _signInManager.SignInAsync(user,isPersistent: false);
                _logger.Loginformation(3,"User created a new account with password.");
                return RedirectToLocal(returnUrl);
            }

            AddErrors(result);
        }

        // If we got this far,redisplay form
        return View(model);
}

Startup.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.AddControllersWithViews();
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.KNownProxies.Add(IPAddress.Parse("10.0.0.100"));
        });

        services.AddDbContext<Context>(options => options.UsesqlServer(Configuration.GetConnectionString("farmaowl")));

        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                            .RequireAuthenticatedUser()
                            .Build();
            config.Filters.Add(new Authorizefilter(policy));
        });

        services.AddIdentityCore<ApplicationUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<Context>()
            .AddSignInManager()
            .AddDefaultTokenProviders();

        services.AddAuthentication(o =>
        {
            o.DefaultScheme = IdentityConstants.ApplicationScheme;
            o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
        })
        .AddIdentityCookies(o => { });
    }

    // 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.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();
        app.UseAuthentication();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",pattern: "{controller=Recepcion}/{action=Habitaciones}/{id?}");
        });

        // app.UseMvc(routes =>
        // {
        //     routes.MapRoute(
        //         name: "default",//         template: "{controller=Home}/{action=Index}/{id?}");
        // });
    }
}

我正在关注此代码https://github.com/aspnet/Identity/tree/master/samples/IdentitySample.Mvc

我错过了什么?我是否缺少任何其他必要的文件或任何其他配置?我是使用 ASP.NET Core MVC 的 Identity 新手(通常在 ASP.NET MVC 中不是新的)。是 cookie 的问题吗?

解决方法

你中间件的顺序不对,正确的应该是

app.UseAuthentication();   
app.UseAuthorization();