我的网站上有一个用户可以选择的子域列表。我想为他们仅选择的子域创建一个auth cookie,并非所有子域 假设我的网站是mysite.com,那么用户可以看到
当他们选择了他们的子域名时,我在控制器操作中执行以下操作
var faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
faCookie.HttpOnly = true
faCookie.Domain = (subdomain + ".mysite.com")
faCookie.Secure = FormsAuthentication.RequireSSL
response.Cookies.Add(faCookie)
return this.Redirect("http://" + subdomain + ".mysite.com")
其中encTicket只是一些加密的用户信息
在小提琴手中,我将此视为回应
HTTP/1.1 302 Found
Cache-Control: private, s-maxage=0
Content-Type: text/html; charset=utf-8
Location: http://domainOne.mysite.com
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=9ECF5B2533<snip>; domain=domainOne.mysite.net; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Fri, 19 Jul 2013 04:19:02 GMT
Content-Length: 142
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="http://domainOne.mysite.net">here</a>.</h2>
</body></html>
好的,所以这对我来说都很好看。 repsonse告诉浏览器为子域添加cookie。
然而,基于重定向的后续GET在其请求中根本没有cookie。
我缺少一些诡计吗?为了清楚起见,我不想为根(.mydomain.com)创建cookie,因为这会在所有子域中进行身份验证。
感谢您的帮助
答案 0 :(得分:0)
我有好消息和坏消息。
坏消息是 - 你不能这样做。有关说明,请参阅here。基本上,您的服务器正在为其不包含的域设置cookie,因此cookie被拒绝。
好消息是 - 无论如何你都不想这样做。您的设计违反了OWASP 2013 A4(不安全和未经验证的直接对象引用)。在这种情况下,您将用户的访问权限存储为cookie的域,黑客可以轻松修改该域。
查找指定子域访问的其他方法。有各种方法可以做到这一点。
这是一种非常接近您的计划的方式:
将子域存储在cookie值本身中。创建一个安全文档容器,列出授予用户访问权限的子域。例如,您可以将子域存储为逗号分隔的字符串,后跟HMAC,以防止恶意用户篡改列表。
var contents = "subdomain1.domain.com,subdomain2.domain.com";
var bytes = System.Text.Encoding.UTF8.GetBytes(contents);
var hash = System.Web.Security.MachineKey.Encode(bytes,
Web.Security.MachineKeyProtection.Validation);
var cookie = new HttpCookie("MYCOOKIE", contents + "|" + hash);
cookie.domain = "domain.com";
当子域站点收到请求时,它必须查找cookie,检查哈希值以验证cookie,然后检查有效负载以查看是否应该授予访问权限。
var cookie = Request.Cookies["MYCOOKIE'];
var chunks = cookie.Value.Split("|");
var list = chunks[0];
var hash = chunks[1];
var bytes = System.Text.Encoding.UTF8.GetBytes(contents);
var checkHash = System.Web.Security.MachineKey.Encode(bytes,
Web.Security.MachineKeyProtection.Validation);
if (checkHash != hash) throw new System.SecurityException("Someone tampered with the cookie!");
var subdomains = list.split(",");
if (!subdomains.Contains(MY_SUBDOMAIN)) throw new System.SecurityException("Someone is using their cookie to access the wrong domain!");
另一种方法是将授权子域列表存储在服务器端的数据库中,将列表与令牌关联,然后在cookie中传递令牌。这种方法会更加安全,因为访问列表永远不会通过网络传递。
第三种方法是建立一个真正的基于SAML的SSO基础设施,但这是一种参与。