spring-boot啟用security組件 · 中
三年前,也是這個時間,我還在鄭州學習,那里曾是我IT生涯開始的地方,所以鄭州對我而言,是有著某種特殊情感的,我記得那年夏天也下了很大的雨,路也被淹了,但是暴風雨很快就過去了,所以這一次,我依然相信暴風雨可以很快結束!加油吧!河南!加油吧!鄭州!加油吧,鐵子們!
最后,被困的小伙伴一定要保護好自己,非必要不要出門!
前言
昨天我們分享了spring-boot啟用security組件的一些基礎知識,演示了security的基本配置和簡單用法,雖然也可以應用于實際開發(fā),但還是過于簡單,并不能真正發(fā)揮sercurity的作用,所以今天我們還要繼續(xù)深挖security的其他配置和用法。目前,我計劃花三天時間分享security相關知識點,不過具體還是要看實際情況。
好了,話不多說,我們直接開整。
security
用戶名及密碼配置補充
開始之前,我們先補充一個security組件密碼和用戶名配置的知識點,昨天我們分享了通過配置類整合我們自己的用戶數據,在翻看spring boot相關書籍的時候,我發(fā)現它還有另外一種方式配置用戶名和密碼——配置文件,配置方式也很簡單,就是在我們的application.properties文件中添加如下配置:
spring.security.user.name=myuser
spring.security.user.password=l23456
但是,需要把我們昨天加的配置類和service先注釋掉,否則會有沖突。在我實際測試過程中,我發(fā)現只要實現了UserDetailsService類,加上@service注解(不需要配置類),其實已經相當于自定義了security組件的用戶數據,只是后臺會報錯誤:

所以我們還是需要通過配置類設定加密器,關于用戶名和密碼配置,還有另外一種方式,也是基于配置類的:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("syske").password("123456");
}
這種方式和配置文件的方式差不多一樣,但是配置文件是支持多用戶配置的:
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("syske").password("123456").and()
.withUser("admin").password("admin");
配置登錄頁面和資源權限控制
下面我們分享security的另一個配置組件,這個組件的作用主要是配置頁面和用戶可訪問的資源,我們可以在這個方法下設置用戶登錄頁。
默認配置如下:
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and()
.formLogin().and()
.httpBasic();
}
我們可以根據自己的需要修改配置:
http.authorizeRequests()
//限定 ” /user/welcome ”請求賦予角色 ROLE_USER 或者 ROLE_ADMIN
.antMatchers("/user/welcome").hasAnyRole("USER", "ADMIN")
// 限定 ” /admin/ ”下所有請求權限賦予角色 ROLE_ADMIN
.antMatchers("/admin/**").hasAnyAuthority("ROLE_ADMIN")
// 其他路徑允許簽名后訪問
.anyRequest().permitAll()
// 對于沒有配置權限的其他請求允許匿名訪問
.and().anonymous()
// 使用spring security 默認的登錄頁面
.and().formLogin()
// 啟動 HTTP 基礎驗證
.and().httpBasic();
這里我們簡單介紹下,authorizeRequests()方法的作用是創(chuàng)建權限配置對象,并把配置對象注入spring boot:

其他的配置操作都是基于這個配置對象展開的。
antMatchers的作用是添加地址匹配規(guī)則,支持正則表達式;hasAnyRole一般是和antMatchers成對出現的,它的作用是設定antMatchers的訪問權限,只要具有指定權限,即可訪問前面配置的訪問規(guī)則;hasAnyAuthority和hasAnyRole類似,它也和antMatchers成對出現,所不同的是hasAnyAuthority要指定的是具體的權限and方法 ,它是連接詞,表示可以重新加入新的權限驗證規(guī)則,就相當于把配置對象返回了anyRequest表示上面限定的所有請求,即antMatchers("/user/welcome").hasAnyRole("USER", "ADMIN")這樣的配置permitAll表示對請求(具體看請求類別)無條件允許訪問anonymous表示對請求(具體看請求類別)允許匿名訪問formLogin表示啟用security默認登錄頁,我們也可以設定自己的登錄頁和登錄成功的頁面

httpBasic表示啟用瀏覽器的http基礎驗證
更多配置方法可以參考這張圖片:

測試
我們定義幾個controller測試一下:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("security")
public Object testSecurity(String name) {
return "hello, " + name;
}
}
管理controller
@RestController
@RequestMapping("/admin")
public class AdminController {
@GetMapping("security")
public Object testSecurity(String name) {
return "hello, admin -" + name;
}
}
普通用戶controller
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("security")
public Object testSecurity(String name) {
return "hello, user -" + name;
}
@PostMapping("welcome")
public Object welcome(String name) {
return "welcome, user -" + name;
}
}
然后我們把獲取用戶的數據進行了修改,將用戶進行了偽代碼處理:
private static Map<String, UserDetails> userDetailsMap = Maps.newHashMap();
static {
userDetailsMap.put("admin", new UserInfo("admin", encrypt("admin"), "ADMIN"));
userDetailsMap.put("user", new UserInfo("user", encrypt("123456"), "USER"));
userDetailsMap.put("test", new UserInfo("test", encrypt("test"), "TEST"));
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (userDetailsMap.containsKey(username)) {
return userDetailsMap.get(username);
} else {
throw new UsernameNotFoundException("用戶不存在");
}
}
private static String encrypt(String password) {
return new BCryptPasswordEncoder().encode(password);
}
需要注意的是,.successForwardUrl("/user/welcome")的地址只能是post接口,如果是get接口的話,登錄成功后會報錯:

總結
今天我們主要分享了security組件的另一個配置方法 —— configure(HttpSecurity http),演示了一些簡單的配置,由于時間的問題,能分享的內容確實也比較有限,而且spring boot單個組件內容又比較多,所以目前還找不到更合適的分享方式,不過各位小伙伴也不用太著急,組件完成后我會做一個系統的demo將所有知識點串起來。好了,今天的內容就到這里吧,今天很忙忙,所以內容更新的也有點晚了。

