Я работаю над реализацией Identity Server, в которой используются библиотеки ASP.net Core 2.1 и IdentityServer4. В контексте протокола OAuth2 сервер идентификации реализован таким образом, чтобы возвращать код авторизации, как только клиент предоставит свои учетные данные для входа через веб-форму, предоставленную сервером. Код возвращается сервером в redirectURI, предоставленный клиентом ранее, когда он впервые сделал запрос на вход в систему (см. Приведенный ниже пример запроса на вход в систему).
1) ПРИМЕР СЦЕНАРИИ
Пример запроса на вход в систему:
http://exampleABC.com:5002/connect/authorize?client_id=XYZ&scope=myscope&response_type=code&redirect_uri=http://exampleXYZ.com
После того, как вышеупомянутый запрос будет выполнен в браузере, браузер откроет страницу входа клиента, на которой его просятввести свой пароль и пароль. Затем открывается страница SMS-токена, где клиент вводит SMS-сообщение, которое он получил на свой мобильный телефон. Затем клиент вводит SMS в браузер. Наконец, сервер перенаправляет браузер клиента на страницу в redirectURI, где браузер отображает код авторизации (то есть код) в адресной строке, как показано ниже:
https://exampleXYZ.com/?code=89c0cbe1a2cb27c7cd8025b6cc17f6c7cf9bc0d4583c5a63&scope=myscope
Здесь код «89c0cbe1a2cb27c7cd8025b6cc17f6c7cf9bc0d6383caтеперь можно использовать для запроса AccessToken с сервера идентификации.
2) ПОСТАНОВКА ПРОБЛЕМЫ
Если я повторно выдаю указанный выше пример запроса на вход в систему в том же клиентебраузер (например, Chrome), то браузер немедленно перенаправляет пользователя на redirectURI без повторного запроса учетных данных входа клиента. Это проблема, потому что мне приходится открывать новый экран входа в систему каждый раз, когда делается запрос на вход, учитывая, что могут быть клиенты, которые имеют разные учетные данные для входа. Поэтому я предоставил конечную точку выхода из системы в своей реализации IdentityServer, где я намерен очистить весь клиентский кеш, а затем выйти из системы, как показано в следующем блоке кода. Здесь я сначала удаляю файлы cookie, а затем создаю новые с тем же ключом и датой истечения срока их действия, чтобы удалить cookie из кеша браузера клиента в дополнение к кешу сервера. Моя цель заключается в том, чтобы постоянно отображать веб-форму входа в браузере без кэширования, если выдается запрос на выход из системы, чтобы форма входа отображалась каждый раз, когда приходит новый клиент.
public async Task<IActionResult> Logout()
{
var vm = await BuildLoggedOutView();
string url = Url.Action("Logout", new { logoutId = vm.LogoutId });
try
{
if (HttpContext.Request != null && HttpContext.Request.Cookies != null && HttpContext.Request.Cookies.Keys != null && HttpContext.Request.Cookies.Keys.Count > 0)
{
foreach (var key in _accessor.HttpContext.Request.Cookies.Keys)
{
//!!!! Cookie Removal !!!!!!
//Here I delete the cookie first and then recreate it
//with an expiry date having the day before.
_accessor.HttpContext.Response.Cookies.Delete(key);
_accessor.HttpContext.Response.Cookies.Append(
key,
string.Empty,
new CookieOptions()
{
Expires = DateTime.Now.AddDays(-1)
});
}
}
//!!!! Explicit sign out!!!!!!
await _accessor.HttpContext.SignOutAsync();
}
catch (NotSupportedException ex) // this is for the external providers that don't have signout
{
}
catch (InvalidOperationException ex) // this is for Windows/Negotiate
{
}
return View("Logged out", vm);
}
3) ВОПРОС:
Несмотря на то, что я удаляю куки и переопределяю их на стороне сервера, браузер клиента продолжает возвращаться на страницу перенаправления URI, где новый код авторизацииотображается без принуждения клиента к входу в систему (что нежелательно). Итак, мой вопрос здесь, что я пропускаю в приведенном выше блоке кода? Это не выглядит ни переопределением cookie со старой датой истечения срока действия, ни явным вызовом метода SignoutAsync не помогает полностью выйти из клиента. Есть ли какая-то более четкая стратегия, которую вы могли бы предложить, чтобы полностью очистить все как на стороне клиента, так и на стороне сервера после выхода из системы?