Сохранение претензий по всем запросам

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);

Оба claim1 и claim2 сохраняются во всех запросах только за время ClaimsIdentity, пользователь зарегистрирован. Другими словами, когда пользователь выходит из системы, вызывая SignOut(), две заявки также удаляются, и в этом случае следующий пользователь регистрируется > , он больше не является членом этих двух претензий (я предполагаю, что две претензии больше не существуют)

Тот факт, что claim2 сохраняется в разных запросах (даже если cookie проверки подлинности уже был создан при добавлении claim2 к пользователю), предполагает, что утверждает t сохраняется в запросах через cookie аутентификации, но с помощью некоторых других средств.

Итак, как претензии сохраняются в запросах?

EDIT:

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 обычно не сохраняются в DB и почему они должны быть сохранены в cookie?

2)

Если вы хотите получить более глубокий вид, как все это работает, ознакомьтесь с исходный код проекта Katana

Я думал, что Asp.net Identity 2 не входит в проект Katana (а именно, я видел, как люди спрашивали, когда Microsoft выпустит исходный код для Identity Asp.Net, хотя исходный код Катаны уже доступен)?!

Благодарю вас

Ответ 1

Хороший вопрос. Даже заставлял меня немного экспериментировать.

Эта строка:

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

Не установлен файл cookie. Только устанавливает объект Identity для последующего обратного вызова.

Cookie устанавливается только тогда, когда элемент управления передается промежуточному программному средству и некоторому внутреннему методу OWIN под названием Response.OnSendingHeaders.

Таким образом, ваш код просто добавляет claim2 в объект Identity, который хранится в памяти для более позднего пользователя. В теории вы даже можете установить claim1 после выполнения AuthenticationManager.SignIn. И все равно он будет сохранен в файле cookie.

Если вы попытаетесь добавить такой климат в контроллер:

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

        return RedirectToAction("SomeAction");
    }

Эта претензия не будет установлена ​​в файле cookie, и вы не увидите ее в следующем запросе.

Если вы хотите получить более глубокий вид, как все это работает, посмотрите исходный код проекта Katana, посмотрите Microsoft.Owin.Security и Microsoft.Owin.Security.Cookies проекты. Наряду с AuthenticationManager в Microsoft.Owin.Net45 проекте.

Обновление

Чтобы ответить на ваше Редактирование 1 - IdentityUserClaim, действительно сохраняется в базе данных, и таким образом вы можете назначать пользователю постоянные претензии. Вы добавляете их пользователю через UserManager

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

Это создает записи в вашей таблице базы данных, которая представляет IdentityUserClaim. Когда в следующий раз пользователь войдет в систему, эти претензии считываются из базы данных и добавляются к идентификатору и доступны в ClaimsIdentity.Current через свойство .Claims или методом .HasClaim().

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. Identity является частью System.Security.Claims. Все, что принадлежит проекту Identity, - это метод CreateIdentityAsync, который в основном преобразует пользователя из базы данных в ClaimsIdentity со всеми сохраненными ролями и претензиями.

Чтобы ответить на свое Редактирование 2: вы правы, AspNet Identity не является частью проекта Katana, но Identity использует OWIN (часть Катаны) для обработки и авторизации файлов cookie. Проект идентичности в основном касается стойкости пользователя/ролей/претензий и управления пользователями, таких как блокировка, создание пользователей, отправка писем с сбросом пароля, 2FA и т.д.

Для меня было неожиданностью, что ClaimsPrincipal вместе с ClaimsIdentity и Claim являются частью .Net-структуры, доступной вне OWIN или Identity. Они используются не только в Asp.Net, но и в приложениях Windows. Хорошо, что .Net теперь имеет открытый исходный код, и вы можете просматривать все это - дает вам лучшее представление о том, как все это работает. Кроме того, если вы выполняете модульное тестирование, неоценимо знать внутренности, поэтому вы можете отключить все функции без использования mocks.