XSSFilterAttribute.cs 2.91 KB
using HHECS.WebCommon.XSS;
using Microsoft.AspNetCore.Mvc.Filters;
using System;

namespace HHECS.Web.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))
                    {
                        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筛选
                    {
                        try
                        {
                            var propertyValue = item.GetValue(obj);
                            if (propertyValue != null)
                            {
                                var filterValue = xss.XssFilter(propertyValue.ToString());
                                item.SetValue(obj, filterValue);
                            }
                        }
                        catch
                        {

                        }
                    }
                    else if (item.PropertyType.IsClass)  //当参数是一个实体就再次调用
                    {
                        try
                        {
                            PostModelFieldFilter(item.PropertyType, item.GetValue(obj));
                        }
                        catch
                        {

                        }
                    }
                }
            }
        }
    }
}