所谓授权就是我你需要检查某一个用户是否有访问某一个资源的权限,有则允许访问,没有则不许访问

准备

如果配置了数据库,则可以直接在数据库中配置新用户
没有则可以在内存中配置用户

内存用户

  1. @Override
  2. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  3. auth.inMemoryAuthentication()
  4. .withUser("admin")
  5. .password("123456")
  6. .roles("admin")
  7. .and()
  8. .withUser("user1")
  9. .password("12345")
  10. .roles("user");
  11. }

配置了一个user权限的用户user1

数据源配置用户

spring security可以进行多数据源配置,内存数据,数据库,LDAP等都可以用作配置
这些不同来源的数据被集成到同一个UserDetailService接口中,任何实现了该接口的对象都可以是认证数据源

重写WebSecurityConfigureAdapter中的userDetailService,实现数据源配置

 @Bean
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("admin").password("123456").roles("admin").build());
        manager.createUser(User.withUsername("user1").password("123456").roles("user").build());
        return manager;
    }

两种方法任选其一即可

测试接口

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/admin/hello")
    public String admin() {
        return "admin";
    }

    @GetMapping("/user/hello")
    public String user() {
        return "user";
    }
}
  1. /hello 是任何人都可以访问的接口
  2. /admin/hello 是具有 admin 身份的人才能访问的接口
  3. /user/hello 是具有 user 身份的人才能访问的接口
  4. 所有 user 能够访问的资源,admin 都能够访问

「注意第四条规范意味着所有具备 admin 身份的人自动具备 user 身份。」

配置权限拦截

在config(HttpSecurity http)中进行配置权限拦截
注意代码中配置的三条规则的顺序非常重要,和 Shiro 类似,Spring Security 在匹配的时候也是按照从上往下的顺序来匹配,一旦匹配到了就不继续匹配了,「所以拦截规则的顺序不能写错」
注意配置权限拦截一定要在【.anyRequest().authenticated()】之前配置,否则会被覆盖,导致无法生效
如果你强制将 anyRequest 配置在 antMatchers 前面,此时项目在启动的时候,就会报错,会提示不能在 anyRequest 之后添加 antMatchers:

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

配置效果如下:

  1. 如果请求路径满足 /admin/** 格式,则用户需要具备 admin 角色。
  2. 如果请求路径满足 /user/** 格式,则用户需要具备 user 角色。
  3. 剩余的其他格式的请求路径,只需要认证(登录)后就可以访问。

其中通配符的含义如下

通配符 含义
** 匹配多层路径
* 匹配一层路径
? 匹配任意单个字符

测试

用户 接口 结果
admin /hello image.png
/admin/hello image.png
/user/hello image.png
user /hello image.png
/admin/hello image.png
/user/hello image.png

角色继承

我们设计之初想要的功能应该是user权限能访问的,admin权限也能访问,但是admin权限能访问的,user权限不一定能访问
那么就会使用到角色继承,这在实际的开发中非常实用
在config中进行配置

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

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

现在使用admin登录之后,可以访问user的权限