hyp*_*erN 3 javascript asp.net asp.net-mvc angularjs asp.net-identity
使用ASP.net MVC 5来自帐户控制器和帐户视图.在Register视图中有行
@Html.AntiForgeryToken()
Run Code Online (Sandbox Code Playgroud)
以上寄存器控制器有属性:
[ValidateAntiForgeryToken]
Run Code Online (Sandbox Code Playgroud)
我决定使用JSON从javascript发送数据到服务器(我使用的是Angular和$ http.post方法).
我的问题是如何使用javascript发送此AntiForgeryToken并在控制器中验证它?
我应该包括更多安全措施吗?
AngularJS内置支持XSRF(AKA防伪)
XSRF是一种未经授权的站点可以获取用户私有数据的技术.Angular提供了一种对抗XSRF的机制.执行XHR请求时,$ http服务从cookie(默认情况下为XSRF-TOKEN)读取令牌并将其设置为HTTP头(X-XSRF-TOKEN).由于只有在您的域上运行的JavaScript才能读取Cookie,因此您的服务器可以确保XHR来自您域上运行的JavaScript.不会为跨域请求设置标头.
如果要利用此功能,则必须创建将创建和验证XSRF-TOKEN cookie的操作过滤器.这是我使用的简化版本.
AntiForgeryTokenCookieAttribute - 使用此属性添加XSRF-TOKEN cookie
/// <summary>
/// Create a XSRF token in the XSRF-TOKEN cookie which is automatically read by AngularJS
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class AntiForgeryTokenCookieAttribute : ActionFilterAttribute
{
private readonly IAntiForgeryVerificationTokenStore _verificationTokenStore = new AntiForgeryVerificationTokenCookieStore(); //TODO: make configurable
private const string CookieName = "XSRF-TOKEN"; //TODO: make configurable
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var oldVerificationToken = _verificationTokenStore.GetVerificationToken(filterContext.HttpContext.Request);
string newVerificationToken;
string newToken;
AntiForgery.GetTokens(oldVerificationToken, out newVerificationToken, out newToken);
if (newVerificationToken != null)
{
_verificationTokenStore.StoreVerificationToken(filterContext.HttpContext.Response, newVerificationToken);
}
filterContext.HttpContext.Response.Cookies.Add(new HttpCookie(CookieName, newToken));
}
}
Run Code Online (Sandbox Code Playgroud)
ValidateAntiForgeryTokenHeaderAttribute
/// <summary>
/// Validate the XSRF token stored in the X-XSRF-TOKEN header.
/// If the header doesn't exist, look for the XSRF token in the from post.
///
/// Compatible with ValidateAntiForgeryTokenAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenHeaderAttribute : FilterAttribute, IAuthorizationFilter
{
private readonly IAntiForgeryVerificationTokenStore _verificationTokenStore = new AntiForgeryVerificationTokenCookieStore(); //TODO: make configurable
private const string TokenHeaderName = "X-XSRF-TOKEN"; //TODO: make configurable
public void OnAuthorization(AuthorizationContext filterContext)
{
var token = filterContext.HttpContext.Request.Headers[TokenHeaderName];
if (token != null)
{
//validate the token stored in header
var verificationToken = _verificationTokenStore.GetVerificationToken(filterContext.HttpContext.Request);
if (verificationToken == null) { throw new HttpAntiForgeryException("Required verification token not found"); }
AntiForgery.Validate(verificationToken, token);
}
else
{
//validate the token stored in form. Same as ValidateAntiForgeryTokenAttribute
AntiForgery.Validate();
}
}
}
Run Code Online (Sandbox Code Playgroud)
IAntiForgeryVerificationTokenStore
public interface IAntiForgeryVerificationTokenStore
{
string GetVerificationToken(HttpRequestBase request);
void StoreVerificationToken(HttpResponseBase response, string token);
}
Run Code Online (Sandbox Code Playgroud)
AntiForgeryVerificationTokenCookieStore
public class AntiForgeryVerificationTokenCookieStore : IAntiForgeryVerificationTokenStore
{
public string GetVerificationToken(HttpRequestBase request)
{
if (request == null) { throw new ArgumentNullException("request"); }
var token = request.Cookies[AntiForgeryConfig.CookieName];
return token != null ? token.Value : null;
}
public void StoreVerificationToken(HttpResponseBase response, string token)
{
if (response == null) { throw new ArgumentNullException("response"); }
if (token == null) { throw new ArgumentNullException("token"); }
response.Cookies.Add(new HttpCookie(AntiForgeryConfig.CookieName, token) { HttpOnly = true, Secure = AntiForgeryConfig.RequireSsl });
}
}
Run Code Online (Sandbox Code Playgroud)