簡體   English   中英

跨請求保持聲明

[英]Persisting claims across requests

var user = UserManager.Find(...);

ClaimsIdentity identity = UserManager.CreateIdentity(
          user, DefaultAuthenticationTypes.ApplicationCookie );


var claim1 = new Claim(
          ClaimType = ClaimTypes.Country, ClaimValue = "Arctica", UserId = user.Id );
identity.AddClaim(claim1);

AuthenticationManager.SignIn(
          new AuthenticationProperties { IsPersistent = true }, identity );

var claim2 = new Claim(
          ClaimType = ClaimTypes.Country, ClaimValue = "Antartica", UserId = user.Id );
identity.AddClaim(claim2);

無論claim1claim2跨請求僅針對時間持續ClaimsIdentity用戶登錄 換句話說,當用戶通過調用SignOut()注銷時,這兩個聲明也會被刪除,因此下次該用戶登錄時,它不再是這兩個聲明的成員(我假設這兩個聲明不是不再存在)

claim2跨請求持久化的事實(即使在將claim2添加到 user 時已經創建了身份驗證 cookie )表明聲明不會通過身份驗證 cookie跨請求持久化,而是通過其他方式。

那么如何索賠請求間保持恆定?

編輯:

1)據我所知, IdentityUserClaim類型的聲明永遠不會保留在cookie 中

var user = UserManager.Find(...);

/* claim1 won't get persisted in a cookie */
var claim1 = new IdentityUserClaim
      { ClaimType = ClaimTypes.Country, ClaimValue = "Arctica", UserId = user.Id };
user.Claims.Add(claim1);


ClaimsIdentity identity = UserManager.CreateIdentity(
      user, DefaultAuthenticationTypes.ApplicationCookie );


AuthenticationManager.SignIn(
      new AuthenticationProperties { IsPersistent = true }, identity );

如果我的假設是正確的,這就是IdentityUserClaim實例沒有保留在cookie 中的原因,因為假設這些聲明應該存儲在DB 中,因此可以在后續請求中從DB檢索,而Claim類型的Claim通常不存儲在數據庫中,因此為什么需要將它們保存在cookie 中

2)

如果您想更深入地了解它是如何工作的,請查看 Katana 項目的源代碼

我認為Asp.net Identity 2不是Katana 項目的一部分(也就是說,我看到有人問微軟什么時候會發布Asp.Net Identity源代碼,即使Katana 源代碼已經可用)?!

謝謝你

好問題。 甚至讓我做了一個小實驗。

這一行:

AuthenticationManager.SignIn(
          new AuthenticationProperties { IsPersistent = true }, identity );

不設置cookie。 只為后面的回調設置Identity對象。

Cookie 僅在控制傳遞給中間件和一些名為Response.OnSendingHeaders OWIN 內部方法時設置。

因此,您的代碼只是在存儲在內存中供以后用戶使用的identity對象上添加claim2 理論上,您甚至可以在完成AuthenticationManager.SignIn后設置claim1 無論如何,它都會保留在 cookie 中。

如果您嘗試在控制器中添加這樣的 cliam:

    public ActionResult AddNonPersistedClaim()
    {
        var identity = (ClaimsIdentity)ClaimsPrincipal.Current.Identity;
        identity.AddClaim(new Claim("Hello", "World"));

        return RedirectToAction("SomeAction");
    }

此聲明不會在 cookie 中設置,您也不會在下一個請求中看到它。

如果您想更深入地了解它是如何工作的,請查看Katana Project的源代碼,查看Microsoft.Owin.SecurityMicrosoft.Owin.Security.Cookies項目。 Microsoft.Owin.Net45項目中的AuthenticationManager一起使用。

更新

回答您的編輯 1 - IdentityUserClaim確實持久保存到數據庫中,這是您可以將持久聲明分配給用戶的方式。 您通過UserManager在用戶上添加這些

await userManager.AddClaimAsync(userId, new Claim("ClaimType", "ClaimValue"));

這會在您的數據庫表中創建表示 IdentityUserClaim 的記錄。 當用戶下次登錄時,這些聲明會從數據庫中讀取並添加到身份中,並通過屬性.Claims或方法.HasClaim()ClaimsIdentity.Current上可用。

IdentityUserClaim不做任何其他事情 - 只是將Claim對象序列化到數據庫中的方法。 您通常不會直接訪問這些內容,除非您想“赤手空拳”並自己在UserManager之外寫入該表。

換句話說 - Identity 不會設置 cookie。 OWIN 創建 cookie。 看看這段代碼

    public async Task SignInAsync(IAuthenticationManager authenticationManager, ApplicationUser applicationUser, bool isPersistent)
    {
        authenticationManager.SignOut(
            DefaultAuthenticationTypes.ExternalCookie,
            DefaultAuthenticationTypes.ApplicationCookie,
            DefaultAuthenticationTypes.TwoFactorCookie,
            DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie,
            DefaultAuthenticationTypes.ExternalBearer);

        var identity = await this.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);
        identity.AddClaim(new Claim(ClaimTypes.Email, applicationUser.Email));

        authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
    }

這里的身份驗證管理器是 OWIN 的一部分。 IdentitySystem.Security.Claims一部分。 屬於 Identity 項目的所有內容是CreateIdentityAsync方法 - 基本上將用戶從數據庫轉換為具有所有持久角色和聲明的ClaimsIdentity

回答您的編輯 2 :您是對的,AspNet Identity 不是 Katana 項目的一部分,但 Identity 使用 OWIN(Katana 的一部分)進行 cookie 處理和授權。 身份項目主要處理用戶/角色/聲明的持久性和用戶管理,例如鎖定、用戶創建、發送帶有密碼重置的電子郵件、2FA 等。

令我驚訝的是ClaimsPrincipal以及ClaimsIdentityClaim是 .Net 框架的一部分,可在 OWIN 或 Identity 之外使用。 這些不僅在 Asp.Net 中使用,而且在 Windows 應用程序中使用。 好在 .Net 現在是開源的,您可以瀏覽所有這些 - 讓您更好地了解它們是如何協同工作的。 此外,如果您正在進行單元測試,了解內部結構是非常寶貴的,因此您可以在不使用模擬的情況下對所有功能進行存根。

如果您使用的是 AD 身份驗證和 asp 核心 2.1 或 2.2,當我們配置名為 ClaimActions 的服務時,有一個選項 OpenIdConnectOptions,在 ClaimActions 的幫助下,您可以編寫繼承 ClaimActions 的類 [CustomClaimsFactory] ​​還覆蓋其 Run 方法,該方法實際上將設置持久聲明,請在下面找到代碼:

/* startup.cs */  services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
        {

            options.ClaimActions.Add(new CustomClaimsFactory(
                                    "userName",
                                    "xxxxx@outlook.com"
                                )); 
         }

/*CustomClaimsFactory run method*/ public override void Run(JObject userData, ClaimsIdentity identity, string issuer)
    {
        identity.AddClaim(new Claim(_ClaimType, _ValueType, issuer));

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM