217.Spring Boot+Spring Security:基于内存的角色授权_内存

说明

(1)JDK版本:1.8

(2)Spring Boot 2.0.6

(3)Spring Security 5.0.9

 

需求缘起

       之前我们基于内存的方式,构建了两个账号admin和user,对于这两个账号在实际项目中会有不同的角色,比如管理员角色和普通用户角色,对于不同的角色,那么允许访问的方法会不一样。

 

编码思路

       对于不同角色具有不同方法的权限的问题,主要需要思考几个点:

(1)如何给指定的用户指定角色

通过AuthenticationManagerBuilder的roles()方法,就可以指定角色,示例代码:

 

auth.inMemoryAuthentication()
            .withUser("admin")
            .password(passwordEncoder().encode("123456"))
            .roles("beijingAdmin","shanghaiAdmin");

       上面的示例中指定了用户admin,具有beijingAdmin,shanghaiAdmin的角色。

(2)如何开启方法级别安全控制

       想要开启Spring方法级安全,你需要在已经添加了@Configuration注解的类上再添加@EnableGlobalMethodSecurity注解即可。

(3)如何配置方法级别的权限控制

       使用注解@PreAuthorize("hasAnyRole('admin')")即可指定访问级别的角色。

 

一、基于内存的角色授权

       这里基于上一篇文章进行编码。

1.1 为用户配置角色

       通过AuthenticationManagerBuilder的roles()方法分配角色:

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        /*
         * 配置为从内存中进行加载认证信息.
         * 这里配置了两个用户 admin和user
         */
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password(passwordEncoder().encode("123456"))
            .roles("admin");

        auth.inMemoryAuthentication()
            .withUser("user")
            .password(passwordEncoder().encode("123456"))
            .roles("normal");
    }

 

1.2 开启Spring方法级安全

       想要开启Spring方法级安全,你需要在已经添加了@Configuration注解的类上再添加@EnableGlobalMethodSecurity注解:

(1)prePostEnabled :决定Spring Security的前注解是否可用 [@PreAuthorize,@PostAuthorize,..]

(2)secureEnabled : 决定是否Spring Security的保障注解 [@Secured] 是否可用。

(3)jsr250Enabled :决定 JSR-250 annotations 注解[@RolesAllowed..] 是否可用。

       我们这里在WebSecurityConfig进行添加配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}

说明:只有添加了@EnableGlobalMethodSecurity(prePostEnabled=true)之后,@PreAuthorize("hasAnyRole('admin')")才能生效。

 

1.3 配置方法级拥有的角色

       我们在HelloController添加两个方法,使用注解@PreAuthorize指定访问该方法需要的角色:

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public String getWelcomeMsg() {       
        return "Hello,Spring Security";
    }


    @GetMapping("/helloAdmin")
    @PreAuthorize("hasAnyRole('admin')")
    public String helloAdmin() {       
        return "Hello,admin";
    }

    @GetMapping("/helloUser")
    @PreAuthorize("hasAnyRole('admin','normal')")    
    public String helloUser() {       
        return "Hello,user";
    }
}

 

1.4 测试角色

       到这里就可以启动测试下:

(1)启动应用程序,访问如下地址:

http://127.0.0.1:8080/hello/helloUser

跳转到登录页面,输入账号user/123456,成功登录之后,会看到返回信息:Hello,user

然后在输入另外一个地址:

http://127.0.0.1:8080/hello/helloAdmin

这时候会看到403的报错:

217.Spring Boot+Spring Security:基于内存的角色授权_内存_02

(2)重新启动应用程序,输入admin/123456账号进行测试,都能正常访问。