交换Azure Web App部署槽会注销ASP.NET Core RC2中的所有用户

Yel*_*ive 9 c# azure asp.net-identity azure-web-app-service asp.net-core

每当我更新作为Azure Web App运行的ASP.NET Core RC2网站时,它都会注销所有用户.这似乎与将暂存部署槽交换到生产相关(我使用从VS到登台的Web部署,并将其设置为自动交换到生产).如果我直接更新生产槽,那很好,但我不想这样做.我不知道如何配置这个,帮助将不胜感激!

这是我现在如何配置它,我的网站只允许直接登录(没有Facebook登录等):

在Startup中的ConfigureServices中

// found some post that said this would help... doesn't seem to work...
services.AddDataProtection()
        .SetApplicationName("myweb");

services.AddIdentity<MyUser, MyRole>(options =>
{
    options.Cookies.ApplicationCookie.CookieDomain = settings.CookieDomain; // cookie domain lets us share cookies across subdomains
    options.Cookies.ApplicationCookie.LoginPath = new PathString("/account/login");
    options.Cookies.ApplicationCookie.ReturnUrlParameter = "ret";
    options.Cookies.ApplicationCookie.CookieSecure = CookieSecureOption.Never; // TODO: revisit site-wide https

    // allow login cookies to last for 30 days from last use
    options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(60);
    options.Cookies.ApplicationCookie.SlidingExpiration = true;

    // I think this needs to at least be longer than cookie expiration to prevent security stamp from becoming invalid before the cookie?
    options.SecurityStampValidationInterval = TimeSpan.FromDays(90);
})
.AddUserStore<MyUserStore>() // custom stores to hook up our old databases to new identity system
.AddRoleStore<MyRoleStore>()
.AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)

在Configure in Startup中

app.UseIdentity();
Run Code Online (Sandbox Code Playgroud)

Yel*_*ive 15

经过多次研究......我认为我有这个工作.

因此,对于任何想要使用Identity Core登录的ASP.NET Core RC2网站,并希望在Azure Web App上托管它,并希望使用部署插槽通过交换进行更新,并且希望每个人都这样的人用户每次更新网站时都会退出...继续阅读!

**通常,Azure会为您提供一些神奇的默认配置,使一个Web应用程序中的所有实例能够协同工作.部署插槽的问题在于它本质上就像两个完全独立的Web应用程序,所以所有的魔力都消失了.

您需要正确配置数据保护才能使其正常工作.这有点令人困惑,因为.NET Core Identity的文档没有明确提及依赖或要求您正确配置Data Protection,但确实如此.数据保护是它在引擎盖下用来加密应用程序登录cookie的方式.

ConfigureServices中需要以下代码:

services.AddDataProtection()
    .SetApplicationName("myweb")
    .ProtectKeysWithCertificate("thumbprint");

services.AddSingleton<IXmlRepository, CustomDataProtectionRepository>();
Run Code Online (Sandbox Code Playgroud)

每件作品说明:

  1. 通过设置应用程序名称,您可以跨使用此相同应用程序名称的多个应用程序共享受保护数据 可能并非所有情况都需要,但对我们的情况不会有害.
  2. 您需要使用在两个部署插槽中一致的自定义密钥加密方法.默认值特定于每个部署插槽,并且只能在该插槽中使用.如果查看静态密钥加密,Azure默认使用Windows DPAPI.不适合我们的目的.所以我选择使用证书,只需输入Azure门户中的指纹即可.注意:对于那些讨厌证书及其周围所有术语的人,.NET Core文档说您需要一个支持CAPI私钥的X.509证书,否则它将无法运行.blah blah blah blah使用你为你的网站获得的SSL证书,它应该工作得很好.
  3. 旁白:你必须做一些额外的谷歌搜索才能真正使用证书工作.在Azure的情况下,数据保护文档会让您感到茫然......仅使用上面的代码,部署到Azure时可能会出现500错误.首先,确保您已将证书上载到Web App的"自定义域和SSL"部分.其次,您需要添加WEBSITE_LOAD_CERTIFICATES应用程序设置并将证书的指纹添加到该设置以便使用它.请参阅azure网站中的证书.
  4. 设置证书以加密数据后...它会消除有关存储数据位置的任何默认配置 - Azure将其存储在默认情况下所有实例都可以访问的共享文件夹中(此处描述的默认值为数据保护默认值) .但是不同的部署插槽是分开的...所以内置的文件系统和注册表选项没有帮助.您必须编写如下所述的自定义实现:密钥存储提供程序.但是哦等等......自定义密钥存储库底部的部分是1-liner,没有关于如何连接它的链接或解释......你真的需要在这里阅读:密钥管理,转到IXmlRepository部分.不幸的是,除了你需要做的事情之外,IDataProtectionBuilder还有一些方便的扩展,因此我们将这个自定义IXmlRepository注册到服务提供者的行.尽管该接口具有惊人的通用名称,但它只会影响数据保护,并且不会混淆您的其他内容.
  5. 未显示的是CustomDataProtectionRepository的实现.我使用Azure blob存储.这是一个非常简单的界面,如果您需要帮助,请发表评论.

最后我们让OMG工作.享受丢失密码客户服务请求500%减少;)


Eri*_*onG 7

我试图拼凑一些文章,包括这里的一个完整的解决方案.这就是我想出的.原创博文:http://intellitect.com/staying-logged-across-azure-app-service-swap/

// Add Data Protection so that cookies don't get invalidated when swapping slots.
string storageUrl = Configuration.GetValue<string>("DataProtection:StorageUrl");
string sasToken = Configuration.GetValue<string>("DataProtection:SasToken");
string containerName = Configuration.GetValue<string>("DataProtection:ContainerName");
string applicationName = Configuration.GetValue<string>("DataProtection:ApplicationName");
string blobName = Configuration.GetValue<string>("DataProtection:BlobName");

// If we have values for all these things set up the data protection store in Azure.
if (storageUrl != null && sasToken != null && containerName != null && applicationName != null && blobName != null)
{
    // Create the new Storage URI
    Uri storageUri = new Uri($"{storageUrl}{sasToken}");

    //Create the blob client object.
    CloudBlobClient blobClient = new CloudBlobClient(storageUri);

    //Get a reference to a container to use for the sample code, and create it if it does not exist.
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExists();

    services.AddDataProtection()
        .SetApplicationName(applicationName)
        .PersistKeysToAzureBlobStorage(container, blobName);
}
Run Code Online (Sandbox Code Playgroud)

以下是appsettings.json示例,如果它们以这种方式存储的话.

{
  "DataProtection": {
    "ApplicationName": "AppName",
    "StorageUrl": "https://BlobName.blob.core.windows.net",
    "SasToken": "?sv=YYYY-MM-DD&ss=x&srt=xxx&sp=xxxxxx&se=YYYY-MM-DDTHH:MM:SSZ&st=YYYY-MM-DDTHH:MM:SSZ&sip=a.b.c.d-w.x.y.z&spr=https&sig=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "ContainerName": "data-protection-container-name", // All lower case with dashes and numbers.
    "BlobName": "data-protection-blob-name"
  }
}
Run Code Online (Sandbox Code Playgroud)