#c_sharp #net #aspnet #aspnet_mvc #aspnet_core
Необходимо, чтобы если у пользователя изменилось имя, email или пароль произошел выход со всех других устройств. По умолчанию авторизация сохраняется, даже если старая комбинация логина и пароля в бд отсутствует. Используется ASP.NET Core Identity Сделал костыль с сохранением токинов в базе данных и их проверкой при каждом запросе к не статическим ресурсам. При смене пароля или email все сохраненные токины удаляются из бд. Я уверен, что в ASP.NET Core Identity должен быть какой-то более простой способ для сброса авторизаций.
Ответы
Ответ 1
Сначала кратко опишу терминологию, чтобы не путаться в дальнейшем. В стандарте OAuth2 клиенты получают у сервера авторизации токен доступа (access token) и передают его владельцу ресурса в каждом запросе. Передавать токен можно в куках либо в заголовке HTTP, последний способ аутентификации называется Bearer. Сам токен является зашифрованной или по меньшей мере подписанной информацией о пользователе. Часто для подписания и шифровки используют стандарт JWT, тогда данные хранятся в виде json-объекта. У токена доступа есть время жизни. Дата/время завершения токена хранится непосредственно в нём, поэтому сервер может вычислить, жив токен или нет. Проблематика Такая схема не позволяет деаутентифицировать клиентов при наступлении определённых условий, потому что пока время жизни не истекло, владелец ресурса считает токен валидным. Решение Чтобы можно было сделать токены невалидными, владелец ресурса должен складывать их в кеш memcached или Redis. Тогда проверка токена будет проходить в два этапа: сначала мы должны убедиться, что токен есть в кеше, а потом проверить время его жизни. При несоблюдении любого из этих условий токен считается невалидным. Соответственно, при смене пароля надо удалить из кеша все токены доступа данного пользователя. Если помимо токенов доступа вы реализовали токены обновления (refresh tokens), их также надо хранить в кеше, и также надо удалять. Конкретика Этот механизм может быть реализован разными способами. Вот статья на MSDN, описывающая, как могут быть кешированы токены доступа в ASP.NET Core.Ответ 2
Обычно (в стандартных проектах ASP.NET MVC) в классе Startup вызывается метод ConfigureAuth(app), код которого выглядит примерно так: app.UseCookieAuthentication(new CookieAuthenticationOptions { Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator .OnValidateIdentity( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager), getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))) }, // other configurations }); Смысл кода в том, что при смене пароля (или даже при логине пользователя) генерируется некий SecurityStamp (например, рандомный гуид) и сохраняется в базе с привязкой к пользователю (как правило, в той же таблице, где и креденшиалы пользователя). Далее каждые 30 минут (validateInterval: TimeSpan.FromMinutes(30)) вызывается метод OnValidateIdentity, который проверяет, совпадает ли текущий SecurityStamp из куков пользователя с SecurityStamp из базы. Если не совпадает, то пользователь будет разлогинен. На примере: пользователь залогинился на устройстве A, через 5 минут он же залогинился на устройстве B и сменил пароль. При смене пароля сгенерировался новый SecirityStamp и сохранился в базу, на устройтсве B куки также обновились. Далее пользователь вернулся к устройству A и продолжил работать. Здесь он не менял пароль, поэтому SecurityStamp в куках останется старый и через 25 минут этот самый SecurityStamp не пройдет проверку. Пользователь будет разлогинен. То же самое (генерация SecurityStamp) можно делать при логине пользователя. Тогда пользователь не сможет продолжительно работать на нескольких устройствах. Интервал валидации SecurityStamp выбираете сами. Также не забудьте проверять его и при таких важных операциях, как смена пароля. В целом суть именно такая. В большинстве случаев достаточно этого стандартного подхода, иногда лишь придется написать свой метод для присвоения его свойству OnValidateIdentity экземпляра класса CookieAuthenticationProvider.
Комментариев нет:
Отправить комментарий