2011-02-16 3 views
8

Je travaille sur une page qui permet aux utilisateurs de modifier les informations de profil. Je veux qu'ils soient en mesure d'éditer leurs informations publiques, mais ne leur permettent pas de changer les drapeaux du système tels que leur type d'utilisateur.Protéger des champs spécifiques lors de la liaison au printemps

Ceci est implémenté avec Spring MVC (3.0). L'objet utilisateur a des champs typiques tels que firstName, lastName, email (tout doit être modifiable) et un booléen administrator (qui ne doit pas être modifiable

Ma méthode ressemble à ceci:.

@RequestMapping(method = RequestMethod.POST) 
public String doEdit(
     @ModelAttribute("user") User user, 
     BindingResult result, 
     ModelMap model) 
throws IOException 
{ 
     // validate, blah blah 
     // save user object 
     // return page 

} 

Ma forme comprend des champs firstName, lastName etc et semblait fonctionner très bien.

le problème est que si un utilisateur malveillant de messages une requête avec le paramètre administrator comme « true » ils peuvent définir ce champ quand ils shouldn 't.

Je sais que je peux créer un objet "formulaire" séparé avec seulement les champs que je veux changer et utiliser pour la liaison automatique. (la copie sur les données). Le problème est que j'ai beaucoup d'endroits qui utilisent cette technique. (pour l'utilisateur et d'autres objets). Ce serait un problème à maintenir quand je veux ajouter des champs.

Existe-t-il un moyen d'utiliser des annotations ou d'autres techniques dans Spring MVC pour ajouter des paramètres à la liste blanche et empêcher les modifications des propriétés d'objet de domaine arbitraires?

+3

juste une anecdote historique, le printemps était si lâche dans ce domaine, qu'un utilisateur malveillant pourrait injecter « class.classLoader.URLs [] » à tout objet de modèle, en prenant complètement le contrôle du serveur. http://www.springsource.com/security/cve-2010-1622 – irreputable

+1

Je suis stupéfait. Je viens de passer de Spring 3.0.2 à Spring 3.0.5 en production la semaine dernière. –

Répondre

10

Le DataBinder a deux propriétés nommées allowedFields et disallowedFields qui définissent ce qu'il faut (dés) autoriser pour la liaison. Il suffit d'utiliser que dans votre méthode @InitBinder:

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.setDisallowedFields("administrator"); 
} 
+0

Existe-t-il un moyen d'autoriser certains champs en fonction du rôle de l'utilisateur connecté? –

+0

c'est un code java, donc cela pourrait être fait avec une logique programmée if (acl.allowCapability()) –

+0

Nice. Cela semble plus flexible, marquant ainsi comme la réponse. –

-2

Ne pas envoyer ce administrateur du côté client, contrôlez-le côté serveur.

+0

ce n'est pas un paramètre en soi, c'est une propriété de l'objet User. Ma question demande s'il y a un moyen d'ignorer cette propriété. –

+0

Votre objet de modèle utilisateur est lié à la couche de vue? Certaines personnes pensent que c'est bon. Je crois que non. Cependant, c'est une question controversée. Voir http://stackoverflow.com/questions/2680071/dto-or-domain-model-object-in-the-view-layer. Mon commentaire se passe lorsque vous utilisez des DTO dans oposite d'objets de domaine. – Iogui

3

Vous pouvez filtrer la demande avec les expressions de style, pour indiquer que le paramètre spécifié n'est pas censé être présent dans la demande « myParam! ».

@RequestMapping(params="!administrator") 
+0

sympa. Je pense que ceci ou la méthode initBinder fonctionnerait. Dommage que je ne puisse pas "répondre" deux fois. –

Questions connexes