【发布时间】:2016-04-26 19:01:13
【问题描述】:
我有两个 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 身份验证。但是,应用程序池有一个身份,这就是我要寻找的身份。
【问题讨论】:
-
如果你从另一个 api(公共)调用一个 api(内部),你为什么需要防伪令牌?
-
主要原因是确保其他内部应用程序无法利用此 API。数据异常敏感。如果我们只有 Windows 身份验证,那么我们觉得这还不够。这可能是我们必须解决的问题,但我们想添加某种类型的承载,我们想从尝试使用
AntiForgery令牌开始。当然还有其他方式,但就架构而言,它们的参与度更高。 -
你确定你真的明白你想在这里用 AF 令牌实现什么吗?这些令牌是为了防止 CSRF 攻击,而不是保护服务之间的请求。您想要使用它们的方式完全违背了它们的设计目的。您基本上将一堆加密数据从服务 A 传递到服务 B 并检查 B 是否知道解密密钥,但是不需要 AF 来做这些事情。
-
@Evk,我想简单地在服务之间传递一个密钥是正确的。我只是希望我能够利用 AF 代币来做到这一点,而不是构建那个架构。
-
好吧,您只能使用 AF 的加密部分,跳过其他所有内容(无论如何这与您的任务无关)。只需使用 MachineKey.Protect (msdn.microsoft.com/en-us/library/…) 使用与 AF 令牌相同的密钥加密任意数据,然后使用 MachineKey.Unprotect 进行解密。请注意,AF 令牌还包含您案例的“任意数据”。如果不确定要加密什么 - 加密请求数据本身,那么您也可以确定请求不是在中间伪造的。
标签: c# .net security asp.net-web-api csrf