我让OIDC使用ID4和ASP.Net Core Identity来管理用户成员身份。带有Pagemodel的Razor。我有一个可以正确使用SSO登录的测试客户端。注销时,它将注销客户端OK,但不会从ID4服务器注销。
注销时,客户端使用结束会话URL重定向到我的ID4服务器。它确实具有提示令牌。 ID4服务器的确显示了注销页面,但仍处于登录状态。我怀疑问题是我使用了脚手架的ASP.Net Identity页面进行登录/注销。
手动单击ID4服务器上的注销按钮即可正常工作。用户已在服务器和客户端上登录。
我能够通过重定向到ASP.Net Core Indentity注销页面并使其具有OnGet方法调用_signInManager.SignOutAsync()来使其工作。但这对我来说似乎是一个糟糕的解决方案。
阅读ID4文档,规范以及许多github和SO帖子,我在客户端上有以下注销代码:
var id_token = (await HttpContext.AuthenticateAsync()).Properties.Items[".Token.id_token"];
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
var redirectUrl = $"{Startup.IdentityServerUrl}/connect/endsession?id_token_hint={id_token}";
return Redirect(redirectUrl);
这是我的客户端的启动代码:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = IdentityServerUrl;
options.RequireHttpsMetadata = false;
options.ClientId = "testClient1";
options.ClientSecret = "xxxxxxxxxxxxx";
options.ResponseType = "code";
options.SaveTokens = true;
});
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/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.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute()
.RequireAuthorization();
});
}
这是我的ID4服务器的启动代码:
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
services.AddIdentity<ApplicationUser, IdentityRole>(
config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.SignIn.RequireConfirmedAccount = true;
config.User.RequireUniqueEmail = true;
config.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
config.Lockout.MaxFailedAccessAttempts = 5;
config.Lockout.AllowedForNewUsers = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// these point ID4 to the correct pages for login, logout, etc.
services.ConfigureApplicationCookie((options) =>
{
options.LoginPath = "/Identity/Account/Login";
options.LogoutPath = "/Identity/Account/Logout";
options.AccessDeniedPath = "/Error";
});
services.AddIdentityServer()
.AddOperationalStore(options =>
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString, sqlOptions => sqlOptions.MigrationsAssembly(migrationsAssembly)))
.AddConfigurationStore(options =>
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString, sqlOptions => sqlOptions.MigrationsAssembly(migrationsAssembly)))
.AddAspNetIdentity<ApplicationUser>()
.AddDeveloperSigningCredential();
ConfigureEmailServices(services);
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
InitializeDbTestData(app);
}
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.UseAuthentication();
app.UseAuthorization();
app.UseIdentityServer();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
答案 0 :(得分:1)
对于idp注销,您无需手动重定向。只需返回一个SignOutResult
,重定向将由oidc处理程序通过使用发现端点并正确装入请求来完成。将此代码放入您的注销方法:
return SignOut(new[] { "Cookies", "oidc" });
或者其他:
return new SignOutResult(new[] { "Cookies", "oidc" });
如果要在idp注销后重定向到客户端,请设置postLogoutRedirectUri。