Spring Security

簡介

Spring Security是Spring家族中的一個組成框架,具有強大且高度可定製的身份驗證和訪問控制功能,致力於為Java應用程式提供身份的驗證和授權

(先來一個小案例叭)

本人的環境如下

IDEA:2019.3.5

Maven: 3.6.3

JDK: 1.8

1.建立一個Maven專案

2.引入依賴

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-parent</artifactId>
  4. <version>2.0.6.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!--spring boot web-->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-web</artifactId>
  11. </dependency>
  12. <!--Spring Security-->
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-security</artifactId>
  16. </dependency>
  17. </dependencies>

3.建立啟動類

  1. @SpringBootApplication
  2. public class SecurityApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(SecurityApplication.class, args);
  5. }
  6. }

4.寫一個測試方法(Controller層)

  1. @RestController
  2. @RequestMapping("/test")
  3. public class SecurityController {
  4. @RequestMapping("sayHello")
  5. public String sayHello() {
  6. return "Hello Spring Security";
  7. }
  8. }

然後我們就可以啟動我們的小demo啦,啟動的時候輸出控制檯會列印Spring Security的登入密碼(每次啟動都會重新初始化),是由UUID生成的,使用者名稱預設是user,輸入使用者名稱和密碼,登入就成功啦。

5.修改登入的使用者名稱和密碼

在resources目錄下建立一個配置檔案application.properties(application.yml),

  1. # 自定義 spring security使用者名稱和密碼
  2. spring.security.user.name=huang
  3. spring.security.user.password=123456

不想要Spring Security的登入也是可以去掉的(關閉驗證),只要把Security的自動配置去掉就可以啦,在啟動類的@SpringBootApplication註解中新增就好。

  1. @SpringBootApplication(exclude = SecurityAutoConfiguration.class)

6.基於記憶體的使用者資訊

有時候我們的使用者名稱和密碼太多,寫在配置檔案中不好,可以把使用者名稱和密碼儲存到記憶體中進行管理。

1)要寫一個配置類

一個繼承了 WebSecurityConfigurerAdapter抽象類的類,重寫它的 config 方法,在方法裡面新增使用者

  1. //新增為配置類(相當於spring的xml檔案)
  2. @Configuration
  3. //開啟Spring Security功能
  4. @EnableWebSecurity
  5. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  6. @Override
  7. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  8. //加密
  9. PasswordEncoder pe = passwordEncoder();
  10. auth.inMemoryAuthentication()
  11. .withUser("huangxc")
  12. .password(pe.encode("123456"))
  13. .roles();
  14. auth.inMemoryAuthentication()
  15. .withUser("xian")
  16. .password(pe.encode("654321"))
  17. .roles();
  18. auth.inMemoryAuthentication()
  19. .withUser("admin")
  20. .password(pe.encode("admin"))
  21. .roles();
  22. }
  23. }

這樣當我們啟動專案時,就可以使用config方法裡面配置的使用者名稱和密碼了。如果你的Spring Security版本是5(現在只出到5)的話,是會報錯的(java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"),原因是密碼不能使用明文的方式,要進行加密。

配置類中加如下程式碼進行加密就好,PasswordEncoder是一個介面,有很多加密演算法的子類,而 new BCryptPasswordEncoder就是其中一個。

  1. //把方法新增到spring容器中
  2. @Bean
  3. public PasswordEncoder passwordEncoder() {
  4. return new BCryptPasswordEncoder();
  5. }
2)對使用者新增角色

在專案中,一個使用者往往可以具有多個角色的許可權,可以在新增使用者的時候進行設定,在roles方法中新增角色(可以新增多個),我這裡以新增兩個為例。

配置類上面新增一個註解

  1. //開啟方法級別的認證
  2. @EnableGlobalMethodSecurity(prePostEnabled = true)

控制器中寫兩個方法來測試一下

  1. @RequestMapping("commonUser")
  2. //表示這個方法有兩個角色
  3. @PreAuthorize(value = "hasAnyRole('admin','normal')")
  4. public String commonUser() {
  5. return "Hello 只用戶normal角色";
  6. }
  7. @RequestMapping("adminUser")
  8. //表示這個方法只擁有 admin 這個角色
  9. @PreAuthorize(value = "hasAnyRole('admin'")
  10. public String adminUser() {
  11. return "Hello 使用者 admin 和 normal兩個角色";
  12. }

@PreAuthorize:進行方法前的驗證,比如我admin這個使用者去進行登入,兩個方法都可以訪問,如果是 huangxc或者是xian這兩個使用者去訪問,只能訪問commonUser()這個方法(溫馨提示:每次測試的時候記得要輕觸快取)。