Exiger une autorisation préalable ne fonctionne pas
Je suis en train d'écrire un serveur socket (pas de web-application !) application et que vous voulez utiliser la méthode de base de la sécurité pour gérer mes ACL besoins. j'ai suivi un petit tutoriel que j'ai trouvé printemps de sécurité par exemple
jusqu'à présent, j'ai configuré:
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler" />
</security:global-method-security>
<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator">
<bean id="permissionEvaluator" class="myPermissionEvaluator" />
</property>
</bean>
<security:authentication-manager id="authenticationmanager">
<security:authentication-provider ref="authenticationprovider" />
</security:authentication-manager>
<bean id="authenticationprovider" class="myAuthenticationProvider" />
Avec un service de haricot:
@Named
public class ChannelService {
@PreAuthorize("isAuthenticated() and hasPermission(#channel, 'CHANNEL_WRITE')")
public void writeMessage(Channel channel, String message) { ... }
}
Tout compile et l'application démarre et fonctionne très bien, mais sans le contrôle d'accès. Mon journal de débogage montre que mon Évaluateur n'est jamais appelée.
Quand j'ai essayé quelque chose de similaire avec un @Secured
annotation l'annotation a été évaluée et l'accès a été refusé. mais le simple rôle de fonction de sécurité n'est pas suffisant pour mes besoins.
MODIFIER
fait des tests un peu plus: lorsque je configure seulement garanti-annotations="activé" le rôle sécurité basée sur les œuvres. lors de la configuration de pré-post-annotations="activé" en OUTRE ni sécurisé, ni exiger une autorisation préalable de travaux. lorsque je configure uniquement pré-post-annotations cela ne fonctionne toujours pas.
EDIT2
des tests un peu plus:
avec seulement secured_annotations="activé" l'appel à mon channelservice passe par la Cglib2AopProxy
dès que j'ai activer les pré-post-annotations à l'appel des terres directement dans le channelservice. aucun intercepteur, pas de proxy, rien.
Je deviens désespérée...
EDIT3
Je debug-connecté mon lancement pour test ici est la partie pour le printemps-sécurité
avec seulement garanti-annotations="activé"
2012-04-12 13:36:46,171 INFO [main] o.s.s.c.SpringSecurityCoreVersion - You are running with Spring Security Core 3.1.0.RELEASE
2012-04-12 13:36:46,174 INFO [main] o.s.s.c.SecurityNamespaceHandler - Spring Security 'config' module version is 3.1.0.RELEASE
2012-04-12 13:36:49,042 DEBUG [main] o.s.s.a.m.DelegatingMethodSecurityMetadataSource - Caching method [CacheKey[mystuff.UserService; public void mystuff.UserService.serverBan(java.lang.String,mystuff.models.User,org.joda.time.DateTime)]] with attributes [user]
2012-04-12 13:36:49,138 DEBUG [main] o.s.s.a.i.a.MethodSecurityInterceptor - Validated configuration attributes
2012-04-12 13:36:49,221 DEBUG [main] o.s.s.a.m.DelegatingMethodSecurityMetadataSource - Caching method [CacheKey[mystuff.ChannelService; public void mystuff.ChannelService.writeMessage(mystuff.models.Channel,java.lang.String)]] with attributes [blubb]
2012-04-12 13:36:51,159 DEBUG [main] o.s.s.a.ProviderManager - Authentication attempt using mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:36:56,166 DEBUG [Timer-1] o.s.s.a.ProviderManager - Authentication attempt using mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:36:56,183 DEBUG [Timer-1] o.s.s.a.i.a.MethodSecurityInterceptor - Secure object: ReflectiveMethodInvocation: public void mystuff.ChannelService.writeMessage(mystuff.models.Channel,java.lang.String); target is of class [mystuff.ChannelService]; Attributes: [blubb]
2012-04-12 13:36:56,184 DEBUG [Timer-1] o.s.s.a.i.a.MethodSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@312e8aef: Principal: mystuff.UserId@ced1752b; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities
Exception in thread "Timer-1" org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:88)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:205)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at mystuff.ChannelService$$EnhancerByCGLIB$$3ad5e57f.writeMessage(<generated>)
at mystuff.run(DataGenerator.java:109)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
2012-04-12 13:36:56,185 DEBUG [Timer-1] o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@1cfe174, returned: 0
2012-04-12 13:36:56,185 DEBUG [Timer-1] o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@da89a7, returned: 0
avec pré-post-annotations="activé"
2012-04-12 13:39:54,926 INFO [main] o.s.s.c.SpringSecurityCoreVersion - You are running with Spring Security Core 3.1.0.RELEASE
2012-04-12 13:39:54,929 INFO [main] o.s.s.c.SecurityNamespaceHandler - Spring Security 'config' module version is 3.1.0.RELEASE
2012-04-12 13:39:54,989 INFO [main] o.s.s.c.m.GlobalMethodSecurityBeanDefinitionParser - Using bean 'expressionHandler' as method ExpressionHandler implementation
2012-04-12 13:39:59,812 DEBUG [main] o.s.s.a.ProviderManager - Authentication attempt mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:39:59,850 DEBUG [main] o.s.s.a.i.a.MethodSecurityInterceptor - Validated configuration attributes
Autant je comprends ce journal de sortie de printemps ne réalise pas mes haricots doivent être déterminées, de sorte qu'ils ne le sont pas et donc je n'ai pas de sécurité.
EDIT4
Je debug-connecté complète sprint de démarrage... (c'est un grand journal) et j'y trouve:
2012-04-12 14:40:41,385 INFO [main] o.s.c.s.ClassPathXmlApplicationContext - Bean 'channelService' of type [class mystuff.ChannelService] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
est-il un moyen de comprendre pourquoi? car autant que je le comprends. en raison de @exiger une autorisation préalable de la fève doit être admissibles. avec seulement garanti-annotations="activé" je reçois un post-traitement de journal.
printemps 3.1.0.COMMUNIQUÉ de tout.
Vous pouvez déboguer si "PrePostAnnotationSecurityMetadatasource#getAttributes()" est appelée pour votre méthode, lorsque le Printemps initialise ?
je peux et ça ne fonctionne pas. il semble que, parce que mon PermissionEvaluator besoins de la chaîne de service ce service est créé avant de la source de données (création du service est entre loglines 215 (démarrer) -702 (fin); la source de données est d'abord mentionné dans la ligne de 870 avec "n'est pas admissible à obtenir ....)
quand j'ai enlevé @inject ChannelService de mon PermissionEvaluator le proxy a été créé.
OriginalL'auteur Laures | 2012-04-11
Vous devez vous connecter pour publier un commentaire.
Cette configuration a fonctionné comme prévu pour moi:
J'ai reçu le message de log:
Et une exception:
À partir d'un simple test:
Une chose que je ne diffrent était d'utiliser l'interface d'un service et JDK procurations au lieu de cglib:
et:
UPDATE1:
Avec cette simplifié config j'obtiens le même résultat:
UPDATE2:
Le message de débogage à partir de Edit4 indique que
channelService
ne peut pas avoir de haricots mandaté à tous comme il a obtenu classés commene sont pas admissibles pour l'auto-proxy
. Cette qiestion réponses problème similaire - essayez de ne pas utiliser@Autowired
ou de tout autre mécanisme basé surBeanPostProcessors
pour configurer les haricots impliqués dans les contrôles de sécurité (c'est à diremyPermissionEvaluator
).UPDATE3:
Vous ne peut pas utilisation des ressources sécurisées (i.e. les services) au sein de haricots responsable pour les contrôles de sécurité! Cela crée une dépendance de la boucle et est une erreur dans Votre configuration. Vous doit utilisation amant d'accès de niveau (c'est à dire DAO) pour vérifier les autorisations, tout ce qui est pas sécurisé! La mise en œuvre des contrôles de sécurité à l'aide de ressources sécurisées est pas ce que Vous voulez faire.
Si, en dépit de l'aide pas des ressources sécurisées avec
@Autowired
les choses ne fonctionnent pas comme prévu, essayez d'utiliser de la vieille école XML confiuration de style pour tous les haricots impliqués dans les contrôles de sécurité. Rappelez-vous aussi que<context:component-scan />
est en fait unBeanDefinitionRegistryPostProcessor
et introduit la numérisation de haricots dans leBeanFactory
après tous ceux déclarés dans le XML sont déjà là.voir ma réponse étendue pour plus de conseils.
les méthodes que j'utilise pour vérifier les autorisations ne sont pas sécurisés (et ne sera pas), mais ils font partie du service qui a obtenu méthodes. j'ai résolu le problème en recherchant l'objet de service de l'application de contexte quand j'ai besoin. peut-être pas la solution la plus propre, mais dans mon cas il n'y a pas de baisse de niveau d'accès.
Vous devez diviser ce service en 2 separete classes - un contenant uniquement non garantis méthodes pour l'utilisation dans les contrôles de sécurité, et l'autre contenant l'sécurisé méthodes pour le cas d'utilisation d'affaires. Puis les deux
@Inject
de non garantie d'un service à VotrepermissionEvaluator
et auto-proxy sécurisé fonctionne correctement. Même lorsque vous n'utilisez pas sécurisé méthodes, Vous êtes toujours à l'aide d'une classe que vous Vous attendez à être mandatées avec des contrôles de sécurité - c'est une dépendance de la boucle qui doit être enlevée par un projet de division.La troisième mise à jour m'a sauvé la vie. Vous NE pouvez pas appeler des services dans votre customPermissionEvaluator qui ont toute sorte de Pré/PostAuthorization. Cette juste échoue silencieusement et d'autorisation est jamais exécuté. Je l'ai résolu en ajoutant @Paresseux pour les services susmentionnés lorsqu'il est passé au travers de mon PermissionEvaluator constructeur
OriginalL'auteur Roadrunner
il fonctionne,
assurez-vous que vous avez
<sec:global-method-security pre-post-annotations="enabled"/>
dans votre printemps servlet (c'est à dire où vous pouvez avoir votre<mvc:annotation-driven/>
)"sec" est de
xmlns:sec="http://www.springframework.org/schema/security"
quel est le nom de l'annotation que vous utilisez? ce n'est pas un printemps annotation, peut-être que vous devriez essayer avec le Composant anntotation
nommé est un jsr330 annotation basictly signifie la même chose en tant que composant, mais son standartized et pas de printemps spécifiques. la jsr 330 est mis en œuvre d'ici le printemps.
OriginalL'auteur storm_buster