재우니의 블로그

 

asp.net mvc 의 filter 함수를 통해 사용할 수 있다.

 

사용법은 간단하다. 원하는 컨트롤러에 [Audit] 라고 명시하면 된다. 레벌은 1~3까지 종류를 제공한다.

        [Audit]
        public ActionResult LevelZero()
        {
            return Content("Level 0 Audit Executed");
        }

        [HttpPost]
        [Audit(AuditingLevel = 2)]
        public ActionResult LevelThree(AdvancedViewModel model)
        {
            return Content("Level 2 (Advanced) Audit Executed");
        }

 

아래는 필터를 명시한 부분이다.

    public class Audit
    {
        //A new SessionId that will be used to link an entire users "Session" of Audit Logs
        //together to help identifer patterns involving erratic behavior
        public string SessionID { get; set; }
        public Guid AuditID { get; set; }
        public string IPAddress { get; set; }
        public string UserName { get; set; }
        public string URLAccessed { get; set; }
        public DateTime TimeAccessed { get; set; }
        //A new Data property that is going to store JSON string objects that will later be able to
        //be deserialized into objects if necessary to view details about a Request
        public string Data { get; set; }

        public Audit()
        {
        }
    }

    public class AuditingContext : DbContext
    {
        public DbSet<Audit> AuditRecords { get; set; }
    }

    public class AuditAttribute : ActionFilterAttribute
    {
        //Our value to handle our AuditingLevel
        public int AuditingLevel { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //Stores the Request in an Accessible object
            var request = filterContext.HttpContext.Request;

            //Generate the appropriate key based on the user's Authentication Cookie
            //This is overkill as you should be able to use the Authorization Key from
            //Forms Authentication to handle this. 
            var sessionIdentifier = string.Join("", MD5.Create()
                 .ComputeHash(Encoding.ASCII.GetBytes(request.Cookies[FormsAuthentication.FormsCookieName].Value))
                 .Select(s => s.ToString("x2")));

            //Generate an audit
            Audit audit = new Audit()
            {
                SessionID = sessionIdentifier,
                AuditID = Guid.NewGuid(),
                IPAddress = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress,
                URLAccessed = request.RawUrl,
                TimeAccessed = DateTime.UtcNow,
                UserName = (request.IsAuthenticated) ? filterContext.HttpContext.User.Identity.Name : "Anonymous",
                Data = SerializeRequest(request)
            };

            //Stores the Audit in the Database
            AuditingContext context = new AuditingContext();
            context.AuditRecords.Add(audit);
            context.SaveChanges();

            base.OnActionExecuting(filterContext);
        }

        //This will serialize the Request object based on the level that you determine
        private string SerializeRequest(HttpRequestBase request)
        {
            switch (AuditingLevel)
            {
                //No Request Data will be serialized
                case 0:
                default:
                    return "";
                //Basic Request Serialization - just stores Data
                case 1:
                    return Json.Encode(new { request.Cookies, request.Headers, request.Files });
                //Middle Level - Customize to your Preferences
                case 2:
                    return Json.Encode(new { request.Cookies, request.Headers, request.Files, request.Form, 
                         request.QueryString, request.Params });
                //Highest Level - Serialize the entire Request object
                case 3:
                    //We can't simply just Encode the entire request string due to circular references as well
                    //as objects that cannot "simply" be serialized such as Streams, References etc.
                    //return Json.Encode(request);
                    return Json.Encode(new { request.Cookies, request.Headers, request.Files, 
                     request.Form, request.QueryString, request.Params });
            }
        }
    }