C# IdentityServer4+;从客户端注销ASP.Net核心标识不会在ID4上注销

C# IdentityServer4+;从客户端注销ASP.Net核心标识不会在ID4上注销,c#,asp.net,asp.net-identity,identityserver4,C#,Asp.net,Asp.net Identity,Identityserver4,我知道我正在使用ID4 for OIDC和ASP.Net核心标识来管理用户成员身份。带有页面模型的剃须刀。我有一个使用SSO正确登录的测试客户端。注销时,它可以从客户端注销,但不会从ID4服务器注销 注销时,客户端使用结束会话url重定向到我的ID4服务器。它确实有提示标记。ID4服务器确实显示了注销页面,但仍在登录。我怀疑问题在于我正在使用ASP.Net身份页进行登录/注销 手动单击ID4服务器上的注销按钮可以正常工作。用户已登录到服务器和客户端 我可以通过重定向到ASP.Net Core I

我知道我正在使用ID4 for OIDC和ASP.Net核心标识来管理用户成员身份。带有页面模型的剃须刀。我有一个使用SSO正确登录的测试客户端。注销时,它可以从客户端注销,但不会从ID4服务器注销

注销时,客户端使用结束会话url重定向到我的ID4服务器。它确实有提示标记。ID4服务器确实显示了注销页面,但仍在登录。我怀疑问题在于我正在使用ASP.Net身份页进行登录/注销

手动单击ID4服务器上的注销按钮可以正常工作。用户已登录到服务器和客户端

我可以通过重定向到ASP.Net Core Indentity注销页面并让OnGet方法调用_signInManager.SignOutAsync()使其正常工作。但这对我来说似乎是个糟糕的解决方案

阅读ID4文档、规范和许多github等帖子,我的客户端上有以下注销代码:

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();
        });

    }
以下是我的客户机的启动代码:

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();
        });
    }
public void配置服务(IServiceCollection服务)
{
var connectionString=Configuration.GetConnectionString(“DefaultConnection”);
var migrationassembly=typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext(选项=>
使用SQLServer(connectionString));
服务附加性(
配置=>
{
config.SignIn.RequireConfirmedEmail=true;
config.SignIn.RequireConfirmedAccount=true;
config.User.RequireUniqueEmail=true;
config.locket.DefaultLockoutTimeSpan=TimeSpan.FromMinutes(5);
config.locket.MaxFailedAccessAttempts=5;
config.locket.AllowedForNewUsers=true;
})
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
//这些将ID4指向用于登录、注销等的正确页面。
services.configureApplicationOkie((选项)=>
{
options.LoginPath=“/Identity/Account/Login”;
options.LogoutPath=“/Identity/Account/Logout”;
options.AccessDeniedPath=“/Error”;
});
services.AddIdentityServer()
.addStore(选项=>
options.ConfigureDbContext=builder=>
builder.UseSqlServer(connectionString,sqlOptions=>sqlOptions.MigrationsAssembly(MigrationsAssembly)))
.AddConfigurationStore(选项=>
options.ConfigureDbContext=builder=>
builder.UseSqlServer(connectionString,sqlOptions=>sqlOptions.MigrationsAssembly(MigrationsAssembly)))
.AddAsNetIdentity()
.AddDeveloperSigningCredential();
配置电子邮件服务(服务);
services.AddRazorPages();
}
//此方法由运行时调用。使用此方法配置HTTP请求管道。
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
初始化的BTestData(应用程序);
}
其他的
{
app.UseExceptionHandler(“/Home/Error”);
//默认的HSTS值为30天。您可能希望在生产场景中更改此值,请参阅https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseIdentityServer();
app.UseEndpoints(端点=>
{
endpoints.MapControllerRoute(
名称:“默认”,
模式:“{controller=Home}/{action=Index}/{id?}”);
endpoints.MapRazorPages();
});
}

对于idp注销,您不需要手动重定向。只需返回一个
SignOutResult
,oidc处理程序将通过使用发现端点并正确装载请求来完成重定向。将此代码放入您的注销方法中:

 return SignOut(new[] { "Cookies", "oidc" });
或其他:

return new SignOutResult(new[] { "Cookies", "oidc" });

如果您想在idp注销后重定向到客户端,请设置postLogoutRedirectUri。

如何设置postLogoutRedirectUri?此设置在客户端配置中Hi,您找到解决此问题的方法了吗?