Identity Server 4 — GetProfileDataAsync, вызываемый несколько раз, приводит к множеству записей в базе данных

У меня довольно другой вариант использования, когда мне нужно отслеживать историю входа в систему, и для их отслеживания я создаю новый GUID в IProfileService и добавляю его в претензии, а также в БД, чтобы продолжить переднюю задачу.

Проблема в том, что я получаю несколько записей в БД для одного щелчка входа, который начинает отображать две записи для каждого входа.

GUID используется для отслеживания текущего сеанса входа в систему (у нас есть параллельный сценарий входа).

Вопрос 1 - Правильно ли создавать GUID внутри этой функции, если нет, то где это сделать?

Вопрос 2. Предоставляет ли IDSvr уникальный идентификатор для каждого входа в систему, чтобы я мог просто использовать его в претензиях.

Вопрос 3. Как остановить/свести к минимуму другие вызовы БД, сделанные из-за нескольких вызовов.

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
       {
           var user = DataBaseUserRetrive();
           var claims = new List<Claim>
           {
                        //All Claims from user
           };
               string deviceIdGuid = Guid.NewGuid().ToString();
               Claim deviceId = new Claim("device_id", deviceIdGuid ,ClaimValueTypes.String);
               claims.Add(deviceId);
               await databaseCall(user,deviceIdGuid );
          context.IssuedClaims = claims;
       }

PS: - я новичок в Identity Server


person Babloo Singh    schedule 26.11.2019    source источник
comment
Прочтите мой ответ здесь для объяснения, почему это так. звонили несколько раз.   -  person Ruard van Elburg    schedule 26.11.2019
comment
Что касается ведения журнала, почему вы не регистрируете успешный вход в метод Account.Login? Как вы уже заметили, ProfileService не является надежным местом для ведения журнала, поскольку его могут вызывать и другие процессы.   -  person Ruard van Elburg    schedule 26.11.2019
comment
@Ruard Мне также нужно добавить этот вновь созданный GUID в утверждения, и я не смог найти место, чтобы добавить его в утверждения, кроме этого метода. Многократный вызов, я понял другой контекст, но мое приложение запрашивает только токен и не вызывается конечной информацией пользователя. Опять же, мой вопрос остается прежним, могу ли я добавить это пользовательское утверждение куда угодно, кроме этого метода, если да, то где и как я могу его интегрировать.   -  person Babloo Singh    schedule 26.11.2019
comment
Вы можете добавить утверждение в ProfileService при регистрации успешного входа в систему в Account.Login.   -  person Ruard van Elburg    schedule 26.11.2019
comment
ProfileService вызывается после моего успешного входа в систему, если я не ошибаюсь? И я предполагаю, что он вызывается внутри, потому что мы регистрируем его в службах. Как я могу создать GUID в контроллере учетной записи, а задница находится в службе профилей, getprofiledata получает только контекст. PS. В любом случае я не могу получить этот GUID после сохранения, как будто это своего рода уникальный первичный ключ.   -  person Babloo Singh    schedule 26.11.2019
comment
Identityserver4 выделяет уникальный идентификатор сеанса каждый раз, когда пользователь входит в систему. Он сохраняется как свойство внутри файла cookie аутентификации с именем session_id. Имеет смысл использовать это для отслеживания сессий. Если вы просто хотите отслеживать каждый раз, когда выделяется идентификатор сеанса, вы можете предоставить свою собственную реализацию IUserSession, которая выполняет необходимое ведение журнала.   -  person mackie    schedule 28.11.2019
comment
@mackie Спасибо, я попробую, можете ли вы привести пример реализации IUserSession? Я не мог найти пример, относящийся к этому в официальных документах. На данный момент я реализовал IClaimsTransformer, чтобы добавить GUID в PrincipalClaim и ведение журнала, а в ProfileService я просто обращаюсь к нему, чтобы добавить его в претензию.   -  person Babloo Singh    schedule 29.11.2019


Ответы (1)


Чтобы расширить мой комментарий к OP, я думаю, что пользовательская реализация IUserSession (или наследование и переопределение виртуальных методов в DefaultUserSession), вероятно, является правильным местом для перехвата событий, связанных с сеансом, и добавления пользовательского поведения и логики.

Реализация по умолчанию здесь: https://github.com/IdentityServer/IdentityServer4/blob/3.0.2/src/IdentityServer4/src/Services/Default/DefaultUserSession.cs

Взгляните на метод EnsureSessionIdCookieAsync() — вероятно, это хорошее место для подключения любой пользовательской логики.

Этот идентификатор сеанса — это то, что отправляется клиентам и является частью протокола, в частности спецификации выхода из внешнего канала и мониторинга сеанса.

person mackie    schedule 02.12.2019