将身份与 SSO 一起使用时,用户在成功登录后始终无法进行身份验证

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

我需要允许用户通过 SSO 或身份登录进行身份验证。

我可以让其中任何一个单独工作,但是当试图允许两者都工作时,我得到了这个:

SSO 按预期工作并且用户已通过身份验证。

身份登录成功后,用户将被重定向,并且在控制器中检查身份验证状态,但始终为 false。

我认为program.cs可能是错误的,这里是,以及控制器方法:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.UI.Services;
using Serilog.Sinks.MSSqlServer;
using Serilog;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;

var builder = WebApplication.CreateBuilder(args);

// Configure database connection
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();

// Configure Identity services
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
    options.SignIn.RequireConfirmedAccount = false; // Adjust according to your needs
})
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();

// Configure OpenID Connect Authentication
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Use cookies by default
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; // Challenge with OpenID Connect
})
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();

builder.Services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.SameSite = SameSiteMode.Lax;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.Cookie.HttpOnly = false;
});



// Configure logging
Log.Logger = new LoggerConfiguration()
    .WriteTo.MSSqlServer(
        connectionString: builder.Configuration.GetConnectionString("DefaultConnection"),
        sinkOptions: new MSSqlServerSinkOptions
        {
            TableName = "Logs",
            AutoCreateSqlTable = true
        },
        restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information,
        columnOptions: new ColumnOptions())
    .CreateLogger();
builder.Host.UseSerilog();

// Add services and Razor Pages
builder.Services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();
builder.Services.AddHttpContextAccessor();

// Configure CORS policy
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", builder =>
        builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});

// Register other application services
builder.Services.AddTransient<IEmailTemplateService, EmailTemplateService>();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("SmtpSettings"));
builder.Services.AddTransient<ISiteService, SiteService>();
builder.Services.AddTransient<IDocumentService, DocumentService>();
builder.Services.AddTransient<IUtilitiesService, UtilitiesService>();
builder.Services.AddTransient<IRemediationsService, RemediationsService>();
builder.Services.AddTransient<IViewRenderService, ViewRenderService>();
builder.Services.AddTransient<IApplicationService, ApplicationService>();
builder.Services.AddTransient<IPdfService, PdfService>();

var app = builder.Build();

// Configure the HTTP request pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

// Set IronPdf license key
var provider = app.Services;
var configuration = provider.GetRequiredService<IConfiguration>();
IronPdf.License.LicenseKey = configuration.GetSection("Keys").GetValue<string>("IronPdf.LicenseKey");

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseFileServer();
app.UseRouting();
app.UseCors("AllowAll");
app.UseAuthentication();
app.UseAuthorization();

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

app.UseStatusCodePagesWithRedirects("/Error/{0}");

app.Run();

用户登录方式:

[HttpPost]
[AllowAnonymous]
[Route("LoginUser")]
public async Task<IActionResult> LoginUser(LoginModel model, string returnUrl = null)
{
    try
    {
        Log.Information("Login attempted: " + model.Email);
        ViewData["ReturnUrl"] = returnUrl;

        var result = await signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            Log.Information("Successful Identity login: " + User.Identity.Name);

            return Ok(new { message = "Success", redirectUrl = Url.Action("Home", "Accounts") });
        }
        else
        {
            Log.Error("Invalid login: " + model.Email);
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return BadRequest(new { message = "Unsuccessful" });
        }
    }
    catch (Exception ex)
    {
        Log.Error("Error on login: " + model.Email + " " + ex.Message);
        ModelState.AddModelError(string.Empty, "Error login attempt.");
        return BadRequest(new { message = ex.Message });
    }
}

当我在

if (result.Succeeded)

上设置断点时就成功了

我们重定向到的控制器方法验证失败:

[Route("/accounts/home")]
public IActionResult Home()
{

    if (User.Identity.IsAuthenticated)
    {
        return View();
    }
    return RedirectToAction("Login", "Home");
}
c# asp.net-mvc asp.net-identity single-sign-on
1个回答
0
投票

注意身份验证方案,Identity 的默认方案是 Identity.Application

您可以查看AddDefaultIdentity方法的代码:

public static IdentityBuilder AddDefaultIdentity<TUser>(this IServiceCollection services, Action<IdentityOptions> configureOptions) where TUser : class
{
    services.AddAuthentication(o =>
    {
        o.DefaultScheme = IdentityConstants.ApplicationScheme;
        o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    })
    .AddIdentityCookies(o => { });

    return services.AddIdentityCore<TUser>(o =>
    {
        o.Stores.MaxLengthForKeys = 128;
        configureOptions?.Invoke(o);
    })
        .AddDefaultUI()
        .AddDefaultTokenProviders();
}



public class IdentityConstants
{
    private const string IdentityPrefix = "Identity";

    /// <summary>
    /// The scheme used to identify application authentication cookies.
    /// </summary>
    public static readonly string ApplicationScheme = IdentityPrefix + ".Application";

    /// <summary>
    /// The scheme used to identify bearer authentication tokens.
    /// </summary>
    public static readonly string BearerScheme = IdentityPrefix + ".Bearer";

    /// <summary>
    /// The scheme used to identify combination of <see cref="BearerScheme"/> and <see cref="ApplicationScheme"/>.
    /// </summary>
    internal const string BearerAndApplicationScheme = IdentityPrefix + ".BearerAndApplication";

    /// <summary>
    /// The scheme used to identify external authentication cookies.
    /// </summary>
    public static readonly string ExternalScheme = IdentityPrefix + ".External";

    /// <summary>
    /// The scheme used to identify Two Factor authentication cookies for saving the Remember Me state.
    /// </summary>
    public static readonly string TwoFactorRememberMeScheme = IdentityPrefix + ".TwoFactorRememberMe";

    /// <summary>
    /// The scheme used to identify Two Factor authentication cookies for round tripping user identities.
    /// </summary>
    public static readonly string TwoFactorUserIdScheme = IdentityPrefix + ".TwoFactorUserId";
}

在这里您将默认的身份验证方案修改为Cookies

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Use cookies by default
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; // Challenge with OpenID Connect
})

您必须使用

[Authorize(AuthenticationSchemes ="Identity.Application")]
或其他方式选择身份验证方案,您可以阅读此文档了解更多详细信息

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