摘要: 原創出處 https://www.cnkirito.moe/spring-security-2/ 「老徐」歡迎轉載,保留摘要,謝謝!html
上一篇文章《Spring Security(一)–Architecture Overview》,咱們介紹了Spring Security的基礎架構,這一節咱們經過Spring官方給出的一個guides例子,來了解Spring Security是如何保護咱們的應用的,以後會對進行一個解讀。前端
1 <dependencies> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-web</artifactId> 5 </dependency> 6 <dependency> 7 <groupId>org.springframework.boot</groupId> 8 <artifactId>spring-boot-starter-security</artifactId> 9 </dependency> 10 <dependency> 11 <groupId>org.springframework.boot</groupId> 12 <artifactId>spring-boot-starter-thymeleaf</artifactId> 13 </dependency> 14 </dependencies>
2.2 建立一個不受安全限制的web應用因爲咱們集成了springboot,因此不須要顯示的引入Spring Security文檔中描述core,config依賴,只須要引入spring-boot-starter-security便可。web
這是一個首頁,不受安全限制spring
src/main/resources/templates/home.html
數據庫
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 3 <head> 4 <title>Spring Security Example</title> 5 </head> 6 <body> 7 <h1>Welcome!</h1> 8 9 <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p> 10 </body> 11 </html>
src/main/resources/templates/hello.html這個簡單的頁面上包含了一個連接,跳轉到」/hello」。對應以下的頁面安全
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Hello World!</title> 6 </head> 7 <body> 8 <h1>Hello world!</h1> 9 </body> 10 </html>
1 @Configuration 2 public class MvcConfig extends WebMvcConfigurerAdapter { 3 4 @Override 5 public void addViewControllers(ViewControllerRegistry registry) { 6 registry.addViewController("/home").setViewName("home"); 7 registry.addViewController("/").setViewName("home"); 8 registry.addViewController("/hello").setViewName("hello"); 9 registry.addViewController("/login").setViewName("login"); 10 } 11 12 }
2.3 配置Spring Security接下來配置Spring MVC,使得咱們可以訪問到頁面。springboot
一個典型的安全配置以下所示:架構
1 @Configuration 2 @EnableWebSecurity <1> 3 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { <1> 4 @Override 5 protected void configure(HttpSecurity http) throws Exception { 6 http <2> 7 .authorizeRequests() 8 .antMatchers("/", "/home").permitAll() 9 .anyRequest().authenticated() 10 .and() 11 .formLogin() 12 .loginPage("/login") 13 .permitAll() 14 .and() 15 .logout() 16 .permitAll(); 17 } 18 19 @Autowired 20 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 21 auth <3> 22 .inMemoryAuthentication() 23 .withUser("admin").password("admin").roles("USER"); 24 } 25 }
<2> configure(HttpSecurity)
定義了哪些URL路徑應該被攔截,如字面意思所描述:」/「, 「/home」容許全部人訪問,」/login」做爲登陸入口,也被容許訪問,而剩下的」/hello」則須要登錄後才能夠訪問。<1> @EnableWebSecurity註解使得SpringMVC集成了Spring Security的web安全支持。另外,WebSecurityConfig配置類同時集成了WebSecurityConfigurerAdapter,重寫了其中的特定方法,用於自定義Spring Security配置。整個Spring Security的工做量,其實都是集中在該配置類,不單單是這個guides,實際項目中也是如此。併發
<3> configureGlobal(AuthenticationManagerBuilder)
在內存中配置一個用戶,admin/admin分別是用戶名和密碼,這個用戶擁有USER角色。app
咱們目前尚未登陸頁面,下面建立登陸頁面:
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Spring Security Example </title> 6 </head> 7 <body> 8 <div th:if="${param.error}"> 9 Invalid username and password. 10 </div> 11 <div th:if="${param.logout}"> 12 You have been logged out. 13 </div> 14 <form th:action="@{/login}" method="post"> 15 <div><label> User Name : <input type="text" name="username"/> </label></div> 16 <div><label> Password: <input type="password" name="password"/> </label></div> 17 <div><input type="submit" value="Sign In"/></div> 18 </form> 19 </body> 20 </html>
最後,咱們爲hello.html添加一些內容,用於展現用戶信息。這個Thymeleaf模板提供了一個用於提交用戶名和密碼的表單,其中name=」username」,name=」password」是默認的表單值,併發送到「/ login」。 在默認配置中,Spring Security提供了一個攔截該請求並驗證用戶的過濾器。 若是驗證失敗,該頁面將重定向到「/ login?error」,並顯示相應的錯誤消息。 當用戶選擇註銷,請求會被髮送到「/ login?logout」。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Hello World!</title> </head> <body> <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> <form th:action="@{/logout}" method="post"> <input type="submit" value="Sign Out"/> </form> </body> </html>
2.4 添加啓動類咱們使用Spring Security以後,HttpServletRequest#getRemoteUser()能夠用來獲取用戶名。 登出請求將被髮送到「/ logout」。 成功註銷後,會將用戶重定向到「/ login?logout」。
@SpringBootApplication public class Application { public static void main(String[] args) throws Throwable { SpringApplication.run(Application.class, args); } }
http://localhost:8080/
:2.5 測試點擊here,嘗試訪問受限的頁面:/hello
,因爲未登陸,結果被強制跳轉到登陸也/login
:
輸入正確的用戶名和密碼以後,跳轉到以前想要訪問的/hello
:
點擊Sign out退出按鈕,訪問:/logout
,回到登陸頁面:
網上百度了一下發現這是由於Spring security 5.0中新增了多種加密方式,也改變了密碼的格式。
要想咱們的項目還可以正常登錄,須要修改一下configure中的代碼。咱們要將前端傳過來的密碼進行某種方式加密,spring security 官方推薦的是使用bcrypt加密方式。那麼如何對密碼加密呢,只須要在configure方法裏面指定一下。
修改後是這樣的:
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //inMemoryAuthentication 從內存中獲取 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("user1").password(new BCryptPasswordEncoder().encode("123456")).roles("USER"); }
在inMemoryAuthentication()後面多了".passwordEncoder(new BCryptPasswordEncoder())",這至關於登錄時用BCrypt加密方式對用戶密碼進行處理。之前的".password("123456")" 變成了 ".password(new BCryptPasswordEncoder().encode("123456"))" ,這至關於對內存中的密碼進行Bcrypt編碼加密。比對時一致,說明密碼正確,容許登錄。
若是你如今用的也是從內存中取密碼,那麼按照上面這麼修改後應該會成功登陸沒有問題的。
若是你用的是在數據庫中存儲用戶名和密碼,那麼通常是要在用戶註冊時就使用BCrypt編碼將用戶密碼加密處理後存儲在數據庫中。而且修改configure()方法,加入".passwordEncoder(new BCryptPasswordEncoder())",保證用戶登陸時使用bcrypt對密碼進行處理再與數據庫中的密碼比對。以下:
//注入userDetailsService的實現類 auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());