Spring security added prefix “ROLE_” to all roles name?

前端 未结 5 1523
被撕碎了的回忆
被撕碎了的回忆 2020-12-01 12:00

I have this code in my Web Security Config:

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests         


        
相关标签:
5条回答
  • 2020-12-01 12:40

    _ROLE prefix is used by spring security, to identify that it is as a role. A role has a set of privileges a.k.a Authorities, these authorities define varies permissions for a role. ex:- EDIT_PROFILE, DELETE_PROFILE

    You can define both the roles and authorities, if you are defining a role then it must be prefixed with "ROLE_"

    In your case you are looking for a role, so by default spring security looks for a string that is prefixed with "ROLE_".

    0 讨论(0)
  • 2020-12-01 12:44

    Spring security adds the prefix "ROLE_" by default.

    If you want this removed or changed, take a look at

    How to change role from interceptor-url?

    EDIT: found this as well: Spring Security remove RoleVoter prefix

    0 讨论(0)
  • 2020-12-01 12:46

    You can create a mapper to add _ROLE at the beginning of all of your roles:

    @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;
    }
    

    The you should add the mapper to your provider:

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        // your config ...
        provider.setAuthoritiesMapper(authoritiesMapper());
    
        return provider;
    }
    
    0 讨论(0)
  • 2020-12-01 12:47

    In Spring 4, there are two methods hasAuthority() and hasAnyAuthority() defined in org.springframework.security.access.expression.SecurityExpressionRoot class. These two methods checks only your custom role name without adding ROLE_ prefix. Definition as follows:

    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;
    }
    

    Example usage:

    <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>
    
    0 讨论(0)
  • 2020-12-01 12:52

    As @olyanren sad, you can use hasAuthority() method in Spring 4 instead of hasRole(). I am adding JavaConfig example:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        .authorizeRequests()
        .antMatchers("/api/**")
        .access("hasAuthority('ADMIN')")
        .and()
        .httpBasic().and().csrf().disable();
    }
    
    0 讨论(0)
提交回复
热议问题