使用 Identity Server 对 ASP.NET Web App 和 .NET 6 进行身份验证

Using Identity Server for Authentication with ASP.NET Web App and .NET 6

我们公司有定制的身份服务器,我们的一些 Web 应用程序使用它来进行身份验证。我正在尝试将我们的身份服务器与新创建的 ASP.NET 核心 Web 应用程序一起使用,使用 .NET 6 框架。我正在尝试使用预定义的 OIDC URLs,而不必自己编写代码。

身份验证基本正常;例如,如果我将 [Authorize] 添加到某个 Razor PageModel,它将自动重定向到 Authority URL,然后 return 到该页面并在验证后登录。

我遇到的问题是:我似乎无法让自动注销工作。我正在尝试使用任一预定义的 OIDC signout URLs(signout-oidc 或 signout-callback-oidc),但我似乎遗漏了一些东西。我也很难找到好的示例代码或清晰的文档来帮助调试问题。

我也尝试过使用 OIDC 事件——例如“OnSignedOutCallbackRedirect”:

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", async options =>
    {
        options.Authority = testIdentitySettings.Authority;
        options.SignedOutRedirectUri = testIdentitySettings.SignedOutRedirectUri;
        options.RequireHttpsMetadata = testIdentitySettings.RequireHttpsMetadata ?? true;
        options.ClientId = testIdentitySettings.ClientId;
        options.SignInScheme = "Cookies";
        options.Scope.Add("roles");
        options.SaveTokens = true;

        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name",
            RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
        };

        options.Events.OnSignedOutCallbackRedirect = async (context) =>
        {
            await context.HttpContext.SignOutAsync("Cookies");

            var redirUrl = context.Options.SignedOutRedirectUri;

            var prop = new AuthenticationProperties
            {
                RedirectUri = redirUrl
            };

            await context.HttpContext.SignOutAsync("oidc", prop);

            context.Response.Redirect(redirUrl);
            context.HandleResponse();
        };
    });

这似乎行得通。它确实重定向到我的 SignedOutRedirectUri (/LoggedOut),当我检查该页面上的用户时,User.Identity 显示 IsAuthenticated = false,并且声明为零;但是,如果我随后加载主页 (/),User.Identity 将返回并通过所有声明进行身份验证。

如有任何帮助或见解,我们将不胜感激。

注销的例子可以参考下面的代码

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Auth0.AspNetCore.Authentication;

public class AccountController : Controller
{
    [Authorize]
    public async Task Logout()
    {
        var authenticationProperties = new LogoutAuthenticationPropertiesBuilder()
            // Indicate here where Auth0 should redirect the user after a logout.
            // Note that the resulting absolute Uri must be added to the
            // **Allowed Logout URLs** settings for the app.
            .WithRedirectUri(Url.Action("Index", "Home"))
            .Build();

        await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    }
}

参考:Logout

如果问题仍然存在,您可以尝试使用下面的代码示例进行测试,以减少 AddCookie 配置中的 ExpireTimeSpan

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(/* ... */)
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(1);
            });
        // ...
    }

更多详细信息,请参考

我会用它来注销:

[Authorize]
/// <summary>
/// Do the actual logout
/// </summary>
/// <returns></returns>
public async Task DoLogout()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}

我认为您不需要使用 OnSignedOutCallbackRedirect 处理程序。

在您的情况下,由于您已重命名方案,注销方法应为:

[Authorize]
/// <summary>
/// Do the actual logout
/// </summary>
/// <returns></returns>
public async Task DoLogout()
{
    await HttpContext.SignOutAsync("Cookies");
    await HttpContext.SignOutAsync("oidc");
}