How to get authenticated user's name, IP address, and the controller action being called from an HTTP Filter?

90abyss picture 90abyss · Dec 6, 2016 · Viewed 11.2k times · Source

I'm trying to audit my action events on the controller. I want to keep track of authenticated user's name, his IP address, and controller action being called.

My filter code:

public class AuditAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext filterContext)
        {
            var request = filterContext.Request;
            // get user name + ip address + controlleraction 
            base.OnActionExecuting(filterContext);
        }

I was searching on the internet only to see examples of how to do it for Mvc but not for HTTP. For instance, this link here talks about how to audit events for Mvc: http://rion.io/2013/03/03/implementing-audit-trails-using-asp-net-mvc-actionfilters/

This link however talks about how to capture IP address for HTTP web app: Capture request IP Address in Web API Authentication Filter But I'm struggling to follow it. Not sure where exactly to put this code in.

Appreciate your help.

Answer

Vinod picture Vinod · Dec 6, 2016

Try using below code.

UPDATE: For asp.net web api, please try this

public class AuditAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var context = actionContext.RequestContext;
            var user = context.Principal.Identity.IsAuthenticated ? context.Principal.Identity.Name : string.Empty;
            var ip = GetClientIpAddress(actionContext.Request);
            var action = actionContext.ActionDescriptor.ActionName;
            var controller = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;

            base.OnActionExecuting(actionContext);
        }

        private string GetClientIpAddress(HttpRequestMessage request)
        {
            if (request.Properties.ContainsKey("MS_HttpContext"))
            {
                return IPAddress.Parse(((HttpContextBase)request.Properties["MS_HttpContext"]).Request.UserHostAddress).ToString();
            }
            if (request.Properties.ContainsKey("MS_OwinContext"))
            {
                return IPAddress.Parse(((OwinContext)request.Properties["MS_OwinContext"]).Request.RemoteIpAddress).ToString();
            }
            return String.Empty;
        }

    }

And for asp.net MVC, you can try this

public class AuditAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        // get user name + ip address + controlleraction 
        var controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        var action = filterContext.ActionDescriptor.ActionName;
        var ip = filterContext.HttpContext.Request.UserHostAddress;
        var dateTime = filterContext.HttpContext.Timestamp;
        var user = GetUserName(filterContext.HttpContext);
    }


    private string GetUserName(HttpContext httpContext)
    {
        var userName = string.Empty;
        var context = httpContext.Current;
        if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
        {
            userName = context.User.Identity.Name;
        }
        else
        {
            var threadPincipal = Thread.CurrentPrincipal;
            if (threadPincipal != null && threadPincipal.Identity.IsAuthenticated)
            {
                userName = threadPincipal.Identity.Name;
            }
        }
        return userName;
    }
}

Update 2 : Retrieving Client IP address is always a tricky business because there are lot of factors that has to be considered. How are clients accessing the application? Are they coming thru a proxy server? IP addresses can be spoofed, so there is no 100% reliable way. Looking at the Http Headers will provide you some level of success in both web api and mvc. But you always have to consider the fact that there will be cases where client IP is not valid.

How can I get the client's IP address in ASP.NET MVC?