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等註解的使用方式比較複雜,無關本篇文章的主題,所以我就沒有敘述,不過其簡單使用已經註釋在原始碼中了。-> 獲取原始碼