1. 程式人生 > >Java安全——一步步搭建Spring Security環境

Java安全——一步步搭建Spring Security環境

首先,先建立springboot專案(這裡我的版本號採用的是spring boot2.0),選擇引入web和security的依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId
>
<artifactId>spring-boot-starter-web</artifactId> </dependency>

現在,我們建立一個Controller類作為介面進行測試:

@RestController
public class DemoController{
    @GetMapping("/")
    public String home(){
        return "hello hdonghong~";
    }
}

啟動Spring Boot專案後,進行訪問,當頁面自動跳轉到/login下面時說明security的環境已經搭建成功:
這裡寫圖片描述

接下來,我們正式進行Spring Security的配置。
在剛剛建立的Controller類中增加一個介面test:

@GetMapping("/test")
    public String test(){
    return "test authentication";
}

然後建立SpringSecurityConfig類並繼承WebSecurityConfigurerAdapter類,具體實現如下:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override protected void configure(HttpSecurity http) throws Exception{ //允許訪問專案主路徑/的請求 //其它請求都要經過攔截驗證 //同時也允許登出請求 //支援表單驗證登入 //取消掉預設的csrf認證 http.authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and() .logout().permitAll() .and() .formLogin(); http.csrf().disable(); } }

現在啟動專案,繼續訪問http://localhost:8080/會發現可以成功訪問了,而訪問http://localhost:8080/test則會被攔截。因為我們在SpringSecurityConfig類中配置了放行主路徑/的請求和登出請求,而攔截所有其他請求。【這裡省略演示過程】

好了,我們繼續完善配置。Controller類中新增一個介面test2:

//ROLE_是SpringS ecurity要求的許可權字首,參考原始碼:private String defaultRolePrefix = "ROLE_";
//這裡@PreAuthorize註解發生在方法執行前,意思是要求執行此方法要有ADMIN許可權
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/test2")
public String test2(){
    return "admin auth";
}

回到SpringSecurityConfig類中,新增重寫父類的configure方法:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //注意:使用springsecurity5,需要加上{noop}指定使用NoOpPasswordEncoder給DelegatingPasswordEncoder去校驗密碼
    //,同時需要知道NoOpPasswordEncoder已經過時了,這裡僅是為了方便
    auth.inMemoryAuthentication().withUser("admin").password("{noop}admin").roles("ADMIN");
    auth.inMemoryAuthentication().withUser("scott").password("{noop}scott").roles("USER");
}

重新啟動專案,現在訪問http://localhost:8080/test輸入賬號/密碼為admin/admin就可以通過驗證,而其它的如scott使用者則不可以。
【這裡省略演示過程】

到這裡,我們的Spring Security配置還沒有結束,我們繼續進行最後一步。
建立一個MyPasswordEncoder並實現PasswordEncoder介面,具體實現如下:

public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence charSequence){
        BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
        return bCryptEncoder.encode(charSequence);
    }
    @Override
    public boolean matches(CharSequence charSequence,String s) {
        BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
        return bCryptEncoder.matches(charSequence, s);
    }
}

這個是密碼校驗類,我們這裡採用了bCrypt加密演算法(PS:原本打算用MD5的,可是發現似乎Spring Security5沒有了這個MD5的Encode類,在StackOverflow搜尋,由於個人搜尋能力有限,也沒弄明白,懇請知道的大佬解答下)。

現在,我們回到SpringSecurityConfig類中修改configure方法的實現:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //使用自己的密碼校驗類
    auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());
    //資料庫管理方面支援的預設處理
    auth.jdbcAuthentication()
        .usersByUsernameQuery("")
        .authoritiesByUsernameQuery("")
        .passwordEncoder(new MyPasswordEncoder());
}

至此,Spring Security環境搭建完畢,當然一些註解如@PreAuthrize、@PostAuthrize、@PreFilter、@PostFilter等註解的使用方式比較複雜,無關本篇文章的主題,所以我就沒有敘述,不過其簡單使用已經註釋在原始碼中了。-> 獲取原始碼