web-dev-qa-db-fra.com

L'annotation @PreAuthorize ne fonctionne pas

J'ai trouvé beaucoup de questions similaires mais aucune n'a résolu mon problème . Mon problème est ROLE_USER, je peux accéder aux fonctions de ROLE_ADMIN

Mon code spring-security.xml suit.

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:s="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security
                    http://www.springframework.org/schema/security/spring-security-3.0.xsd">   

<s:http auto-config="true" use-expressions="true">
    <s:intercept-url pattern="/index.jsp" access="permitAll" />
    <s:intercept-url pattern="/welcome*" access="hasRole('ROLE_USER')" />
    <s:intercept-url pattern="/helloadmin*" access="hasRole('ROLE_ADMIN')" />

    <s:form-login login-page="/login" default-target-url="/welcome"
        authentication-failure-url="/loginfailed" />
    <s:logout logout-success-url="/logout" />
</s:http>

<s:authentication-manager>
  <s:authentication-provider>
    <s:user-service>
        <s:user name="asif" password="123456" authorities="ROLE_USER,ROLE_ADMIN" />
        <s:user name="raheel" password="123456" authorities="ROLE_USER" />          
    </s:user-service>
  </s:authentication-provider>
</s:authentication-manager>

quand j'ajoute <s:global-method-security pre-post-annotations="enabled"/>my, le code indique une erreur de ressource non trouvée et lorsque je supprime mon code, je l'exécute avec succès, mais ROLE_USER peut accéder aux fonctions ROLE_ADMIN

Ma fonction de contrôleur est.

@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value="/delete", method = RequestMethod.GET)
public String DeleteAll(ModelMap model, Principal principal ) {

    org.springframework.security.core.userdetails.User activeUser = (org.springframework.security.core.userdetails.User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    System.out.println("Active user is "+activeUser.getUsername()+"Authorities are "+activeUser.getAuthorities());
    return "deleteUsers";

}
23
Raheel

Tu aurais dû

<s:global-method-security pre-post-annotations="enabled"/>

Si vous voulez que les annotations @PreAuthorize fonctionnent.


Pour répondre au commentaire:

Il semble que vous manquiez de la dépendance spring-aop.

Si vous utilisez Maven, vous avez besoin de:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${org.springframework.version}</version>
</dependency>

Sinon, vous pouvez obtenir le pot de ici .

26
Simeon

Je faisais face au même problème. Mon problème est résolu lorsque j'ai déplacé l'élément ci-dessous de applicationContext.xml vers * -servlet.xml (la configuration de mon répartiteur). 

<security:global-method-security secured-annotations="enabled"/>

Vous devez inclure cet élément dans le code XML de votre dispatcher PAS dans le code XML de votre application.
Spring FAQ

14

J'avais le même problème avec les annotations, le problème était qu'il n'y avait pas d'annotation @Controller dans mon contrôleur.


Il semble donc que vous ayez besoin de:

  • Ces annotations dans votre configuration Spring Security:

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    
  • Ces annotations dans votre contrôleur:

    @Controller
    public class ServiceRS {
    
        @RequestMapping(value = "/admin", method = RequestMethod.GET)
        @PreAuthorize("hasAuthority('ROLE_ADMIN')")
        public void wsAdmin() {
            [...]
        }
    }
    

De plus, si vous rencontrez toujours des problèmes, pensez à ajouter ceci à votre configuration log4j2:

    <Logger name="org.springframework.security" level="trace" additivity="false">
        <AppenderRef ref="Console" />
        <AppenderRef ref="RollingRandomAccessFile" />
    </Logger>

Vous verrez dans les journaux si vos annotations sont prises en compte par Spring:

TRACE org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource {} [main] Looking for Pre/Post annotations for method 'wsAdmin' on target class '***.ServiceRS' 
DEBUG org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource {} [main] @org.springframework.security.access.prepost.PreAuthorize(value=hasAuthority('ROLE_ADMIN')) found on specific method: public void ***.ServiceRS.wsAdmin() 
DEBUG org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource {} [main] Caching method [CacheKey[***.ServiceRS; public void ***.ServiceRS.wsAdmin()]] with attributes [[authorize: 'hasAuthority('ROLE_ADMIN')', filter: 'null', filterTarget: 'null']] 

Et évidemment, vous pouvez envisager d'ajouter des points d'arrêt dans les méthodes correspondantes dans org.springframework.security.access.expression.SecurityExpressionRoot pour voir si un appel est effectué avec la condition dans votre annotation.

Cordialement.

3
Alexandre Hamon

Essayez avec l'annotation @Secured,

Ensuite, vous aurez

@Secured("ROLE_ADMIN")
@RequestMapping(value="/delete", method = RequestMethod.GET)
public String DeleteAll(ModelMap model, Principal principal ) {

  ...

}

Voici un article de blog détaillé à ce sujet .

3
Martin Spa

Aucune des réponses ci-dessus n'a fonctionné pour moi. J'ai dû ajouter des décorateurs de sécurité. 

Les décorateurs sont placés sur des haricots dans le fichier servlet-context.xml.

Ajoutez d’abord un schéma de sécurité à l’espace de noms XML:

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
...
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

Ensuite, appliquez le décorateur à la mise en oeuvre du bean de service, comme si ..

<beans:bean id="myService" class="my.service.impl.MyServiceImpl" scope="request">
    <security:intercept-methods>
        <security:protect access="ROLE_USER" method="get*"/>
        <security:protect access="ROLE_ADMIN" method="set*"/>
    </security:intercept-methods>
</beans:bean>
2
user2601995

Cela pourrait vous aider: 

<security:global-method-security secured-annotations="enabled" proxy-target-class="true"/>

Cordialement.

1
rweiller

Ce problème se posera lors de l'utilisation de Servlet 3 avec Web Async Support. Spring Security 3.1.4 et versions antérieures perdent leur contexte de sécurité une fois la méthode anonyme de la méthode Callable égarée 

Mettre à jour Spring Security vers 3.2.0 RC1 résoudra vos problèmes.

Dépendance Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>3.2.0.RC1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>3.2.0.RC1</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>http://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>http://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
1
user2601995

mettez la balise ci-dessous dans un autre fichier de configuration de printemps, pas dans le fichier de configuration de sécurité de printemps.

J'avais aussi la même erreur.

<security:global-method-security secured-annotations="enabled" proxy-target-class="true"/>
0
pradipgarala