2017-09-27 33 views
0

我已經失去了至少2個完整的工作日,並嘗試了很多方法來取得成功。如何使用.Net Core在Azure中跨應用程序共享Cookie身份驗證?

這種情況是這樣的:我有2個應用程序部署到Azure,假設他們是backoffice.website.comfrontoffice.website.com。兩者都是2個獨立的Azure網絡應用程序。登錄到backoffice.website.com的用戶應該能夠訪問frontoffice.website.com登錄的用戶列表,並選擇要模擬的用戶,將其重定向到frontoffice.website.com,並以所選用戶的身份登錄。

兩個網站使用Azure的相同的數據庫和共享相同的DbContext(這兩個項目住在Visual Studio中相同的解決方案,並均引用同一個數據訪問層,它指向數據庫,這兩個應用程序(包括應用程序使用。同樣的.Net核心身份的設置和表)

現在,根據文章here

你應該能夠成立Startup.ConfigureServices方法看起來是這樣的:

app.AddIdentity<ApplicationUser, IdentityRole>(options => 
{ 
    options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie"; 
    var protectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\")); 
    options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider; 
    options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2")); 
}); 

這可以在本地使用IIS Express進行,但在Azure中,Azure帳戶中的所有應用程序都可以共享的應用程序之外不存在目錄訪問權限(我知道,並且是的,我知道他們有其他選項可用於文件共享,但我們現在會談到這一點)。

既然我們不能用一個目錄,用於存放在Azure中的目錄2個應用程序之間所需的共享密鑰的文件,

我們參考本文here,從而導致在創建的Blob容器Azure存儲密鑰,以便我希望在Azure中創建和託管的任何和所有應用都可以從商店訪問密鑰。

使用來自第一引用的文章和第2位,現在該代碼看起來是這樣的(設置所有的Startup.ConfigureServices方法可讀性):

var storageAccount = new CloudStorageAccount(
      new StorageCredentials("blob", "SASKeyHere"), 
      new StorageUri(new Uri("https://endpoint.blob.core.windows.net/")), 
      null, 
      null, 
      null 
     ); 

var client = storageAccount.CreateCloudBlobClient(); 
var container = client.GetContainerReference("container"); 
container.CreateIfNotExistsAsync().GetAwaiter().GetResult(); 

var serviceCollection = new ServiceCollection(); 
serviceCollection.AddDataProtection().PersistKeysToAzureBlobStorage(container, "fileName.xml"); 
var service2 = serviceCollection.BuildServiceProvider(); 

var dataProtector = service2.GetRequiredService<IDataProtectionProvider>(); 

// Add framework services. 
services.AddDbContext<DbContext>(options => options 
      .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

services.AddIdentity<ApplicationUser, IdentityRole>(options => 
      { 
       options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie"; 
       var protectionProvider = dataProtector; 
       options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider; 

       options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2")); 
      }) 
      .AddEntityFrameworkStores<DbContext>() 
      .AddDefaultTokenProviders(); 

這也是本地工作!此代碼位於兩個應用程序的ConfigureServices方法中,並允許跨這兩個應用程序讀取cookie,但一旦部署,就不起作用!

有沒有人能夠實現這個或類似的東西?

回答

0

這很可能是因爲cookie默認不跨子域。

你可以嘗試添加您的根域作爲Cookie域(這可能需要一個配置設定,讓本地工作呢!)

app.AddIdentity<ApplicationUser, IdentityRole>(options => 
{ 
    options.Cookies.ApplicationCookie.CookieDomain = ".mydomain.com"; 
} 
+0

難以置信!這似乎工作,非常感謝你!值得注意的是,出於某種原因,要模仿用戶的個人在登錄「記住我」時必須勾選勾選框,否則該模擬對該用戶不起作用。如果你能幫助我理解這背後的理由,那將會很好。它絕對可以只是我的代碼。 –

+0

可能最適合另一個問題。我建議的是,對於像你這樣的大問題,你可以嘗試在Github上創建一個簡單的POC,並在你的問題中分享鏈接。我只是在這個黑暗中刺了一刀,但對於模仿等等,它太大了,以至於無法猜測答案。 – MindingData

相關問題