一篇文章帶你搞定 SpringSecurity 配置多個HttpSecurity 和實現對於方法安全的控制

南淮北安發表於2020-09-26

一、實現配置多個 HttpSecurity

前期的配置和學習基本和本系列的文章都一樣,
本篇文章不再贅述:學習 Spring Security 看這一篇部落格就夠了

@Configuration
public class MultiHttpSecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("nlcs").password("$2a$10$G3kVAJHvmRrr6sOj.j4xpO2Dsxl5EG8rHycPHFWyi9UMIhtdSH15u").roles("admin")
                .and()
                .withUser("yolo").password("$2a$10$kWjG2GxWhm/2tN2ZBpi7bexXjUneIKFxIAaMYJzY7WcziZLCD4PZS").roles("user");
    }

    @Configuration
    @Order(1)
    public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasAnyRole("admin");
        }
    }

    @Configuration
    public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginProcessingUrl("/doLogin")
                    .permitAll()
                    .and()
                    .csrf().disable();
        }
    }
}

(1)當配置多個 httpsecurity 時,就不用像前面那樣主方法繼承 WebSecurityConfigurerAdapter,只需要內部的靜態類繼承 WebSecurityConfigurerAdapter 即可

(2)當多個 httpsecurity 時,需要通過 @Order(1) 指定優先順序

二、實現方法安全的控制

1. 編寫配置類

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class MultiHttpSecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("yolo").password("$2a$10$G3kVAJHvmRrr6sOj.j4xpO2Dsxl5EG8rHycPHFWyi9UMIhtdSH15u").roles("admin")
                .and()
                .withUser("nlcs").password("$2a$10$kWjG2GxWhm/2tN2ZBpi7bexXjUneIKFxIAaMYJzY7WcziZLCD4PZS").roles("user");
    }

    @Configuration
    @Order(1)
    public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasAnyRole("admin");
        }
    }

    @Configuration
    public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginProcessingUrl("/doLogin")
                    .permitAll()
                    .and()
                    .csrf().disable();
        }
    }
}

prePostEnabled 表示在方法前進行校驗

2. 編寫 service

@Service
public class MethodService {
    @PreAuthorize("hasRole('admin')")
    public String admin(){
        return "hello admin";
    }
    //有 user 這個角色才可以訪問
    @Secured("ROLE_user")
    public String user(){
        return "hello user";
    }
    @PreAuthorize("hasAnyRole('admin','user')")
    public String hello(){
        return "hello hello";
    }
}

@PreAuthorize("hasRole('admin')") 表示方法訪問前對其進行驗證,是否是 admin 許可權

3. 編寫 controller

@RestController
public class HelloController {

    @Autowired
    MethodService methodService;
    @GetMapping("/admin")
    public String admin() {
        return methodService.admin();
    }
    @GetMapping("/user")
    public String user() {
        return methodService.user();
    }
    @GetMapping("/hello")
    public String hello() {
        return methodService.hello();
    }
}

對於 這三個介面都可以訪問,但是對於介面裡的具體方法,只有具有對應許可權的使用者才可以訪問。

4. 測試

yolo 登入:它具有 admin 許可權,可以訪問 admin 介面及其方法,但是對於 user 方法的訪問則不可以

在這裡插入圖片描述

相關文章