.net mvc全局拦截CSRF跨站点攻击

4 篇文章 0 订阅

开发中如果不想每个页面都验证CSRF跨站点攻击,可以按以下方法添加拦截器

1. 添加api请求拦截器   

/// <summary>
    /// Api拦截
    /// </summary>
    public class ApiPermissionFilter : System.Web.Http.Filters.ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
        {
            try
            {
                var request = filterContext.Request;
                if (request.Method != HttpMethod.Get && request.Method != HttpMethod.Post)
                    return;
                var antiForgeryCookie = HttpContext.Current.Request.Cookies[AntiForgeryConfig.CookieName];
                var cookieValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null;
                var heads = request.Headers.GetValues("__RequestVerificationToken");
                if (heads.Count() < 1)
                {
                    filterContext.Response = new System.Net.Http.HttpResponseMessage(HttpStatusCode.Forbidden);
                    return;
                }
                string token = heads.FirstOrDefault();

                从cookies 和 Headers 中 验证防伪标记
                try
                {
                    AntiForgery.Validate(cookieValue, token);
                }
                catch (Exception ex)
                {
                    filterContext.Response = new System.Net.Http.HttpResponseMessage(HttpStatusCode.Forbidden);
                    return;
                }

                base.OnActionExecuting(filterContext);
            }
            catch
            {
                filterContext.Response = new System.Net.Http.HttpResponseMessage(HttpStatusCode.NotFound);
            }
        }
    }

 

 

2. WebApiConfig.cs添加

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Filters.Add(new ApiPermissionFilter());
        }
    }

3. cshtml页面添加,最好在母版页添加

                                @Html.AntiForgeryToken()
                                @Html.ValidationSummary(true)

4. 新建   com.antiForgery.js文件,并在页面引入,该脚本目前我已经实现了post和get请求自动加入参数__RequestVerificationToken,脚本下载地址:https://download.csdn.net/download/a506602491/12372800

 

5. 添加普通Action请求的验证(非api)LoginActionFilter.cs

 /// <summary>
    /// 验证防伪标记,防止非法访问
    /// </summary>
    public class LoginActionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            if (request.HttpMethod != WebRequestMethods.Http.Post && request.HttpMethod != WebRequestMethods.Http.Get)
                return;
            if (filterContext.HttpContext.Request.HttpMethod == WebRequestMethods.Http.Post || request.IsAjaxRequest())
            {
                var antiForgeryCookie = request.Cookies[System.Web.Helpers.AntiForgeryConfig.CookieName];
                var cookieValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null;
                string token = !string.IsNullOrWhiteSpace(request.Headers["__RequestVerificationToken"]) ? request.Headers["__RequestVerificationToken"] : request.Form["__RequestVerificationToken"];
                if (string.IsNullOrWhiteSpace(token) && (request.UrlReferrer != null))
                {
                    filterContext.Result = new ContentResult() { Content = "非法访问" };
                    filterContext.HttpContext.Response.StatusCode = 404;
                }
                从cookies 和 Headers 中 验证防伪标记
                try
                {
                    //string openValidateUrl = "www.baidu.com";
                    如果允许访问,则在启用下面判断
                    //if (request.UrlReferrer != null || openValidateUrl.Contains(request.CurrentExecutionFilePath.ToLower()))
                    //{
                    //    base.OnActionExecuting(filterContext);
                    //    return;
                    //}
                    //else
                    //{
                    //    AntiForgery.Validate(cookieValue, token);
                    //}
                    AntiForgery.Validate(cookieValue, token);
                }
                catch (Exception ex)
                {
                    filterContext.Result = new ContentResult() { Content = "非法访问" };
                    filterContext.HttpContext.Response.StatusCode = 404;
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }

6. FilterConfig.cs添加,如果没有就自己新建一个

public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new LoginActionFilter());
        }
    }

 

7.global文件的Application_Start加入

  protected void Application_Start()
        {
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

        }

完成上面工作后每次POST和GET请求页面都会添加__RequestVerificationToken的参数,并且会触发LoginActionFilter和ApiPermissionFilter两个拦截器

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值