限制Auth& ASP.NET MVC5中子域的会话Cookie

时间:2015-04-14 16:27:13

标签: asp.net-mvc authentication forms-authentication

我有一个多租户的应用程序,有几个客户端,以子域名区分:

client1.mydomain.com
client2.mydomain.com
etc

我正在使用表单身份验证和ASP.NET Auth&客户端上的会话cookie是为子域设置的,例如, client1.mydomain.com。这意味着如果我浏览到client2.mydomain.com,那么我没有登录,浏览器也没有发布client1 cookie。这是应该的。

然而,我们的安全测试已经提到的一点是,您可以从client1获取cookie值并使用这些值为client2创建cookie(我们已在firebug中完成此操作)。 ASP.NET接受这些cookie并认为您已在client2上获得授权。

如何配置ASP.NET以便不会发生这种情况?

web.config中的表单元素允许您设置域名,但我无法使用此作为我的多租户应用程序。我用

设置了cookie
 FormsAuthentication.SetAuthCookie(userName, false);

但我不明白为什么要将此限制为子域名。

1 个答案:

答案 0 :(得分:2)

您应该将域名添加到cookie的用户数据中。要做到这一点,你必须切换到另一个cookie api:

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
   ... other parameters ..., domain );

HttpCookie cookie = new HttpCookie( FormsAuthentication.FormsCookieName );

cookie.Value = FormsAuthentication.Encrypt( ticket );

Response.SetCookie( cookie );

然后,在您的全局应用程序类中有一个事件处理程序,在为请求建立标识后触发。在处理程序中,验证cookie中的域名是否等于当前请求的域:

public void Application_PostAuthorizeRequest( object sender, EventArgs e )
{
    HttpApplication app = sender as HttpApplication;
    HttpContext ctx = app.Context;

    if ( ctx.User.Identity.IsAuthenticated )
    {
        // current domain
        string currentDomain = ctx.Request.Url.... // get the domain

        // domain from cookie
        FormsIdentity id = (FormsIdentity)ctx.User.Identity;
        FormsAuthenticationTicket ticket = id.Ticket;

        string cookieDomain = ticket.UserData;

        if ( currentDomain != cookieDomain )
           throw new Exception( "break the execution of the current request" );

        ...

此检查将验证cookie是否针对当前域发布,或者是否有人尝试在不同域之间重用cookie。