如何在 ASP.Net MVC 5 中跟踪匿名用户的活动?

Ian*_*Ian 3 c# asp.net asp.net-mvc user-activity asp.net-mvc-5

我创建了一个ASP.Net MVC 5Web 应用程序,其服务可供匿名用户使用。当匿名用户使用 Web 服务时,它会从数据库中进行一些查询。但是,出于安全原因,我的客户想要跟踪匿名用户的“可疑”活动。其中之一包括匿名用户每天查询的次数(以防止大量数据被“窃取”)。

有没有办法捕获这些信息?

对于注册用户,我们可以在被ApplicationUser调用者中创建额外的属性QueryNo并将其添加Claim如下:

public class ApplicationUser : IdentityUser {
    public uint QueryNo { get; set; } //how many times this user has queried

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("QueryNo", QueryNo));
        return userIdentity;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我们想要跟踪它的活动时,我们可以简单地增加它的QueryNo每个查询活动。例如,当我们想要显示它时,我们可以简单地定义一个扩展,Identity如下所示:

public static class IdentityExtensions {
    public static string GetQueryNo(this IIdentity identity) {
        if (identity == null) {
            throw new ArgumentNullException("identity");
        }
        var ci = identity as ClaimsIdentity;
        if (ci != null) {
            return ci.FindFirstValue("QueryNo");
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样在视图中简单地使用它:

<p>No Of Query: @User.Identity.GetQueryNo()</p>
Run Code Online (Sandbox Code Playgroud)

但是我们如何跟踪匿名用户的活动(例如它的查询次数)?

Mis*_*pic 6

首先创建您的操作过滤器:

public class TrackingActionFilter : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var sessionId = filterContext.HttpContext.Session.SessionID;
        Debug.WriteLine("Printing session Id: " + sessionId);

        var ip = filterContext.HttpContext.Request.UserHostAddress;
        Debug.WriteLine("Printing ip: " + ip);

        var headers = filterContext.RequestContext.HttpContext.Request.Headers;
        foreach(var header in headers) {
            Debug.WriteLine("Printing header: " + header);
        }

        var parms = filterContext.HttpContext.Request.Params;
        foreach (var key in parms.AllKeys)
        {
            Debug.WriteLine("Printing parameter: " + key + " - " + parms[key]);
        }

        var routeDataKeys = filterContext.RouteData.Values.Keys;
        foreach(var key in routeDataKeys)
        {
            Debug.WriteLine("Printing route data value: " + key + " - " + filterContext.RouteData.Values[key]);
        }

        //Stolen with love from http://stackoverflow.com/questions/12938621/how-can-i-log-all-query-parameters-in-an-action-filter
        var stream = filterContext.HttpContext.Request.InputStream;
        var data = new byte[stream.Length];
        stream.Read(data, 0, data.Length);
        Debug.WriteLine(Encoding.UTF8.GetString(data));
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,您将捕获相关详细信息,而不仅仅是将它们写入调试窗口。

现在您可以在操作级别应用操作过滤器:

[TrackingActionFilter]
public ActionResult Index()
Run Code Online (Sandbox Code Playgroud)

或者在控制器级别:

[TrackingActionFilter]
public class HomeController : Controller
Run Code Online (Sandbox Code Playgroud)

或者您可以通过以下方式全局覆盖整个 MVC 应用程序FilterConfig

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new TrackingActionFilter());
    }
}
Run Code Online (Sandbox Code Playgroud)