Spring Security使用详解2(基于内存的用户、URL权限配置 )

二、基于内存的用户、URL权限配置

1、用户角色配置

(1)我们可以通过自定义类继承 WebSecurityConfigurerAdapter,从而实现对 Spring Security 更多的自定义配置。比如下面样例我们就配置了两个用户,以及他们对应的角色。

注意:基于内存的用户配置在配置角色时不需要添加“ROLE_”前缀,而下文介绍的基于数据库的认证配置角色时需要添加“ROLE_”前缀。

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 指定密码的加密方式
    @SuppressWarnings("deprecation")
    @Bean
    PasswordEncoder passwordEncoder(){
        // 不对密码进行加密
        return NoOpPasswordEncoder.getInstance();
    }
 
    // 配置用户及其对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin").password("123").roles("ADMIN","USER")
                .and()
                .withUser("hangge").password("123").roles("USER");
    }
}

(2)配置完成后,重启项目,就可以使用这两个用户进行登录了。

 

2、配置 URL 访问权限

(1)上面配置完毕后受保护的资源都是默认的(不同角色访问权限也没有什么不同),而真正项目中我们需要根据实际情况进行角色管理。要实现这个功能只需重写 WebSecurityConfigurerAdapter 中的另一个方法即可: 

第 30 行代码说明:

  • formLogin() 方法表示开启表单登录,即我们之前看到的登录页面。
  • loginProcessingUrl() 方法配置登录接口为“/login”,即可以直接调用“/login”接口,发起一个 POST 请求进行登录,登录参数中用户名必须为 username,密码必须为 password,配置 loginProcessingUrl 接口主要是方便 Ajax 或者移动端调用登录接口。
  • permitAll() 表示和登录相关的接口都不需要认证即可访问。
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 指定密码的加密方式
    @SuppressWarnings("deprecation")
    @Bean
    PasswordEncoder passwordEncoder(){
        // 不对密码进行加密
        return NoOpPasswordEncoder.getInstance();
    }
 
    // 配置用户及其对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("root").password("123").roles("ADMIN","DBA")
        .and()
        .withUser("admin").password("123").roles("ADMIN","USER")
        .and()
        .withUser("hangge").password("123").roles("USER");
    }
 
    // 配置 URL 访问权限
    @Override
    protected  void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() // 开启 HttpSecurity 配置
            .antMatchers("/admin/**").hasRole("ADMIN") // admin/** 模式URL必须具备ADMIN角色
            .antMatchers("/user/**").access("hasAnyRole('ADMIN','USER')") // 该模式需要ADMIN或USER角色
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // 需ADMIN和DBA角色
            .anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问)
            .and().formLogin().loginProcessingUrl("/login").permitAll() // 开启表单登录并配置登录接口
            .and().csrf().disable(); // 关闭csrf
    }
}

(2)接着在 Conctoller 中添加如下接口进行测试:

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

(3)接下来测试一下,我们使用 admin 用户进行登录,由于该用户具有 ADMIN 和 USER 这两个角色,所以登录后可以访问 /hello、/admin/hello 以及 /user/hello 这三个接口。

(4)而由于 /db/hello 接口同时需要 ADMIN 和 DBA 角色,因此 admin 用户仍然无法访问。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章