我有一个.NET Webforms站点,感谢需要发布到我的MVC应用程序,该应用程序当前位于Webform站点内作为单独的应用程序.
Webform应用程序需要将一些敏感值POST到MVC应用程序.
有没有办法在我的WebForms应用程序中生成AntiForgeryToken(),以便它可以与表单发布一起传递.
否则,任何人都知道任何其他自定义防伪代码,这将允许我做类似于MVC的AntiForgeryValidation.
我有一个用户无需登录即可发布的表单.但是,如果他的电子邮件被识别,则需要输入密码.密码表单通过Ajax验证,如果成功,则提交主表单.两种形式都需要有效的AntiForgeryToken.
问题是,密码检查作为副产品也签署了用户(来自客户的要求).这使令牌无效,并且无法发送主表单.
我已尝试以编程方式生成新令牌,但我无法让它工作.
关于如何解决这个问题的任何想法?
最终解决方案
我发现这个问题有助于输入反射.但是,这就是为什么在正常情况下你会避免黑客攻击内部类型的主要原因,这些类型是在版本之间的程序集之间进行的.正如贝蒂建议的那样,使用ILSpy来寻找东西.
这是最终的代码.
if (signIn)
FormsAuth.SignIn(user.Email, false);
var mvcAssembly = typeof(AntiForgery).Assembly;
var afdType = mvcAssembly.GetType("System.Web.Helpers.AntiForgeryData");
string fieldName = Convert.ToString(afdType.InvokeMember(
"GetAntiForgeryTokenName",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] { null }));
var serializerType = mvcAssembly.GetType("System.Web.Helpers.AntiForgeryDataSerializer");
var serializerCtor = serializerType.GetConstructor(new Type[0]);
object serializer = serializerCtor.Invoke(new object[0]);
string text = HttpContext.Request.Form[fieldName];
object antiForgeryData = serializerType.InvokeMember("Deserialize", BindingFlags.InvokeMethod, null, serializer, new object[] { text });
afdType.GetProperty("Username").SetValue(antiForgeryData,
signIn ? user.Email : string.Empty,
null);
string newToken = Convert.ToString(serializerType.InvokeMember(
"Serialize", …Run Code Online (Sandbox Code Playgroud) 我目前正在ASP.net中开发一个MVC应用程序.我正在使用AJAX.ActionLink在记录列表中提供删除链接,但这是非常不安全的.我把这个:
<AcceptVerbs(HttpVerbs.Post)>
Run Code Online (Sandbox Code Playgroud)
在执行删除的功能上,停止仅通过URL调用的功能.但是,仍存在的另一个安全漏洞是,如果我要创建一个包含此内容的基本html页面:
<form action="http://foo.com/user/delete/260" method="post">
<input type="submit" />
</form>
Run Code Online (Sandbox Code Playgroud)
它仍将是一个帖子,但来自不同的位置.
是否可以将AntiForgeryToken与AJAX ActionLink一起使用?如果是这样,这是一种安全的方法吗?我还没有意识到更多的安全漏洞吗?
ASP.NET MVC的AntiForgeryToken机制基于当前HttpContext.User.它在您调用时使用该值来构造令牌Html.AntiForgeryToken().基本上没关系(请参阅此处最后一段中的解释)但是当您通过Ajax调用登录时会出现问题.
在我的代码中,当用户登录时,凭据在Ajax中作为Json对象发送(AntiForgeryToken隐藏字段值也在Json内发送),服务器验证用户,应用FormsAuthentication.SetAuthCookie(),并返回Json结果包含一些用户特定的数据.这样,我可以在登录时避免整页刷新.
问题是现在每个后续的Ajax请求都会失败ValidateAntiForgeryTokenAttribute,因为它现在需要一个与防伪cookie不兼容的防伪标记.
如何将有效的防伪标记放入客户端的隐藏字段中,以便登录后的每个Json请求都会成功?
我试图手动获取一个新的隐藏字段标记(AntiForgery.GetHtml()在操作上使用,提取标记字符串本身,将其返回到Json中的客户端并在JavaScript中手动将其放置在防伪隐藏字段中)但它不起作用 - ValidateAntiForgeryTokenAttribute服务器上的后续Ajax调用失败.事实上,每次调用AntiForgery.GetHtml()(基本上是Html.AntiForgeryToken()帮助程序所做的)都会产生一个不同的令牌,这会使前一个令牌失效.
我也试着设置HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null);详见这里,但它不工作.
注意: 由于我的具体情况,此解决方案对我不起作用:Ajax 登录更改服务器上的用户身份,因此登录前生成的每个令牌都无效; 此解决方案也不适用,因为它解决了不同的问题.
我正在添加一个WebForm,我想从中解析到URL的路由.例如,在MVC中我会使用
return RedirectToAction("Action", "Controller");
Run Code Online (Sandbox Code Playgroud)
因此,如果您有一种方法可以从同一个应用程序中的WebForm获取相同的URL,那么我们将不胜感激.
我正在努力提高我公司网站的安全性,并希望创建一个令牌,以防止可以轻松维护的伪造尝试,这就是我想出的.
public class AntiForgeryToken
{
private readonly string _referenceToken;
public AntiForgeryToken()
{
_referenceToken = Guid.NewGuid().ToString();
}
public string ReferenceToken
{
get { return _referenceToken; }
}
}
Run Code Online (Sandbox Code Playgroud)
在我的MasterPage的基类中,我有一个HiddenField包含属性名为: ReferenceToken
protected virtual void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
InjectToken();
}
ValidateToken();
}
private void InjectToken()
{
var token = ObjectFactory.GetInstance<AntiForgeryToken>();
ReferenceToken = token.ReferenceToken;
}
private void ValidateToken()
{
var token = ObjectFactory.GetInstance<AntiForgeryToken>();
if (ReferenceToken.Equals(token.ReferenceToken, SC.InvariantCultureIgnoreCase))
return;
...do stuff for failed token
}
Run Code Online (Sandbox Code Playgroud)
我有StructureMap句柄将令牌存储在Session中,所以它是每个用户会话持久化的,所有这些都是AntiForgery方案的有效实现吗?
编辑:我的问题似乎有些混乱,是的我理解ASP.NET MVC有一个内置的AntiForgeryToken方案,这个问题明确是关于如何为WebForms重新创建这个以防止使用CSRF攻击(Cross …