我有一个网页,它为同一个应用程序使用多个URL:
例如: * .MyWebPage.com.au * .YourWebPage.com.au
因此它将在多个网址上使用子域名。问题是我需要允许用户在他们登录的URL的所有子域上进行身份验证。
例如,如果他们通过www.mywebpage.com.au登录,则需要为* .mywebpage.com.au设置cookie,或者如果他们通过www.yourwebpage.com.au登录,则cookie应为* .yourwebpage .com.au。
允许ASP.NET核心标识子域的大多数文档都指向startup.cs(或startup.auth.cs)文件并输入如下内容:`
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieDomain = "mywebpage.com.au"
});`
这对我不起作用,因为我不想要一个固定的域名,我只想让所有用户都可以访问他们登录的URL的所有子域名。我可以通过请求显然在登录时获取他们的URL,但我需要动态设置cookiedomain。
答案 0 :(得分:6)
我开始时没想到的是Identity和CookeieAuthentication之间的区别。 因为我使用的是身份
app.UseIdentity();
app.UseCookieAuthentication不是解决方案。
我终于通过实施ICookieManager找到了我的解决方案。
这是我的解决方案:
在Startup.cs中:
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequiredLength = 5;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Cookies.ApplicationCookie.CookieManager = new CookieManager(); //Magic happens here
}).AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
现在在一个叫做CookieManager.cs的类中:
public class CookieManager : ICookieManager
{
#region Private Members
private readonly ICookieManager ConcreteManager;
#endregion
#region Prvate Methods
private string RemoveSubdomain(string host)
{
var splitHostname = host.Split('.');
//if not localhost
if (splitHostname.Length > 1)
{
return string.Join(".", splitHostname.Skip(1));
}
else
{
return host;
}
}
#endregion
#region Public Methods
public CookieManager()
{
ConcreteManager = new ChunkingCookieManager();
}
public void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options)
{
options.Domain = RemoveSubdomain(context.Request.Host.Host); //Set the Cookie Domain using the request from host
ConcreteManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(HttpContext context, string key, CookieOptions options)
{
ConcreteManager.DeleteCookie(context, key, options);
}
public string GetRequestCookie(HttpContext context, string key)
{
return ConcreteManager.GetRequestCookie(context, key);
}
#endregion
答案 1 :(得分:3)
除了@ michael的解决方案:
ICookie
:ICookie Interface
是http cookie object
之上的抽象层,用于保护data
。ICookieManager
:Cookie Manager
是ICookie Interface
之上的抽象层。这会根据<TSource>
通用支持Func<TResult>
扩展Cookie行为。这由DefaultCookieManager
类实现。 ICookie Interface
是这门课程的完整之处。 CookieManager
的用法:
CookieManager
。git
Nemi Chand上找到。答案 2 :(得分:1)
有多少主要域名?如果没有太多,可以添加几个CookieAuthenticationOptions。像这样:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "mywebpage.com.au",
CookieDomain = "mywebpage.com.au",
});
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "yourwebpage.com.au",
CookieDomain = "yourwebpage.com.au",
});
如果主域名太多,您需要编写自己的cookie提供程序。
答案 3 :(得分:1)
除了@ michael的回答: 如何“处理deletecookie事件,添加options.Domain = RemoveSubdomain(context.Request.Host.Host)”: 只需添加
options.Domain= RemoveSubdomain(context.Request.Host.Host);
前
ConcreteManager.DeleteCookie(context, key, options);
in
CookieManager.DeleteCoockie(..){..};
不要忘记在注销时调用CookieManager.DeleteCoockie!
PS此外,如果您需要能够在subdomain.example.com和example.com上同时登录 - 您需要修改AppendResponseCookie(..){..},否则您将只获得TLD(.com) /.ru等)这里