web-dev-qa-db-fra.com

La sécurité de printemps a ajouté le préfixe "ROLE_" à tous les noms de rôles?

J'ai ce code dans ma configuration de sécurité Web:

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/api/**")
            .hasRole("ADMIN")
            .and()
            .httpBasic().and().csrf().disable();

}

J'ai donc ajouté un utilisateur avec le rôle "ADMIN" dans ma base de données et je reçois toujours une erreur 403 lorsque j'essayais de me connecter avec cet utilisateur, puis j'ai activé le journal pour le printemps et j'ai trouvé cette ligne:

2015-10-18 23:13:24.112 DEBUG 4899 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /api/user/login; Attributes: [hasRole('ROLE_ADMIN')]

Pourquoi Spring Security recherche "ROLE_ADMIN" au lieu de "ADMIN"? 

20
Gustavo Rozolin

Spring Security ajoute le préfixe "ROLE_" par défaut.

Si vous voulez que cela soit supprimé ou modifié, jetez un oeil à 

http://forum.spring.io/forum/spring-projects/security/51066-how-to-change-role-from-interceptor-url

EDIT: a également trouvé ceci: Spring Security supprimer le préfixe RoleVoter

16
jmcg

Au printemps 4, il existe deux méthodes hasAuthority() et hasAnyAuthority() définies dans la classe org.springframework.security.access.expression.SecurityExpressionRoot. Ces deux méthodes vérifient uniquement le nom de votre rôle personnalisé sans ajoutant le préfixe ROLE_. Définition comme suit:

public final boolean hasAuthority(String authority) {
    return hasAnyAuthority(authority);
}
public final boolean hasAnyAuthority(String... authorities) {
    return hasAnyAuthorityName(null, authorities);
}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
    Set<String> roleSet = getAuthoritySet();

    for (String role : roles) {
        String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
        if (roleSet.contains(defaultedRole)) {
            return true;
        }
    }

    return false;
}
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
    if (role == null) {
        return role;
    }
    if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
        return role;
    }
    if (role.startsWith(defaultRolePrefix)) {
        return role;
    }
    return defaultRolePrefix + role;
}

Exemple d'utilisation:

<http auto-config="false" use-expressions="true" pattern="/user/**"
      entry-point-ref="loginUrlAuthenticationEntryPoint">
    <!--If we use hasAnyAuthority, we can remove ROLE_ prefix-->
    <intercept-url pattern="/user/home/yoneticiler" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
    <intercept-url pattern="/user/home/addUser" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
    <intercept-url pattern="/user/home/addUserGroup" access="hasAuthority('FULL_ADMIN')"/>
    <intercept-url pattern="/user/home/deleteUserGroup" access="hasAuthority('FULL_ADMIN')"/>
    <intercept-url pattern="/user/home/**" access="hasAnyAuthority('FULL_ADMIN','ADMIN','EDITOR','NORMAL')"/>
    <access-denied-handler error-page="/403"/>
    <custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
    <logout logout-url="/user/logout"
            invalidate-session="true"
            logout-success-url="/user/index?logout"/>
    <!-- enable csrf protection -->
    <csrf/>
</http>   <beans:bean id="loginUrlAuthenticationEntryPoint"
            class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:constructor-arg value="/user"/>
</beans:bean>
13
olyanren

Comme @olyanren sad, vous pouvez utiliser la méthode hasAuthority () dans Spring 4 au lieu de hasRole (). J'ajoute un exemple JavaConfig:

@Override
protected void configure(HttpSecurity http) throws Exception {
    .authorizeRequests()
    .antMatchers("/api/**")
    .access("hasAuthority('ADMIN')")
    .and()
    .httpBasic().and().csrf().disable();
}
3
Svitlana Onish

Vous pouvez créer un mappeur pour ajouter _ROLE au début de tous vos rôles:

@Bean
public GrantedAuthoritiesMapper authoritiesMapper() {
    SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
    mapper.setPrefix("ROLE_"); // this line is not required 
    mapper.setConvertToUpperCase(true); // convert your roles to uppercase
    mapper.setDefaultAuthority("USER"); // set a default role

    return mapper;
}

Vous devez ajouter le mappeur à votre fournisseur:

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    // your config ...
    provider.setAuthoritiesMapper(authoritiesMapper());

    return provider;
}
0
Hamid Mohayeji