简体   繁体   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?

This is about an application aspnetcore 3.0 with EF core In which login security and authorization was added using openID.这是关于带有 EF 核心的应用程序 aspnetcore 3.0,其中使用 openID 添加了登录安全性和授权。 The problem although users do ends up in the EF core DB, and validation does happens at openID.尽管用户确实最终出现在 EF 核心数据库中,但问题确实发生在 openID 上。 That after login the partial view does not recognize that the user is logged in. So I cant make use of the username or email at other pages, kinda weird.登录后部分视图无法识别用户已登录。所以我不能在其他页面使用用户名或 email,有点奇怪。
loginpartial.cs:登录部分.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

I got the idea there is something wrong with my program.cs in which the whole configuration is givven, that i somehow have to transfer the current user towards the previous injected user manager or so.我的想法是我的 program.cs 有问题,其中给出了整个配置,我必须以某种方式将当前用户转移到以前注入的用户管理器左右。
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 its not about older MVC5 applications, its MVC6 here) (PS 它不是关于旧的 MVC5 应用程序,它的 MVC6 在这里)

Hard to say without running your code locally (which I have not done).如果不在本地运行您的代码(我没有这样做),很难说。

I am, however, suspicious of how you are mapping controllers and injecting authorization to them.但是,我怀疑您如何映射控制器并向它们注入授权。

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?}");

Why the difference between the two?为什么两者有区别? Ie why does the first require authorization while the second does not?即为什么第一个需要授权而第二个不需要?

Why not use something simple like the below?为什么不使用像下面这样简单的东西?

app.MapControllers().RequireAuthorization();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM