注销Webforms身份验证不会删除服务器上的身份验证



我使用开箱即用的webforms身份验证。

请求"注销"后使用:

 FormsAuthentication.SignOut();

用户通过从客户端浏览器中删除cookie".aspxauth"来注销。

这是意料之中的事。

我们的网站进行了安全审计,审计员声称当用户注销时,身份验证令牌不会从服务器中删除。

我可以使用Fiddler重现这种行为。

  • 我登录到该网站并复制cookie".aspxauth"
  • 我注销:cookie在客户端上被删除,我再也无法访问安全页面
  • 我使用fiddler composer使用以前复制的cookie"aspxauth"向网站发送了一个请求。我可以用那个cookie访问安全页面

预期的结果是,如果我注销,我就无法通过提供旧的aspxauth cookie来访问安全页面。

有没有办法使服务器上的旧aspxauth cookie无效?

我通过在Auth cookie中存储salt值来解决这个问题,该值也会在用户登录时保存在数据库中。

在每个请求中,都会检查authcookie中的salt是否与数据库中的salte相同。否则,用户将注销。

如果用户注销,salt将从数据库中删除,旧的auth-cookie将无法再使用。

登录时存储盐

    // Generate a new 6 -character password with 2 non-alphanumeric character.
string formsAuthSalt = Membership.GeneratePassword(6, 2);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
    orderAuthToken.EMail,
    DateTime.Now,
    DateTime.Now.AddMinutes(20),
    ApplicationConfiguration.CreatePersistentCookie,
    formsAuthSalt,
    FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

UserInfo user = UserService.GetUser(orderAuthToken.EMail);
user.FormsAuthenticationCookieSalt = formsAuthSalt;
UserService.UpdateUser(user);

检查过滤器中的盐,用对所有操作进行去核

public class CheckFormsAuthenticationCookieSalt : ActionFilterAttribute
{
    private readonly IUserService UserService = ObjectFactory.GetInstance<IUserService>();
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if ( filterContext.HttpContext.Request.IsAuthenticated)
        {
            // Encrypt the ticket.
            if (HttpContext.Current.Request.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
            {
             var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (cookie != null)
                {
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
                    if (ticket != null)
                    {
                        string salt = ticket.UserData;
                        int userID = UserService.GetUniqueID(filterContext.HttpContext.User.Identity.Name, true, false, "MyAppName");
                        UserInfo user = UserService.GetUser(userID);
                        //for deployment: dont logg out existing users with no cookie
                        if (user.FormsAuthenticationCookieSalt != salt && user.FormsAuthenticationCookieSalt != "seed")
                        {
                            FormsAuthentication.SignOut();
                            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "action", "Index" }, { "controller", "Home" } );
                        }
                    }
                }
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

相关内容

最新更新