當你看到這篇文章時,我猜你肯定是碰到令人苦惱的問題了,我希望本文能讓你有所收獲。
本人幾個月前還是 Spring 小白,幾個月走來,看了 Spring,Spring boot,到這次的 Spring Security。
為了避免大家踩坑,本人將入門的經驗傳授給那些和我一樣正在學習 Spring Security 的小白。
我們從官方例子學習起:
1、我們先來創建一個 Spring Boot 的項目 HelloWorld:
我用的開發工具是 eclipse,如果沒裝 STS 的話,請點擊 Help -> Eclipse MarketPlace...
2、點擊 File -> New -> Spring Starter Project。
然后我們根據需要進行選擇,如圖所示:
3、項目創建好后的目錄如圖所示:
4、接下來我們新建一個包,取名為 security.config,再在包下建一個類並使其繼承 WebSecurityConfigurerAdapter。
5、這樣就已經可以生成 jar 啦,我們右鍵項目 Run as -> Maven Build... 然后 Debug,就會在 target 目錄下生成 jar 。
6、右鍵生成的 jar,點擊屬性后會看到它的文件位置,我們在控制台運行它:
java -jar C:\Users\Anonymous\eclipse-workspace\HelloWorld\target\HelloWorld-0.0.1-SNAPSHOT.jar
再在瀏覽器輸入 http://localhost:8080/ 就會出現一個登錄頁面。
用戶名為 user,密碼在控制台可找到: Using generated security password: 254f14b9-a3e4-4dd5-9888-4c46b0c27e3f
輸入進去就會出現如下圖片:
7、讓我們從頭回顧一下,我們干了啥!我們僅僅在 security 包下創建了一個 config 子包。
然后在該子包里創建了一個類並讓它繼承 WebSecurityConfigurerAdapter 類,並在類上加了一個注解 @EnableWebSecurity。
我們打開 HelloWorldApplication 類,可以看到 main() 函數里只一行代碼:
SpringApplication.run(HelloWorldApplication.class, args); 其實這一行代碼的作用總的來說是加載整個項目的意思。
在這個類上方有個 @SpringBootApplication 注解,我們將鼠標放在上面可以看到該注解是由一系列注解組成的。
我們可以把這個類比作一個樹的根,所有其他的配置都需要以它為基礎而展開,所以項目其他的包應該都是它的子包。
8、我們再看看自己創建的類 WebSecurityConfig,這個類的 @EnableWebSecurity 注解會啟用 Web 安全功能。
但是它本身並沒有什么用處,Spring Security 必須配置在一個實現了 WebSecurityConfigurer 的 bean 中,
或者(簡單起見)擴展 WebSecurityConfigurerAdapter。
9、好啦,最基礎的就是這些啦,讓我們來實現一下讓它打印 HelloWorld!
在配置類中我們寫上如下代碼:
package security.config; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // TODO Auto-generated method stub http.authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin().defaultSuccessUrl("/hello"); } }
10、再在控制器類中寫上如下代碼:
package security.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello World"; } }
11、好啦,大功告成,代碼已經可以運行啦。現在我們來了解一下它們。
在 WebSecurityConfig 類中我們重寫了 configure(HttpSecurity http) 方法,這個方法是完成用戶授權的。
還有另外一個 configure(AuthenticationManagerBuilder auth) 方法,這個方法是完成用戶認證的。
暫時我們只了解第一個,第二個我們在(二) 中了解。
以下內容摘自 《Spring Boot2 企業應用實戰》:HttpSecurity 的 authorizeRequests() 方法有多個子節點。
其中每個 matcher 按照它們的聲明順序執行,指定用戶可以訪問的多個 URL 模式。
Ⅰ、antMatchers 使用 Ant 風格匹配路徑。
Ⅱ、regexMatchers 使用正則表達式匹配路徑。
在匹配了請求路徑后,可以針對當前用戶的信息對請求路徑進行安全處理。
方法 | 用途 |
anyRequest | 匹配所有請求路徑 |
access(String) | Spring EL 表達式結果為 true 時可以訪問 |
anonymous() | 匿名可以訪問 |
denyAll() | 用戶不能訪問 |
fullyAuthenticated() | 用戶完全認證可以訪問(非 remember-me 下自動登錄) |
hasAnyAuthority(String...) | 如果有參數,參數表示權限,則其中任何一個權限可以訪問 |
hasAnyRole(String...) | 如果有參數,參數表示角色,則其中任何一個角色可以訪問 |
hasAuthority(String...) | 如果有參數,參數表示權限,則其權限可以訪問 |
hasIpAdress(String...) | 如果有參數,參數表示 IP 地址,如果用戶 IP 和參數匹配,則可以訪問 |
hasRole(String...) | 如果有參數,參數表示角色,則其角色可以訪問 |
permitAll() | 用戶可以任意訪問 |
rememberMe() | 允許通過 remember-me 登錄的用戶訪問 |
authenticated() | 用戶登錄后可訪問 |
12、現在我們讀一下代碼的意思:授權請求的路徑為 "/login" 時,用戶可以任意訪問。
其他匹配所有請求的路徑都需要授權才能訪問。.and() 是再從 http 參數開始。
舉個例子:.and().formLogin() 相當於 http.formLogin()。
formLogin():開始設置登錄操作。defaultSuccessUrl("/hello"): 指定登錄成功后轉向的頁面。
另外還有其他的方法,我們在(二)再了解。控制類中的代碼是常見的代碼,就不說了。
13、代碼寫完了,我們在控制台運行一下,再在瀏覽器輸入:http://localhost:8080/login:
登錄后,就可以看到 Hello World!
14、運行結果如上圖所示,市面上有些書說輸入 http://localhost:8080/ 就會自動跳轉的 login 頁面。
這的確沒錯,但是當我們輸入用戶名密碼后,會進入到 error 頁面。這是為什么呢?
這是因為 "/" (空)請求需要用戶認證,而又沒有設置 "/" (空)請求可以任意訪問,所以跳轉到 login 頁面進行認證。
認證成功后,控制類中並沒有對 "/" 空請求的處理。所以這將導致出現錯誤頁面。
注意這是一個大坑,坑了我好幾天了。
15、最后,上面的例子僅僅是一個簡單的入門例子,我們更常用的是自定義登錄頁面,並且用戶名和密碼都是從數據庫讀取來認證的。
這一部分內容將在(二)中講解。
16、如果這篇文章幫助了你,請給我點個贊哦!方便的話關注一下噠!