使用AntiForgery标记模拟Windows用户

时间:2016-04-26 19:01:14

标签: c# .net security asp.net-web-api csrf

我有两个Web API;一个是公开的,一个是内部的。我希望公众与内部人员进行沟通。但是,我想为内部安全性提供两层安全性:

  • Windows身份验证(已完成)
  • AntiForgery令牌(这是我遇到的麻烦)

现在我正在公共API中生成AntiForgery令牌:

string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;

然后我在内部API的过滤器中删除它们:

var request = actionContext.Request;
if (!request.RequestUri.PathAndQuery.StartsWith("/api"))
{
    return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
}

string cookieToken = "";
string formToken = "";

IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
    string[] tokens = tokenHeaders.First().Split(':');
    if (tokens.Length == 2)
    {
        cookieToken = tokens[0].Trim();
        formToken = tokens[1].Trim();
    }
}

try
{
    AntiForgery.Validate(cookieToken, formToken);
}
catch (HttpAntiForgeryException ex)
{
    return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));
}

return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));

这是有效的。我得到的错误是:

  

提供的防伪令牌适用于用户“”,但当前用户是“WINDOWS8VM \ Michael”。

不知何故,我需要在生成令牌时冒充Windows用户,以便用户是相同的。

另一个问题是CredentialCache.DefaultNetworkCredentials为空。这几乎可以肯定是因为公共API没有打开Windows身份验证。但是,应用程序池有一个标识,它将是我要查找的标识。

1 个答案:

答案 0 :(得分:2)

由于您只想验证您的内部API是否由受信任的呼叫者(即公共API)调用 - 您不需要使用防伪令牌。相反,您可以使用AF令牌用于在公共API处对您自己的数据进行加密\签名的相同机制,然后解密和验证此数据是您在内部API所期望的。为此,您可以使用MachineKey.ProtectMachineKey.Unprotect方法。

如果您这样做,请注意,用于加密的密钥可能因应用程序而异。查看machineKey元素的说明,并注意IsolateApps设置的效果。如果您的计算机密钥配置了IsolateApps - 一个IIS应用程序将无法解密受其他人保护的数据(与AF令牌相同的故事),即使它们都位于同一台计算机上。

另请注意,如果在这方面没有隔离应用程序,则同一台计算机上的任何IIS应用程序都可以使用相同的密钥加密数据并调用内部API。但是,如果您只想保护您的api免受网络中其他计算机的影响 - 那应该足够了。

如果您不确定要加密哪些数据 - 合并来自请求本身的所有敏感数据,请将其哈希并保护该哈希。然后在内部api组合相同的数据,散列它,从调用者接收的Unprotect数据,并确保不受保护的数据与目标散列匹配。