OWIN OpenId身份验证-注销后的活动会话

时间:2019-11-15 17:50:14

标签: c# asp.net asp.net-mvc asp.net-identity owin

我已经在我的应用程序中实现了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

我有几个问题:-

  1. 这是Cookie重播攻击吗?
  2. 我在做错什么,如果不是,我将不得不通过某种黑客方式来解决它,例如将cookie存储在缓存中并进行比较?

2 个答案:

答案 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("/");
}
相关问题