我已经在我的应用程序中实现了ASP.Net Cookie身份验证和OWIN OpenId身份验证的混合。我正在尝试修复一个安全漏洞,即使该会话注销后会话也不会失效。
中间件实现:-
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
.............
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
注销代码(基于用户类型):-
HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
我正在捕获 Fiddler 中的流量,然后单击从网页注销。当我尝试重新发出来自Fiddler的请求时,它已成功完成,并且在HttpModule中,application.User.Identity.IsAuthenticated
是 True
我有几个问题:-
答案 0 :(得分:1)
从应用程序注销时,您也必须从身份服务器注销。否则,您的应用程序将被重定向到身份服务器,得到重新认证并再次登录。检查通知下的以下代码段:
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = n =>
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
}
);
您会发现OWIN中间件设置的一些示例(虽然不是您问题的直接答案)here
答案 1 :(得分:0)
不确定该答案是否可以帮助其他人,但是link在此处提供了有关如何使用MVC应用程序设置openId的更多信息。
更改中间件配置
在startup.cs
文件中添加OpenId&Cookies身份验证中间件。将ResponseType
设置为Id_token
以使openId注销也可以工作。
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieHttpOnly = true,
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
CookieName = "AppCookies",
ExpireTimeSpan = TimeSpan.FromMinutes(30),
SlidingExpiration = true
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost:44319/identity",
ClientId = "mvc",
Scope = "openid profile roles",
RedirectUri = "https://localhost:44319/",
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies",
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
var id = n.AuthenticationTicket.Identity;
// we want to keep first name, last name, subject and roles
var givenName = id.FindFirst(Constants.ClaimTypes.GivenName);
var familyName = id.FindFirst(Constants.ClaimTypes.FamilyName);
var sub = id.FindFirst(Constants.ClaimTypes.Subject);
var roles = id.FindAll(Constants.ClaimTypes.Role);
// create new identity and set name and role claim type
var nid = new ClaimsIdentity(
id.AuthenticationType,
Constants.ClaimTypes.GivenName,
Constants.ClaimTypes.Role);
nid.AddClaim(givenName);
nid.AddClaim(familyName);
nid.AddClaim(sub);
nid.AddClaims(roles);
// add some other app specific claim
nid.AddClaim(new Claim("app_specific", "some data"));
n.AuthenticationTicket = new AuthenticationTicket(
nid,
n.AuthenticationTicket.Properties);
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
// if signing out, add the id_token_hint
if ((int)n.ProtocolMessage.RequestType == (int)OpenIdConnectRequestType.Logout)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst(Startup.IdToken);
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
添加注销
添加注销很容易,只需在Katana身份验证管理器中添加一个调用Signout方法的新操作即可:
public ActionResult Logout()
{
Session.Abandon();
// clear session cookie (not necessary for your current problem but i would recommend you do it anyway)
HttpCookie cookie2 = new HttpCookie("ASP.NET_SessionId", "");
cookie2.HttpOnly = true;
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);
// clear site cookie
var siteCookie = new HttpCookie("AppCookies", "");
siteCookie.HttpOnly = true;
siteCookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(siteCookie);
Request.GetOwinContext().Authentication.SignOut();
return Redirect("/");
}