簡體   English   中英

aspnet 3.1 openidconnect 6.0.5 身份驗證,登錄,IsSignedIn(User) 保持為假?

[英]aspnet 3.1 openidconnect 6.0.5 authentication, getting logged in, IsSignedIn(User) stays false?

這是關於帶有 EF 核心的應用程序 aspnetcore 3.0,其中使用 openID 添加了登錄安全性和授權。 盡管用戶確實最終出現在 EF 核心數據庫中,但問題確實發生在 openID 上。 登錄后部分視圖無法識別用戶已登錄。所以我不能在其他頁面使用用戶名或 email,有點奇怪。
登錄部分.cs:

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

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{   ... it never knows that the user is signed in
    ... despite i did get loged on by external service, and endup at the default page

我的想法是我的 program.cs 有問題,其中給出了整個配置,我必須以某種方式將當前用戶轉移到以前注入的用戶管理器左右。
程序.cs:

using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Newtonsoft.Json.Serialization;
using MyApplication.Data;

bool useAuthentication = true;
MyApplication.Common.AppConfig.AddOrUpdate("config:args",args);

var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddControllersWithViews();
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});

if (useAuthentication)
{
builder.Services.AddAuthentication(options =>
    {
     options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie(options=>options.ExpireTimeSpan = TimeSpan.FromMinutes(1))
.AddOpenIdConnect(options =>
{
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.ClientId = builder.Configuration["OpenID:ClientID"];
    options.ClientSecret = builder.Configuration["OpenID:ClientSecret"];
    options.Authority = builder.Configuration["OpenID:Authority"];
    options.CallbackPath = builder.Configuration["OpenID:CallbackPath"];
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.ClaimActions.MapUniqueJsonKey("username", "username");

    options.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = tokencontext =>
        {
        // I could do something here with current user, 
        // though user does get into EF core thus ehm do i need this ??

            return Task.CompletedTask;
        },
        OnTicketReceived = context =>
        {
            // If authentication logic is based on users then add your logic here
            return Task.CompletedTask;
        },
        OnAuthenticationFailed = context =>
        {
            context.Response.Redirect("/Home/Error");
            context.HandleResponse(); // Suppress the exception
            return Task.CompletedTask;
        },
    };
    });
}

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
}

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

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

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

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

app.MapControllerRoute(name: "api", pattern: "api/{controller=Api}/{Action=Test}/{id?}/{country?}");

app.MapRazorPages();
app.Run();

(PS 它不是關於舊的 MVC5 應用程序,它的 MVC6 在這里)

如果不在本地運行您的代碼(我沒有這樣做),很難說。

但是,我懷疑您如何映射控制器並向它們注入授權。

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

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

app.MapControllerRoute(name: "api", pattern: "api/{controller=Api}/{Action=Test}/{id?}/{country?}");

為什么兩者有區別? 即為什么第一個需要授權而第二個不需要?

為什么不使用像下面這樣簡單的東西?

app.MapControllers().RequireAuthorization();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM