[英].Net Core 3.1 Merging JWT and OpenIDConnect Authentication
[英]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.