问题描述
我们有使用 IdentitySrver4 的 SSO 网站。我们最近测试了我们网站的安全性,我们发现了一个漏洞,如下所示,
应用程序的会话令牌保持有效(并且可以使用 验证对应用程序的请求)即使在注销后 函数已在相关会话中被调用。这表明 会话终止机制并不完全有效并且 增加了未经授权访问应用程序的可能性。 需要注意的是,令牌确实有一个有效的超时时间 一段时间后。注销功能终止了关联的 会话客户端(通过从用户的 浏览器),但会话在服务器端仍然有效。请求哪些 是在使用注销功能后进行的,但提供了 原始会话cookie,继续成功。
以下是代码片段,
IdentityServer
启动配置服务:-
services.AddIdentityServer(.......
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,opt=> {
opt.ExpireTimeSpan = TimeSpan.FromMinutes(Convert.ToInt32(Configuration["CookieTimeOut"]));
//This has time limit of 30 minutes
})
.AddOpenIdConnect("oidc",opts =>
{.......
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,cp);
IdentityServer 中的注销方法:-
[HttpGet]
public async Task<IActionResult> logout(string clientId,string returnUrl,string culture)
{
var clientsList = new List<Client>();
// delete authentication cookie
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var cookiesTobedeleted = Request.Cookies.Keys;
foreach (string cookie in cookiesTobedeleted)
{
Response.Cookies.Delete(cookie);
}
var logoutURL = _configuration["DefaultlogoutRedirectUrl"];
if (Uri.IsWellFormedUriString(returnUrl,UriKind.Absolute))
{
//Todo: validate that the return url belongs to the client who has initiated the logout request
//if the url validation fails then we should return to a pre-determined url that is mentioned in the config
logoutURL = returnUrl;
}
var vm = new LoggedOutviewmodel()
{
PostlogoutRedirectUri = logoutURL,SignOutUrls = _clients.Value
.Where(client => !string.IsNullOrWhiteSpace(client.FrontChannellogoutUri))
.Select(client => client.FrontChannellogoutUri),ClientName = clientId,AutomaticRedirectAfterSignOut = true
};
//If there is no return url then display a local logged out page
return View("LoggedOut",vm);
}
[HttpGet]
public IActionResult LoggedOut(string returnUrl)
{
var vm = new LoggedOutviewmodel()
{
PostlogoutRedirectUri = returnUrl,SignOutUrls = null,AutomaticRedirectAfterSignOut = true
};
return View(vm);
}
我们使用了FrontChannel注销,这里所有客户端的“FrontChannellogoutUri”都呈现在身份服务器注销页面的“IFrame”中.
客户端代码(MVC 应用程序):-
启动配置服务:-
services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,ck =>
{
ck.Cookie.Name = "ClientCookie";
ck.ExpireTimeSpan = TimeSpan.FromMinutes(Convert.ToInt32(Configuration["CookieTimeOut"]));
//This also has value of 30 minutes.
})
.AddOpenIdConnect("oidc",opts =>
{.......
客户端应用程序中的注销功能:-
public async Task<IActionResult> logout(string path)
{
var logoutUrl = //This is IdentityServer logout Method URL
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var prop = new Microsoft.AspNetCore.Authentication.AuthenticationProperties()
{
RedirectUri = logoutUrl
};
await HttpContext.SignOutAsync("oidc",prop);
return Redirect(logoutUrl);
}
客户端应用的 FrontChannel 方法:-
[AllowAnonymous]
public async Task<IActionResult> ForcedSignout()
{
var cookiesTobedeleted = Request.Cookies.Keys;
foreach (string cookie in cookiesTobedeleted)
{
Response.Cookies.Delete(cookie);
}
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return View();
}
注销流程如下:-
当从客户端 MVC 应用程序调用 logout 时,我们已经调用了两者 HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme) & HttpContext.SignOutAsync("oidc",prop)。
然后用户被重定向到 IdentityServer logout 方法,该方法再次调用 HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)。
当 Identity 的注销页面呈现时,我们会生成带有客户端“FrontChannellogoutUri”(在本例中为“ForcedSignout()”)的“IFrames”客户端应用程序)。
"ForcedSignout" 方法再次删除 cookie 并调用 HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)。
重现问题的步骤:-
我们在 postman 中捕获了客户端应用程序的编辑方法。
具有更改数据的邮递员请求已运行且有效。
在该用户退出客户端应用程序并再次运行邮递员请求后,即使我们已退出,该请求也成功运行。
然后我们等了 30 分钟(不活动)并尝试了邮递员请求,但这次它没有工作,因为会话已超时。
我们需要知道,当用户退出应用程序时,我们如何从服务器中删除/使会话无效?谢谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)