web-dev-qa-db-fra.com

La sécurité de printemps hasRole () ne fonctionne pas

Je rencontre un problème lorsque j'utilise Spring Security && Thymeleaf, plus particulièrement lorsque j'essaie d'utiliser l'expression hasRole . L'utilisateur 'admin' a un rôle 'ADMIN' mais hasRole('ADMIN') est résolu en false de toute façon, je l'essaie

Mon html:

1.<div sec:authentication="name"></div> <!-- works fine -->
2.<div sec:authentication="principal.authorities"></div> <!-- works fine -->

3.<div  sec:authorize="isAuthenticated()" >true</div> <!-- works fine -->
4.<span th:text="${#authorization.expression('isAuthenticated()')}"></span> <!-- works fine -->

5.<div th:text="${#vars.role_admin}"></div> <!--Works fine -->
6.<div  sec:authorize="${hasRole('ADMIN')}" > IS ADMIN </div> <!-- Doesnt work -->
7.<div  sec:authorize="${hasRole(#vars.role_admin)}" > IS ADMIN </div> <!-- Doesnt work -->
8.<div th:text="${#authorization.expression('hasRole(''ADMIN'')')} "></div> <!-- Doesnt work -->
9.<div th:text="${#authorization.expression('hasRole(#vars.role_admin)')}"></div> <!-- Doesnt work -->

résulte en:

1.admin
2.[ADMIN]
3.true
4.true
5.ADMIN
6."prints nothing because hasRole('ADMIN') resolves to false"
7."prints nothing because hasRole(#vars.role_admin) resolves to false"
8.false
9.false

J'ai activé use-expressions dans mon fichier security.xml

<security:http auto-config="true" use-expressions="true">

Et également inclus le SpringSecurityDialect dans ma config

<bean id="templateEngine"
      class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />  
    <property name="additionalDialects">
        <set>
            <bean class="org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect" />
        </set>
    </property>      
</bean>

Toutes les dépendances nécessaires dans mon fichier pom.xml

<!--Spring security--> 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>4.0.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.0.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.0.1.RELEASE</version>
    </dependency>        

    <!--Thymeleaf Spring Security-->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>2.1.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>

Role.Java

@Entity
@Table(name = "roles")

    public class Role implements Serializable {

        @Id
        @Enumerated(EnumType.STRING)
        private RoleType name;
        //... getters, setters
    }

RoleType

public enum RoleType {

    ADMIN 
}

Et User a un ensemble de Roles

Pourquoi hasRole() ne fonctionne-t-il pas?

J'apprécie votre aide, merci

Solution de contournement

th:if="${#strings.contains(#authentication.principal.authorities,'ADMIN')}"

28
Xipo

Essayez d'utiliser hasAuthority à la place de hasRole dans la balise HTML.

sec:authorize="hasAuthority('ADMIN')"
69
Dmitry Stolbov

J'ai eu le même problème lors de la mise à niveau de Spring Security 3.x vers la version 4.x. Le passage de hasRole() à hasAuthority() a fait l'affaire pour moi.

http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#el-common-built-in

12
Jeffrey B.

Je devais faire quelque chose de similaire lorsque je devais vérifier le rôle de l'utilisateur. J'ai fait ci-dessous

<div th:if="${ #authorization.expression('isAuthenticated()') and #strings.contains(#authentication.principal.authorities,'ADMIN')}">          
    <a th:href="@{/somelink}">ADMIN LINK</a>
 </div>

J'espère que ça aide quelqu'un.

6
rohtakdev

Il vous manque un concept:

  • Si vous utilisez hasRole('ADMIN'), votre ADMIN Enum doit être ROLE_ADMIN au lieu de ADMIN.
  • Si vous utilisez hasAuthority('ADMIN'), votre ADMIN Enum doit être ADMIN.

Dans la sécurité du printemps, hasRole() est identique à hasAuthority(), mais la fonction hasRole() est mappée avec Authority sans le préfixe ROLE_.

Vous pouvez trouver la réponse acceptée dans cet article: Différence entre Role et GrantedAuthority dans Spring Security

5
Huy Quang

J'ai récemment eu le même problème… .. Ce que vous devez faire est:

  1. Dans votre code HTML, ajoutez ces déclarations:

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"   xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
    

(Vous pouvez choisir entre springsecurity4 ou springsecurity3, selon ce que vous utilisez).

  1. Assurez-vous d'avoir ajouté cette ressource à vos bibliothèques. J'utilise gradle mais vous pouvez en faire autant avec Maven.

    compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4:2.1.2.RELEASE'
    
  2. Dans votre classe SpringWebConfiguration ou xml, assurez-vous que vous ajoutez le dialecte pour thymeleaf SpringSecurity: J'utilise une classe Java pour la configuration.

    @Bean
    public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.addDialect(new SpringSecurityDialect());
    return templateEngine;
    }
    

Mais vous pouvez aussi définir comme alexsource dit: La sécurité de printemps et Thymeleaf ne fonctionne pas

J'espère que cela fonctionne pour vous! Salutations!

4
sirandy

Reportez-vous à la documentation officielle. http://www.thymeleaf.org/doc/articles/springsecurity.html

<div sec:authorize="hasRole('ROLE_ADMIN')">
  This content is only shown to administrators.
</div>
<div sec:authorize="hasRole('ROLE_USER')">
  This content is only shown to users.
</div>

Pouvez-vous simplement l'essayer comme ci-dessous sans le ${ ... }.

<div sec:authorize="hasRole('ADMIN')">IS ADMIN</div>

Je crois que vous n'avez pas préfixé les rôles avec ROLE_. Si oui, veillez à ajouter le préfixe comme ci-dessous

<div sec:authorize="hasRole('ROLE_ADMIN')">IS ADMIN</div>
1
Faraj Farook

J'ai eu le même problème, c'est à cause de spring-security4.0. Pour une raison quelconque, thymeleaf-extras-springsecurity4 n'est pas compatible avec spring-security 4.0 et thymeleaf2.x. Donc, j'ai rétrogradé les versions de spring-security en 3.2.9.RELEASE et tout a commencé à fonctionner . Si vous voulez toujours utiliser spring-security 4.0, vous pouvez peut-être essayer d'élever thymeleaf-extras-springsecurity4 en 3.0.0.RELEASE et thymeleaf en passant à 3.0

Ou si vous utilisez une application de démarrage printanière, la situation devient alors plus compliquée, il ne vous reste plus qu'à rétrograder le spring-security ou à mettre à niveau la version de démarrage printanier vers la version 1.4.x (toujours en version bêta).

Dans votre scénario spécifique, les modifications de pom ci-dessous devraient permettre à hasRole de fonctionner

<!--Spring security--> 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>3.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>3.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>3.2.9.RELEASE</version>
    </dependency>        

    <!--Thymeleaf Spring Security-->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>2.1.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>
1