来自客户端的IdentityServer4 + ASP.Net Core身份注销未在ID4上注销

时间:2019-12-30 16:33:55

标签: c# asp.net asp.net-identity identityserver4

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

1 个答案:

答案 0 :(得分:1)

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

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

或者其他:

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

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