MVC intercepteur vs Printemps filtre de sécurité vs autre chose...?
Je suis en utilisant Spring-MVC, Spring Security pour mon application web. Il comprend l'inscription de l'utilisateur pages et privé panneau de l'utilisateur. Je l'ai mis en place actuellement avec l'URL suivant les modèles:
whatever/myapp/login
utilisateur d'ouvrir une session danswhatever/myapp/register?step=1
démarrer l'enregistrementwhatever/myapp/account/**
domaine privé de vues (pages)whatever/myapp/pending
vue affiché pendant le post-processus d'inscription completwhatever/myapp/blocked
compte bloqué vuewhatever/myapp/register/retry
si l'enregistrement a échoué, permettent de réessayer
Essentiellement, ces Url ci-dessous devrait exiger l'authentification de l'utilisateur, c'est à dire besoin de connexion:
whatever/myapp/account/**
(domaine privé de pages)whatever/myapp/pending
(cette page dispose d'une minuterie à rediriger vers /compte/foyer)whatever/myapp/register/retry
C'est assez simple à réaliser à l'aide de Spring security. Cependant, indépendamment de l'authentification de l'utilisateur par le biais de Printemps de la sécurité, domaine privé de la page doit être accessible ou non, en fonction de l'utilisateur du compte courant de l'état (stocké dans ma DB).
Plus précisément: si un utilisateur tente d'accéder à quoi que ce soit dans le secteur privé (/account/**
), il doit être démontré la vue appropriée (redirigé à la page appropriée), selon le statut. J'ai ces statuts définis:
suspended
- est lié à l'attente de vueenabled
- autoriser l'accès completdisabled
- ne sont pas pertinentes iciretry_allowed
- se rapporte à réessayer de vueblocked
- se rapporte à un compte bloqué vue
Actuellement, j'ai un MVC intercepteur de l'installation de /account/**
, qui vérifie l'état de l'utilisateur, et redirige vers les pages appropriées, mais de toute façon j'ai l'impression que ce n'est pas vraiment l'idéal ou une solution appropriée ici, depuis que je suis face à un comportement étrange, comme plusieurs de contrôleur de l'invocation... et aussi je ne suis pas tout à fait certain que le retour true
/false
dans preHandle()
méthode. Voici l'extrait de code de l'intercepteur:
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object arg2)
throws Exception {
IPanelUser pUser = (IPanelUser) SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
//check principal first and then load from DB
//"suspended" is initial status upon registration
if(pUser.getCustomer().getStatus() == CustomerStatus.Suspended.getCode()) {
//if suspended, load from DB and update status
Customer customer = this.customerService.getUserByUsername(pUser.getUsername());
if(customer != null)
pUser.getCustomer().setStatus(customer.getStatus());
//still suspended? redirect to pending
if(pUser.getCustomer().getStatus() == CustomerStatus.Suspended.getCode()) {
response.sendRedirect("../pending");
return false;
}
}
if(pUser.getCustomer().getStatus() == CustomerStatus.Blocked.getCode()) {
//redirect to blocked page
response.sendRedirect("../blocked");
SecurityContextHolder.clearContext();
return false;
}
if(pUser.getCustomer().getStatus() == CustomerStatus.AllowRetry.getCode()) {
//redirect to CC submission page
response.sendRedirect("../register/retry");
return false;
}
if(pUser.getCustomer().getStatus() == CustomerStatus.Enabled.getCode() ||
pUser.getCustomer().getStatus() == CustomerStatus.Disabled.getCode()) {
//do nothing
}
return true;
}
.
Est-ce une approche valable ? Toutes les autres suggestions ?
OriginalL'auteur Less | 2013-10-10
Vous devez vous connecter pour publier un commentaire.
Toutes les options sont valables, cela dépend du niveau d'abstraction que vous voulez.
Dans un
Filter
, vous avez seulement accès àHttpServletRequest
etHttpServletResponse
objets, de sorte que vous êtes très bien couplé avec leServlet
API. Vous pouvez aussi ne pas (directement) ont accès à toutes les grandes Printemps fonctionnalités comme retourner à la vue d'un rendu ou unResponseEntity
.Dans un
HandlerInterceptor
, c'est encore plus de la même chose. Vous pouvez faire votre redirection ou de traitement de la demande directement dans lepreHandle()
où vous n'avez pas accès à laModelAndView
ou de définir un indicateur qui vous vérifier danspostHandle()
. Vous aurez accès à laModelAndView
mais pas à certains autres Spring MVC fonctionnalité.Printemps de Sécurité est une bonne alternative, mais je trouve qu'il a beaucoup de configuration que je n'aime pas trop.
Une alternative définitive, ce que j'aime le plus, c'est de l'utilisation de l'AOP (vous pouvez faire cela avec Ressort de Sécurité ou Shiro). Vous créez une annotation comme
@Private
et vous annoter votre@Controller
méthodes de gestionnaire. Vous utilisez AOP à conseiller ces méthodes. Les conseils fondamentalement vérifie session de certains ou de l'attribut de la demande pour un drapeau (autorisé ou non). Si vous êtes admis, vous continuer à exécuter la méthode de gestionnaire, si pas, vous jetez uneUnauthorizedException
(ou similaire). Vous aussi déclarer un@ExceptionHandler
pour que l'exception dans le cas où vous avez beaucoup de contrôle complet sur la façon dont la réponse est généré: unModelAndView
(et apparentés), unResponseEntity
, d'annoter le gestionnaire avec@ResponseBody
, écrire la réponse directement, etc. Je sens que vous avez beaucoup plus de contrôle, si vous le souhaitez.OriginalL'auteur