Asp.net

使用 Owin 身份驗證的伺服器端聲明記憶體

  • October 4, 2013

我有一個曾經使用過的應用程序,FormsAuthentication不久前我將其切換為使用IdentityModelfromWindowsIdentityFramework以便我可以從基於聲明的身份驗證中受益,但是使用和實現起來相當難看。所以現在我在看OwinAuthentication

我在看OwinAuthenticationAsp.Net Identity框架。但是該Asp.Net Identity框架目前唯一的實現使用EntityModel並且我正在使用nHibernate. 所以現在我想嘗試繞過Asp.Net Identity並直接使用Owin Authentication。我終於能夠使用“如何忽略身份框架魔法並僅使用 OWIN auth 中間件來獲取我尋求的聲明? ”中的提示獲得有效登錄,但現在我持有聲明的 cookie 相當大。當我使用它時,IdentityModel我能夠使用伺服器端記憶體機制來記憶體伺服器上的聲明,並且 cookie 只是為記憶體資訊保存了一個簡單的令牌。中是否有類似的功能OwinAuthentication,還是我必須自己實現?

我希望我會在其中一艘船上…

  1. cookie 保持為 3KB,哦,它有點大。
  2. 啟用類似於我不知道IdentityModel的 SessionCaching的功能。Owin
  3. 編寫我自己的實現來記憶體導致 cookie 膨脹的資訊,看看我是否可以Owin在應用程序啟動時配置它。
  4. 我做這一切都錯了,有一種我沒有想到的方法,或者我在Owin.
public class OwinConfiguration
{
   public void Configuration(IAppBuilder app)
   {
       app.UseCookieAuthentication(new CookieAuthenticationOptions
       {
           AuthenticationType = "Application",
           AuthenticationMode = AuthenticationMode.Active,
           CookieHttpOnly = true,
           CookieName = "Application",
           ExpireTimeSpan = TimeSpan.FromMinutes(30),
           LoginPath = "/Login",
           LogoutPath = "/Logout",
           ReturnUrlParameter="ReturnUrl",
           SlidingExpiration = true,
           Provider = new CookieAuthenticationProvider()
           {
               OnValidateIdentity = async context =>
               {
                   //handle custom caching here??
               }
           }
           //CookieName = CookieAuthenticationDefaults.CookiePrefix + ExternalAuthentication.ExternalCookieName,
           //ExpireTimeSpan = TimeSpan.FromMinutes(5),
       });
   }
}

更新 我能夠使用紅葉提供的資訊獲得預期的效果,我想出了以下邏輯……

Provider = new CookieAuthenticationProvider()
{
   OnValidateIdentity = async context =>
   {
       var userId = context.Identity.GetUserId(); //Just a simple extension method to get the ID using identity.FindFirst(x => x.Type == ClaimTypes.NameIdentifier) and account for possible NULLs
       if (userId == null) return;
       var cacheKey = "MyApplication_Claim_Roles_" + userId.ToString();
       var cachedClaims = System.Web.HttpContext.Current.Cache[cacheKey] as IEnumerable<Claim>;
       if (cachedClaims == null)
       {
           var securityService = DependencyResolver.Current.GetService<ISecurityService>(); //My own service to get the user's roles from the database
           cachedClaims = securityService.GetRoles(context.Identity.Name).Select(role => new Claim(ClaimTypes.Role, role.RoleName));
           System.Web.HttpContext.Current.Cache[cacheKey] = cachedClaims;
       }
       context.Identity.AddClaims(cachedClaims);
   }
}

OWIN cookie 身份驗證中間件尚不支持會話記憶體等功能。#2 不是一個選項。

#3 是正確的方法。正如 Prabu 建議的那樣,您應該在程式碼中執行以下操作:

響應登錄:

  • 使用唯一鍵(GUID)將 context.Identity 保存在記憶體中
  • 創建一個嵌入了唯一鍵的新 ClaimsIdentity
  • 將 context.Identity 替換為新的身份

OnValidateIdentity:

  • 從 context.Identity 獲取唯一鍵聲明
  • 通過唯一鍵獲取記憶體的標識
  • 使用記憶體的身份呼叫 context.ReplaceIdentity

我打算建議你對 cookie 進行 gzip,但我發現 OWIN 已經在它的 TicketSerializer 中這樣做了。不是你的選擇。

引用自:https://stackoverflow.com/questions/19192428