Spring Security 实现角色继承

Spring Security 实现角色继承

本文描述如何基于Spring Security 实现角色继承。

权限声明

很多应用基于Spring Security 实现认证过程,通常需要定义一些角色,这些角色可能会有优先级或层次关系。假设我们有三个角色:
ADMIN, MODERATOR ,USER.

下面代码进行权限声明:

@Secured(['MODERATOR'])
def dashBoard(){
    render(view: 'dashBoard')
}

我们看到通过注解限制角色访问。如果你想ADMIN用户也要访问,我们需要增加角色声明:

@Secured(['ADMIN','MODERATOR'])

这样能够实现需求,但在我们系统中有很多这样场景,因此采用这种方式显得很啰嗦。

实现角色继承

为了实现角色继承,需要下面两步:

  1. 定义bean RoleHierarchy
  2. 定义 expressionhandler 读角色继承关系

示例配置代码:

import org.springframework.context.annotation.Bean;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;

@EnableWebSecurity
public class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter{

    private SecurityExpressionHandler webExpressionHandler() {
        DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
        defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
        return defaultWebSecurityExpressionHandler;
    }

    @Bean
    public RoleHierarchy roleHierarchy(){
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ADMIN > MODERATOR > USER");
        return roleHierarchy;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("ekansh")
                .password("password")
                .authorities("USER", "ROLE");
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("admin")
                .authorities("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .expressionHandler(webExpressionHandler())
                .antMatchers("/admin/**").hasAuthority("ADMIN")
                .antMatchers("/user/**").hasAuthority("USER")
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout()
        ;
    }
    
}

上面示例,角色继承关系如下:

  1. ADMIN 能访问 MODERATOR 和 USER 角色权限.
  2. MODERATOR 能访问 USER 角色权限.
  3. USER 及不能访问 MODERATOR 角色,也不能访问 ADMIN 角色权限.

总结

通过角色继承使得配置和管理角色和角色权限更简单。

你可能感兴趣的:(Spring,Security)