用于Web服务安全性的ASP.NET会话密钥?

时间:2011-08-04 20:59:04

标签: asp.net ajax web-services

我有一个Web服务(ASP.NET 2.0),我使用jQuery的$.ajax()从javascript调用。我被告知会话密钥经常在出于安全目的的情况下用作nonce; Web服务将密钥作为其参数之一,并且仅在与当前会话密钥匹配时才返回数据。

我试图通过在每个Page_Load(即每个回发)上将隐藏字段的值设置为当前SessionID来实现此目的,然后在javascript中抓取它以作为参数传递。但它永远不会与Web服务的当前密钥(Context.Session.SessionID)相同。

这是否可以解决,或者我应该采取另一种方式吗?

编辑:根据请求在隐藏字段中设置会话的代码。

hfSession.Value = Context.Session.SessionID;

这是在.ascx控件的Page_Load中,不在任何条件下(即没有包含if (!Page.IsPostBack)

3 个答案:

答案 0 :(得分:2)

Asp.net实际上会为每个请求生成一个新的会话ID,直到您使用会话状态来存储某些值。这可能是价值观不同的原因。尝试并在会话中保存一些内容。也许

Session["SessionID"] = Context.Session.SessionID;
hfSession.Value = Context.Session.SessionID;

答案 1 :(得分:2)

我相信您正在尝试阻止跨站点脚本请求伪造(CSRF)。会话ID实际上是作为cookie发送的,攻击者可以设置它。您应该使用存储在Session变量中的随机生成的数字,而不是使用会话ID本身。

String GetCSRFToken()
{
    String token = (String)Session["CSRFToken"];
    if( token == null )
    {
        token = GenerateLongRandomString();
        Session["CSRFToken"] = token;
    }
    return token;
}

void AssertValidCSRFToken(String token)
{
    if( token != GetCSRFToken() )
    {
        throw new Exception("Invalid Request!")
    }
}

以下是另一个问题的链接,其中包含有关防止此类攻击的更多信息:

CSRF Validation Token: session id safe?

答案 2 :(得分:0)

每次页面加载时都会生成一个新的SessionID,直到实际分配会话。因此,如果您实际上没有为会话分配任何内容,则SessionID将在每次页面加载时更改。