0

我的应用程序正在使用 Microsoft Identity Web,并且是 BFF。(后端换前端)。它服务于 SPA,负责对真实 API 的身份验证和代理 API 调用。身份验证存储在 cookie 中。这样,SPA 不需要任何身份验证,除了类似api/users/me调用以确定用户是谁的调用。您甚至无法访问 HTML/CSS/JS,因为在您访问它之前,SPA 会将您重定向到 Microsoft 登录。

这在文档或示例中并没有真正涵盖,所以我想知道以下内容。我的注销当前是否正确实施?

请查看我的代码和以下有关它的问题。请注意,类似的东西AddMicrosoftIdentityUi()已添加到我的代码库中,但未在代码中添加以保持简短(呃)。

授权设置:

// Read up on SameSite cookies for more information:
// Copied from https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/f8a37e010cacbc48b63e7d8b875b18b9a2c17313/1-WebApp-OIDC/1-1-MyOrg/Startup.cs
// https://github.com/AzureAD/microsoft-identity-web/wiki/SameSite-Cookies
services.Configure<CookiePolicyOptions>(options =>
{
    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
    options.CheckConsentNeeded = context => false;
    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
    // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
    options.HandleSameSiteCookieCompatibility();
});

// We use these custom cookie, ticket and token settings to avoid them being set as session tokens, which AddMicrosoftIdentityWebAppAuthentication() would do by default.
// With these settings they are valid for 90 days which means that even if you logged out of your account somewhere else, you'd still be logged in here.
// The problem with session cookies is that the app is installable as a PWA and if you were to end your session by closing your browser and/or log out somewhere else, you'd have to log in again constantly.
// This is actually a feature of single sign out, but could also be annoying for the user. 
// TODO: Perhaps we could investigate a while after launch if users would prefer real single sign out, which would mean using session cookies.
services.Configure<CookieAuthenticationOptions>(WellKnownAuthenticationSchemes.CookieName, opt =>
{
    opt.Cookie.IsEssential = true;
    opt.Cookie.Name = "cookie_name";
    // Note: This is not secure, but required for Safari because it is a stupid browser.
    // Safari does not work with SSM.Lax, which would be more secure against CSRF.
    // Read more here:
    // https://github.com/IdentityServer/IdentityServer4/issues/2595
    // https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-5.0
    // Or google stuff like "Safari login azure ad infinite loop" or "safari samesite" etc...
    opt.Cookie.SameSite = SameSiteMode.None;
    opt.Cookie.SecurePolicy = Environment.IsDevelopment()
        ? CookieSecurePolicy.SameAsRequest
        : CookieSecurePolicy.Always;
    opt.Cookie.HttpOnly = true;
    opt.SlidingExpiration = true;
    opt.ExpireTimeSpan = TimeSpan.FromDays(90);
});
services.Configure<MicrosoftIdentityOptions>(opt =>
{
    opt.Events.OnTicketReceived = context =>
    {
        // Mark the authentication properties as persistent, so the cookie expiration settings will be applied
        context.Properties.IsPersistent = true;
        return Task.CompletedTask;
    };
});

services.Configure<MsalDistributedTokenCacheAdapterOptions>(opt =>
{
    opt.SlidingExpiration = TimeSpan.FromDays(90);
});

if (Configuration.GetValue("Features:UseDistributedCache", false))
{
    var connectionString = Configuration.GetConnectionString("DistributedSqlCache");
    services.AddDistributedSqlServerCache(options =>
    {
        options.ConnectionString = connectionString;
        options.TableName = "DistributedCache";
        options.SchemaName = "cache";
    });
}

services.AddAuthentication(WellKnownAuthenticationSchemes.CookieName);

services
    .AddMicrosoftIdentityWebAppAuthentication(Configuration,
        cookieScheme: WellKnownAuthenticationSchemes.CookieName)
    .EnableTokenAcquisitionToCallDownstreamApi(Configuration.GetValue<string>("Scopes").Split(" "))
    .AddDistributedTokenCaches();

var dataProtectionBuilder = services.AddDataProtection();

if (Configuration.GetValue("Features:PersistDataProtectionToDisk", false))
{
    dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo(Configuration.GetValue<string>("DataProtection:Path")));
}

登出:


// Note: The SPA has a <form method="POST" action="/logout"> which activates this.
[HttpPost("/logout")]
public IActionResult Logout()
{
    return SignOut(new AuthenticationProperties
    {
        RedirectUri = "/"
    }, WellKnownAuthenticationSchemes.CookieName, WellKnownAuthenticationSchemes.OpenIdConnect);
}

  • 我的注销是否足够好,还是应该在/microsoftidentity/account/signout路径上使用 SignOut?考虑到我使用自定义 cookie 身份验证设置。
  • 如果是这样,我可以改变这条路吗?如果这不能轻易做到,那不是什么大问题。
  • 为什么 SignOut 是 GET 请求?此线程中的大多数人建议使用 POST。为什么选择 GET?
  • 如果我的注销就足够了,我还需要 UI 包吗?
4

0 回答 0