ADFS 如何对用户进行身份验证?

How does ADFS keep a user authenticated?

我正在使用 WsFed 将 ADFS SSO 实施到应用程序中。如果我尝试 运行 [Authorize] 方法,我将被带到登录页面。当我登录时,会创建一个包含加密信息的 cookie,我可以使用 运行 [Authorize] 方法。 cookie 有选项 ExpireTimeSpan = TimeSpan.FromSeconds(10);。到目前为止,这按预期工作,未经授权的用户无法访问该应用程序。

当 cookie 过期、被更改或从浏览器中删除时,混乱就开始了。发生这种情况时,如果我 运行 一个 [Authorized] 方法,我将自动再次登录而无需重新输入我的凭据并重新创建 cookie。但是,如果我使用 return SignOut(... 方法明确注销,则需要重新输入我的凭据。

如果我删除了 cookie,为什么 ADFS 会重新验证我的身份?它是如何知道这样做的?如果我明确注销,它不会这样做。是否应该保持身份验证取决于 cookie 是否具有正确的值?

Startup.ConfigureServices 中的身份验证设置:

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
    options.Wtrealm = Configuration["AppSettings:wsfed:realm"];
    options.MetadataAddress = Configuration["AppSettings:wsfed:metadata"];
    options.UseTokenLifetime = false;
})
.AddCookie(options =>
{
    options.Cookie.Name = "AuthenticationCookie";
    options.LoginPath = "/signin-wsfed";
    options.LogoutPath = "/NameController/Logout";
    options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
    options.SlidingExpiration = true;
});

登录操作:

[AllowAnonymous]
[HttpGet]
public IActionResult Login()
{
    var authProperties = new AuthenticationProperties
    {
        RedirectUri = "https://app:1234/NameController/Index",
    };

    return Challenge(authProperties, WsFederationDefaults.AuthenticationScheme);
}

注销操作:

[AllowAnonymous]
[HttpGet]
public IActionResult SignOutOfADFS()
{
    return SignOut(
        new AuthenticationProperties
        {
            RedirectUri = "https://app:1234/NameController/AfterLogout"
        },
        CookieAuthenticationDefaults.AuthenticationScheme,
        WsFederationDefaults.AuthenticationScheme);
}

A​​D FS 是一种身份提供者,通常用于单点登录。作为其中的一部分,一个关键功能是 AD FS 确实记住登录用户以便为另一个网站验证他们。它通过记住用户使用单独的会话来实现这一点,该会话使用 AD FS 网站的 cookie 持续存在。

当您从您的应用程序本地注销时,您所做的只是清除您的 local cookie。因此,当您尝试再次进行身份验证并且用户被要求通过身份提供者进行身份验证时,AD FS 能够让用户登录而无需再次询问他们的凭据。对于 AD FS,您的应用程序就像第三个网站,在用户已经登录到 AD FS 后要求进行身份验证。

为了完全退出,您必须执行 WSFederation 退出。作为该过程的一部分,本地 cookie 被清除,然后用户被重定向到 AD FS 注销页面,其中 AD FS 身份验证 cookie 也被清除。在随后的身份验证尝试中,AD FS 不再记住用户(因为没有 cookie),因此他们必须使用其凭据再次进行身份验证。这就是您在 SignOutOfADFS 操作中所做的。

WSFederation 协议支持身份验证应用程序通过在身份验证请求中传递 wfresh=0 参数来要求用户通过身份提供者重新进行身份验证的方法。这在当前的 AD FS 版本中也受支持。不幸的是,我认为 ASP.NET Core 的 WSFederation 身份验证处理程序目前不支持此参数。不过,它不会真正阻止用户重复使用他们的身份验证,因此您将无法使用此安全功能。