具有 ASP.NET 标识的可变 cookie 路径
Variable cookie path with ASP.NET Identity
我们将多租户 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/ and http://example.com/tenant2/)
但是,目前,cookie 存储在根目录中。这会导致安全问题,因为来自租户 1 的用户会自动从租户 2 登录网站。
我们如何使 CookiePath(在 CookieAuthenticationOptions 中)变量使其根据租户而变化?
我在 dampee 的帮助下解决了这个问题。
CookieAuthenticationOptions 对象中的 CookiePath 仅计算一次:在应用程序启动时。
最简单的解决方案(解决方法)是创建一个派生的 CookieAuthenticationProvider,它覆盖 ResponseSignIn 和 ResponseSignOut。
他们都有一个名为 context 的参数,其中有一个名为 CookiePath 的 属性。在这两个方法中修改此 属性 以更改 CookiePath。
您也可以 use the class I created.
然后您所要做的就是将 CookieAuthenticationOptions 中的 CookieAuthenticationProvider 替换为您刚刚创建的
这适用于 ApplicationCookie。 ExternalSignInCookie 无关紧要,因为它仅在使用外部登录名登录时临时使用。
改进 SamuelDebruyn 自己的解决方案,我发现您可以使用 AuthenticationProperties
对象将登录调用的路径传递给提供者。这样,您就可以从源代码中显式传递它,而不是像他的要点所示那样从请求上下文中提取路径:
// 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);
}
}
您可以使用自定义 ICookieManager
根据请求中的内容动态 return 将 cookie 值 CookieAuthenticationProvider
,为此您仍然需要将 CookiePath 保持为“/”,然后将其保留到 ICookieManager
到 return(或写入)您想要的 cookie。 CookieManager
是 CookieAuthenticationOptions
上的一个选项。我在这里写了博客:http://shazwazza.com/post/owin-cookie-authentication-with-variable-cookie-paths/
我们将多租户 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/ and http://example.com/tenant2/)
但是,目前,cookie 存储在根目录中。这会导致安全问题,因为来自租户 1 的用户会自动从租户 2 登录网站。
我们如何使 CookiePath(在 CookieAuthenticationOptions 中)变量使其根据租户而变化?
我在 dampee 的帮助下解决了这个问题。
CookieAuthenticationOptions 对象中的 CookiePath 仅计算一次:在应用程序启动时。 最简单的解决方案(解决方法)是创建一个派生的 CookieAuthenticationProvider,它覆盖 ResponseSignIn 和 ResponseSignOut。 他们都有一个名为 context 的参数,其中有一个名为 CookiePath 的 属性。在这两个方法中修改此 属性 以更改 CookiePath。 您也可以 use the class I created.
然后您所要做的就是将 CookieAuthenticationOptions 中的 CookieAuthenticationProvider 替换为您刚刚创建的
这适用于 ApplicationCookie。 ExternalSignInCookie 无关紧要,因为它仅在使用外部登录名登录时临时使用。
改进 SamuelDebruyn 自己的解决方案,我发现您可以使用 AuthenticationProperties
对象将登录调用的路径传递给提供者。这样,您就可以从源代码中显式传递它,而不是像他的要点所示那样从请求上下文中提取路径:
// 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);
}
}
您可以使用自定义 ICookieManager
根据请求中的内容动态 return 将 cookie 值 CookieAuthenticationProvider
,为此您仍然需要将 CookiePath 保持为“/”,然后将其保留到 ICookieManager
到 return(或写入)您想要的 cookie。 CookieManager
是 CookieAuthenticationOptions
上的一个选项。我在这里写了博客:http://shazwazza.com/post/owin-cookie-authentication-with-variable-cookie-paths/