在 ASP.NET 5 跨子域共享身份验证 Cookie
Sharing Authentication Cookie in ASP.NET 5 across subdomains
我有两个 ASP.NET 5 MVC 6 应用程序。
一个 运行 在 www.mydomain.tld
,一个在 world1.mydomain.tld
。
如果用户登录 www 子域的应用程序,我希望她也登录 world1 子域的应用程序。使用ASP.NET身份实现登录 3.
我在 Startup.cs
中设置了两个应用程序,如下所示:
public void ConfigureServices (IServiceCollection services) {
// [...]
services.AddCaching();
services.AddSession(
options => {
options.CookieDomain = ".mydomain.tld";
options.IdleTimeout = TimeSpan.FromMinutes(30);
}
);
// [...]
}
public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory) {
// [...]
app.UseCookieAuthentication(null, IdentityOptions.ExternalCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
app.UseCookieAuthentication(
config => {
config.CookieDomain = ".mydomain.tld";
},
IdentityOptions.ApplicationCookieAuthenticationScheme
);
// [...]
}
我还通过 web.config
设置了两个应用程序的机器密钥,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<machineKey decryption="AES"
decryptionKey="SOME DECRYPTION KEY"
validation="HMACSHA256"
validationKey="SOME ENCRYPTION KEY" />
</system.web>
</configuration>
登录 www 子域有效,但访问 world1 子域上的站点无效,因为身份验证 cookie 未被识别为有效的登录 cookie。
我做错了什么?
应用程序彼此 automatically isolated。您需要确保三件事;
- 他们使用相同的密钥库
- 他们使用相同的应用程序 ID。
- 它们在同一个应用程序池中,或者每个池中的标识相同。
Apps 运行在同一台主机上,在相同的托管机制下将使用相同的密钥库。如果它们在不同的机器上,您将需要使用网络驱动器上的密钥存储,或其他共享位置,例如 azure blob 存储。
为了设置两个应用程序通用的应用程序 ID,您需要 configure 数据保护堆栈。
例如,
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
services.ConfigureDataProtection(configure =>
{
configure.SetApplicationName("my application");
});
}
如果您需要 运行 应用程序作为不同的用户,那么您需要更改密钥的保护方式以使用机器级 DPAPI 或 X509 证书。
您不需要在您的 web.config 中输入机器密钥,机器密钥不再是用户。
我有两个 ASP.NET 5 MVC 6 应用程序。
一个 运行 在 www.mydomain.tld
,一个在 world1.mydomain.tld
。
如果用户登录 www 子域的应用程序,我希望她也登录 world1 子域的应用程序。使用ASP.NET身份实现登录 3.
我在 Startup.cs
中设置了两个应用程序,如下所示:
public void ConfigureServices (IServiceCollection services) {
// [...]
services.AddCaching();
services.AddSession(
options => {
options.CookieDomain = ".mydomain.tld";
options.IdleTimeout = TimeSpan.FromMinutes(30);
}
);
// [...]
}
public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory) {
// [...]
app.UseCookieAuthentication(null, IdentityOptions.ExternalCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
app.UseCookieAuthentication(
config => {
config.CookieDomain = ".mydomain.tld";
},
IdentityOptions.ApplicationCookieAuthenticationScheme
);
// [...]
}
我还通过 web.config
设置了两个应用程序的机器密钥,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<machineKey decryption="AES"
decryptionKey="SOME DECRYPTION KEY"
validation="HMACSHA256"
validationKey="SOME ENCRYPTION KEY" />
</system.web>
</configuration>
登录 www 子域有效,但访问 world1 子域上的站点无效,因为身份验证 cookie 未被识别为有效的登录 cookie。
我做错了什么?
应用程序彼此 automatically isolated。您需要确保三件事;
- 他们使用相同的密钥库
- 他们使用相同的应用程序 ID。
- 它们在同一个应用程序池中,或者每个池中的标识相同。
Apps 运行在同一台主机上,在相同的托管机制下将使用相同的密钥库。如果它们在不同的机器上,您将需要使用网络驱动器上的密钥存储,或其他共享位置,例如 azure blob 存储。
为了设置两个应用程序通用的应用程序 ID,您需要 configure 数据保护堆栈。
例如,
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
services.ConfigureDataProtection(configure =>
{
configure.SetApplicationName("my application");
});
}
如果您需要 运行 应用程序作为不同的用户,那么您需要更改密钥的保护方式以使用机器级 DPAPI 或 X509 证书。
您不需要在您的 web.config 中输入机器密钥,机器密钥不再是用户。