ASP.NET身份的可变cookie路径

时间:2015-04-08 14:50:26

标签: cookies asp.net-identity owin

我们将多租户MVC应用程序从ASP.NET成员资格提供程序迁移到ASP.NET标识。

这是我的Startup.Auth.cs(简化):

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity =
                    SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, Identity, int>(
                        TimeSpan.FromMinutes(30),
                        (manager, user) =>
                            manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie),
                        clIdentity => clIdentity.GetUserId<int>())
            }
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}

在我们的多租户申请中,每个租户都有自己的'slug'(例如http://example.com/tenant1/http://example.com/tenant2/

但是,目前,cookie存储在根目录中。这会导致安全问题,因为来自tenant1的用户会自动从tenant2登录网站。

我们如何制作CookiePath(在CookieAuthenticationOptions中)变量,以便它根据租户而变化?

3 个答案:

答案 0 :(得分:6)

我在dampee的帮助下解决了这个问题。

CookieAuthenticationOptions 对象中的 CookiePath 仅评估一次:在应用程序启动时。 最简单的解决方案(解决方法)是创建一个派生的 CookieAuthenticationProvider ,它会覆盖 ResponseSignIn ResponseSignOut 。 它们都有一个名为 context 的参数,它有一个名为 CookiePath 的属性。在这两种方法中修改此属性以更改CookiePath。 您还可以use the class I created

然后,您所要做的就是将 CookieAuthenticationOptions 中的 CookieAuthenticationProvider 替换为您刚刚创建的 CookieAuthenticationProvider

这适用于ApplicationCookie。 ExternalSignInCookie并不重要,因为它只是在使用外部登录登录时暂时使用。

答案 1 :(得分:2)

改进SamuelDebruyn自己的解决方案,我发现你可以使用AuthenticationProperties对象将SignIn调用的路径传递给提供者。这样,您可以从源代码中明确地从请求上下文中提取路径:

// method inside web api controller
private void SignIn(string name, string cookiePath)
{
    var claims = new[] { new Claim(ClaimTypes.Name, name) };
    var identity = new ClaimsIdentity(claims, "ApplicationCookie");

    var options = new AuthenticationProperties();
    options.Dictionary["CustomCookiePath"] = cookiePath;

    var authManager = Request.GetOwinContext().Authentication;
    authManager.SignIn(options, identity);
}

// Startup.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    Provider = new CustomCookieProvider()
});

// custom provider
public class CustomCookieProvider : CookieAuthenticationProvider
{
    public override void ResponseSignIn(CookieResponseSignInContext context)
    {
        context.CookieOptions.Path = context.Properties.Dictionary["CustomCookiePath"];
        base.ResponseSignIn(context);
    }
}

答案 2 :(得分:1)

您可以使用自定义current_zone()根据请求中的内容动态地将Cookie值返回到ICookieManager,为此,您仍然可以将CookiePath维护为&#34; /& #34;然后将其留给CookieAuthenticationProvider,以便随时返回(或写入)cookie。 ICookieManager上的CookieManager是一个选项。我在这里写了博客:http://shazwazza.com/post/owin-cookie-authentication-with-variable-cookie-paths/