grant

通过重写 WebSecurityConfigurerAdapter 中的 userDetailsService 方法来提供一个 UserDetailService 实例进而配置多个用户:

@Bean
protected UserDetailsService userDetailsService() {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User.withUsername("javaboy").password("123").roles("admin").build());
    manager.createUser(User.withUsername("江南一点雨").password("123").roles("user").build());
    return manager;
}

两种基于内存定义用户的方法

  • 授权
  • 在 Spring Security 的 configure(HttpSecurity http) 方法中,代码如下:
http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .anyRequest().authenticated()
        .and()
        

这里的匹配规则我们采用了 Ant 风格的路径匹配符,Ant 风格的路径匹配符在 Spring 家族中使用非常广泛,它的匹配规则也非常简单:

通配符含义
**匹配多层路径
*匹配一层路径
?匹配任意单个字符
  1. 如果请求路径满足 /admin/** 格式,则用户需要具备 admin 角色。
  2. 如果请求路径满足 /user/** 格式,则用户需要具备 user 角色。
  3. 剩余的其他格式的请求路径,只需要认证(登录)后就可以访问。
  4. 注意代码中配置的三条规则的顺序非常重要,和 Shiro 类似,Spring Security 在匹配的时候也是按照从上往下的顺序来匹配,一旦匹配到了就不继续匹配了,「所以拦截规则的顺序不能写错」。

另一方面,如果你强制将 anyRequest 配置在 antMatchers 前面,像下面这样:

http.authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .and()

此时项目在启动的时候,就会报错,会提示不能在 anyRequest 之后添加 antMatchers:

角色继承

上级可能具备下级的所有权限,如果使用角色继承,这个功能就很好实现,我们只需要在 SecurityConfig 中添加如下代码来配置角色继承关系即可:

@Bean
RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_admin > ROLE_user");
    return hierarchy;
}

注意,在配置时,需要给角色手动加上 ROLE_ 前缀。上面的配置表示 ROLE_admin 自动具备 ROLE_user 的权限。