.Net 8:无法使用“个人帐户身份验证”模板对用户进行身份验证

问题描述 投票:0回答:1

我使用带有“个人帐户”选项和 SDK 8 的身份验证,使用 MVC(ASP.NET Core Web 应用程序)的默认 .Net 模板从头开始创建了一个 Web 应用程序,我的问题是我无法对用户进行身份验证,至少

SignInManager.IsSignedIn(User)
总是返回 false。

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
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.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

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

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();

Login.cshtml.cs

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl ??= Url.Content("~/");

    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

    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(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);

        var result = SignInResult.Failed;
        AWS_Manager aws = new AWS_Manager(TestController.access_id, TestController.secret_key);

        UserModel oUser = await Task.Run(() => aws.getUser(Input.Email));

        if (oUser != null)
        {
            if (oUser.Password == Crypto.GetSHA1(Input.Password)))
            {
                SetUser(Input.Email);
                result = SignInResult.Success;
            }
        }

        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }

        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
        }

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

    // If we got this far, something failed, redisplay form
    return Page();
}

SetUser

private void SetUser(string email)
{
    var claims = new ClaimsIdentity(
        new[] { 
            // adding following 2 claim just for supporting default antiforgery provider
            new Claim(ClaimTypes.NameIdentifier, email),
            new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
            "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
            new Claim(ClaimTypes.Name, email),

            // optionally you could add roles if any
            // new Claim(ClaimTypes.Role, "RoleName"),
            // new Claim(ClaimTypes.Role, "AnotherRole"),

        }, IdentityConstants.ApplicationScheme);

    var claim = new ClaimsPrincipal(claims);
    HttpContext.SignInAsync(claim);

    //This next line is for testing and returns true
    var isLoggenIn = claim.Identities != null && claim.Identities.Any(i => i.AuthenticationType == IdentityConstants.ApplicationScheme); //=> Returns true
}

_LoginPartial.cshtml

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User)) //=> Always returns false
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity?.Name!</a>
    </li>
    <li class="nav-item">
        <form  class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

根据我已经阅读过的所有线程/帖子,我相信我的问题在于

SetUser
方法,最准确地说是在声明中设置
AuthenticationType
,但不完全确定,而且我不知道如何做吧。

有什么帮助吗?

编辑1:

我很确定我应该在末尾添加 AuthenticationType

ClaimsIdentity constructor, like this (for example):
            var claims = new ClaimsIdentity(
                new[] { 
                    // adding following 2 claim just for supporting default antiforgery provider
                    new Claim(ClaimTypes.NameIdentifier, email),
                    new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
                    "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
                    new Claim(ClaimTypes.Name, email),

                    // optionally you could add roles if any
                    // new Claim(ClaimTypes.Role, "RoleName"),
                    // new Claim(ClaimTypes.Role, "AnotherRole"),

                }, "UserAuthenticated");

但是我不知道在哪里/如何指定“UserAuthenticated”AuthenticationType。

.net asp.net-mvc authentication asp.net-identity claims-based-identity
1个回答
0
投票

我会自己回答并粘贴代码的相关部分。

程序.cs:

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.AccessDeniedPath = "/login";
        options.LoginPath = "/";
    });

登录.cshtml.cs

AWS_Manager aws = new AWS_Manager(TestController.access_id, TestController.secret_key);

UserModel oUser = await Task.Run(() => aws.getUser(Input.Email));
if (oUser != null)
{
    if (oUser.Password == Crypto.GetSHA1(Input.Password)) // && oUser.testloader_enabled == true)
    {
        //SetUser(Input.Email);
        //result = SignInResult.Success;

        //A claim is a statement about a subject by an issuer and    
        //represent attributes of the subject that are useful in the context of authentication and authorization operations.    
        var claims = new List<Claim>() {
                    // adding following 2 claim just for supporting default antiforgery provider
                    new Claim(ClaimTypes.NameIdentifier, Input.Email),
                    new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
                    "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
                    new Claim(ClaimTypes.Name, Input.Email),

                    // optionally you could add roles if any
                    // new Claim(ClaimTypes.Role, "RoleName"),
                    // new Claim(ClaimTypes.Role, "AnotherRole"),
        };
        //Initialize a new instance of the ClaimsIdentity with the claims and authentication scheme    
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        //Initialize a new instance of the ClaimsPrincipal with ClaimsIdentity    
        var principal = new ClaimsPrincipal(identity);
        //SignInAsync is a Extension method for Sign in a principal for the specified scheme.    
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
        {
            IsPersistent = Input.RememberMe
        });
        return LocalRedirect(returnUrl);
    }
}

_LoginPartial.cshtml:

@if (User.Identity.IsAuthenticated)
{
    ...

现在可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.