2016-08-10 3 views
1

Je crée une application Web ASP.Net MVC 5 dont le service peut être utilisé par des utilisateurs anonymes. Lorsque l'utilisateur anonyme utilise le service Web, il va faire une requête à partir de la base de données. Pour des raisons de sécurité, cependant, mon client souhaite suivre les activités «suspectes» des utilisateurs anonymes. L'un d'entre eux comprend combien de fois un utilisateur anonyme interroge par jour (pour éviter qu'une quantité importante de données ne soit «volée»).Comment faire le suivi des activités des utilisateurs anonymes dans ASP.Net MVC 5?

Y at-il un moyen de capturer cette information?

pour les utilisateurs enregistrés, nous pourrions créer des biens supplémentaires dans le ApplicationUser appelé QueryNo et l'ajouter dans le Claim comme ceci:

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; 
    } 
} 

Et quand nous voulons suivre son activité, nous pourrions tout simplement augmenter sa QueryNo par activité de requête. Lorsque nous voulons l'afficher, on pourrait, par exemple, définir simplement une extension pour Identity comme ceci:

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; 
    } 
} 

Et puis il suffit d'utiliser dans la vue comme ceci:

<p>No Of Query: @User.Identity.GetQueryNo()</p> 

Mais comment nous suivons les activités de l'utilisateur anonyme (c'est-à-dire son nombre de requêtes)?

+0

Je ne pense pas que vous puissiez avoir une solution totalement pare-balles. Vous pouvez suivre via la session de l'utilisateur - ce que quelqu'un malveillant pourrait contourner simplement en désactivant les cookies. Si vous êtes d'accord avec cela, je pense qu'un filtre d'action qui permet de suivre quelles actions sont consommées avec des paramètres particuliers pourrait être votre meilleur pari. Vous pouvez capturer des choses comme l'ID de session, l'adresse IP, les détails du navigateur, etc ... bien que tout cela pourrait être suspect. –

+0

Désactiver les cookies serait gênant, certainement. :/mais supposons que la plupart des utilisateurs ne se soucient pas d'élaborer/donner un exemple de votre suggestion, "je pense qu'un filtre d'action qui suit quelles actions sont consommées avec des paramètres particuliers pourrait être votre meilleur pari. capturer des choses comme l'ID de session, adresse IP, les détails du navigateur, etc ... bien que tous ceux qui pourraient être suspects "? – Ian

Répondre

2

D'abord créer votre filtre d'action:

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)); 
    } 
} 

vous aurait obivously capturer les détails pertinents au lieu de les écrire à la fenêtre de débogage.

Vous pouvez maintenant appliquer le filtre d'action au niveau d'action:

[TrackingActionFilter] 
public ActionResult Index() 

Ou au niveau du contrôleur:

[TrackingActionFilter] 
public class HomeController : Controller 

Ou vous pouvez couvrir globalement l'ensemble de votre application MVC via le FilterConfig:

public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new TrackingActionFilter()); 
    } 
} 
+0

Merci pour la réponse élaborée! Je dois vérifier sa mise en œuvre - donnez-moi un peu de temps, vous avez obtenu mon upvote de toute façon. – Ian