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 用戶仍然無法訪問。

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