XSSFilterAttribute.cs 3.1 KB
using Hh.Mes.Common.XSS;
using Microsoft.AspNetCore.Mvc.Filters;
using System;

namespace WebMvc.Aop
{
    /// <summary>
    /// XSS 过滤器 解决xss攻击防御 在需要进行XSS过滤的控制器或者action上加上对应的属性即可
    /// 新增、编辑控制器加上
    /// </summary>
    public class XSSFilterAttribute : ActionFilterAttribute
    {
        private readonly XSSHelper xss;

        public XSSFilterAttribute()
        {
            xss = new XSSHelper();
        }

        /// <summary>
        /// 在调用Action方法之前调用
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //获取参数集合
            var ps = context.ActionDescriptor.Parameters;
            //遍历参数集合
            foreach (var p in ps)
            {
                if (context.ActionArguments.ContainsKey(p.Name))
                {
                    //当参数是str
                    if (p.ParameterType == typeof(string))
                    {
                        if (context.ActionArguments[p.Name] != null)
                        {
                            context.ActionArguments[p.Name] = xss.XssFilter(context.ActionArguments[p.Name].ToString());
                        }
                    }
                    else if (p.ParameterType.IsClass)//当参数是一个实体
                    {
                        PostModelFieldFilter(p.ParameterType, context.ActionArguments[p.Name]);
                    }
                }

            }
        }


        /// <summary>
        /// 遍历实体的字符串属性
        /// </summary>
        /// <param name="type">数据类型</param>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        private void PostModelFieldFilter(Type type, object obj)
        {
            if (obj != null)
            {
                foreach (var item in type.GetProperties())
                {
                    if (item.PropertyType == typeof(string))  //当参数是string才进行XSS筛选
                    {
                        var propertyValue = item.GetValue(obj);
                        if (propertyValue != null)
                        {
                            var filterValue = xss.XssFilter(propertyValue.ToString());
                            item.SetValue(obj, filterValue);
                        }
                    }
                    else if (item.PropertyType.IsArray)//当参数是一个数组
                    {
                        Array arrayValue = obj as Array;
                        for (var i = 0; i < arrayValue.Length; i++)
                        {
                            PostModelFieldFilter(arrayValue.GetType(), arrayValue.GetValue(i));
                        }
                    }
                    else if (item.PropertyType.IsClass)  //当参数是一个实体就再次调用
                    {
                        PostModelFieldFilter(item.PropertyType, item.GetValue(obj));
                    }
                }
            }
        }
    }
}