Spring Security 授权操作4

Spring Security 授权操作

1.授权

所谓的授权,就是用户如果要访问某一个资源,我们要去检查用户是否具备这样的权限,如果具备就允许访问,如果不具备,则不允许访问。

2.准备测试用户

因为我们现在还没有连接数据库,所以测试用户还是基于内存来配置。

基于内存配置测试用户,我们有两种方式,第一种就是我们本系列前面几篇文章用的配置方式,如下:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("javaboy")
            .password("123").roles("admin")
            .and()
            .withUser("江南一点雨")
            .password("123")
            .roles("user");
}

这是一种配置方式。

由于 Spring Security 支持多种数据源,例如内存、数据库、LDAP 等,这些不同来源的数据被共同封装成了一个 UserDetailService 接口,任何实现了该接口的对象都可以作为认证数据源。

因此我们还可以通过重写 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;
}

两种基于内存定义用户的方法,大家任选一个。

3.准备测试接口

测试用户准备好了,接下来我们准备三个测试接口。如下:

@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 身份。

4.配置

接下来我们来配置权限的拦截规则,在 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. 剩余的其他格式的请求路径,只需要认证(登录)后就可以访问。

注意代码中配置的三条规则的顺序非常重要,和 Shiro 类似,Spring Security 在匹配的时候也是按照从上往下的顺序来匹配,一旦匹配到了就不继续匹配了,所以拦截规则的顺序不能写错

5.启动测试

接下来,我们启动项目进行测试。

项目启动成功后,我们首先以 江南一点雨的身份进行登录:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1JeFPBq-1631057276663)(C:\Users\Administrator\Desktop\笔记\SpringBoot\整合Spring Security\Pictures\security-5-2.png)]

登录成功后,分别访问 /hello/admin/hello 以及 /user/hello 三个接口,其中:

  1. /hello 因为登录后就可以访问,这个接口访问成功。
  2. /admin/hello 需要 admin 身份,所以访问失败。
  3. /user/hello 需要 user 身份,所以访问成功。

6.角色继承

所有 user 能够访问的资源,admin 都能够访问,很明显我们目前的代码还不具备这样的功能。要实现所有 user 能够访问的资源,admin 都能够访问,这涉及到另外一个知识点,叫做角色继承。这在实际开发中非常有用。

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

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

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

配置完成后,重启项目,此时我们发现 javaboy 也能访问 /user/hello 这个接口了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值