系列博文html
項目已上傳至guthub 傳送門java
JavaWeb-SpringSecurity初認識 傳送門git
JavaWeb-SpringSecurity在數據庫中查詢登錄用戶 傳送門github
JavaWeb-SpringSecurity自定義登錄頁面 傳送門web
JavaWeb-SpringSecurity實現需求-判斷請求是否以html結尾 傳送門spring
JavaWeb-SpringSecurity自定義登錄配置 傳送門數據庫
JavaWeb-SpringSecurity圖片驗證ImageCode 傳送門安全
JavaWeb-SpringSecurity記住我功能 傳送門ide
JavaWeb-SpringSecurity使用短信驗證碼登錄 傳送門post
在static文件夾下添加一個login.html,做爲自定義登錄頁面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>Gary登錄頁面</h1> <form action="/loginPage" method="post"> 用戶名: <input type="text" name="username"> <br> 密碼: <input type="password" name="password"> <br> <input type="submit"> </form> </body> </html>
在SecurityConfig.java中的configure()方法中配置表單校驗,添加一個自定義跳轉的頁面路徑/login.html
protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") .and() //請求受權 .authorizeRequests() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated(); }
運行程序,發現頁面進入死循環,提示錯誤頁面包含的重定義過多了
緣由:用戶想要進入咱們自定義的登錄頁面,須要SpringSecurity進行身份認證->但用戶要經過SpringSecurity,就會跳轉到咱們自定義的登錄頁面->用戶進入咱們自定義的登錄頁面,就須要SpringSecurity進行身份認證...
無限死循環了!!!
package com.Gary.GaryRESTful.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; //Web應用安全適配器 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告訴SpringSecurity密碼用什麼加密的 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") .and() //請求受權 .authorizeRequests() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated(); } }
因此咱們在配置SecurityConfig.java中的configure()時,對路徑/login.html進行請求放行
protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") .and() //請求受權 .authorizeRequests() //在訪問咱們的URL時,咱們是不須要省份認證,能夠當即訪問 .antMatchers("/login.html").permitAll() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated(); }
此時,咱們再訪問login.html時,發現就能夠進入到咱們自定義的登錄頁面了
package com.Gary.GaryRESTful.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; //Web應用安全適配器 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告訴SpringSecurity密碼用什麼加密的 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") .and() //請求受權 .authorizeRequests() //在訪問咱們的URL時,咱們是不須要省份認證,能夠當即訪問 .antMatchers("/login.html").permitAll() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated(); } }
此時,咱們在本身的頁面中輸入數據庫中帳號密碼,頁面的攔截器都不會生效
這是由於login.html中表單/loginPage請求路徑攔截器不認識
按住Ctrl+Shift+T,能夠找到SpringSecurity攔截器中UsernamePasswordAuthenticationFilter的方法
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { // ~ Static fields/initializers // ===================================================================================== public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username"; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password"; private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; private boolean postOnly = true; // ~ Constructors // =================================================================================================== public UsernamePasswordAuthenticationFilter() { super(new AntPathRequestMatcher("/login", "POST")); }
如今須要咱們login.html中的表單發送請求訪問SpringSecurity攔截器中的UsernamePasswordAuthenticationFilter()這個方法,處理用戶登錄的請求
(若是要使用UsernamePasswordAuthenticationFilter()這個方法處理用戶登錄,必定須要在配置表單登錄時,添加一個csrf跨站請求僞造的防禦)
protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") //若是URL爲loginPage,則用SpringSecurity中自帶的過濾器去處理該請求 .loginProcessingUrl("/loginPage") .and() //請求受權 .authorizeRequests() //在訪問咱們的URL時,咱們是不須要省份認證,能夠當即訪問 .antMatchers("/login.html").permitAll() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated() //SpringSecurity保護機制 .and().csrf().disable(); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>Gary登錄頁面</h1> <form action="/loginPage" method="post"> 用戶名: <input type="text" name="username"> <br> 密碼: <input type="password" name="password"> <br> <input type="submit"> </form> </body> </html>
package com.Gary.GaryRESTful.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; //Web應用安全適配器 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告訴SpringSecurity密碼用什麼加密的 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } protected void configure(HttpSecurity http) throws Exception{ //表單驗證(身份認證) http.formLogin() //自定義登錄頁面 .loginPage("/login.html") //若是URL爲loginPage,則用SpringSecurity中自帶的過濾器去處理該請求 .loginProcessingUrl("/loginPage") .and() //請求受權 .authorizeRequests() //在訪問咱們的URL時,咱們是不須要省份認證,能夠當即訪問 .antMatchers("/login.html").permitAll() //全部請求都被攔截,跳轉到(/login請求中) .anyRequest() //都須要咱們身份認證 .authenticated() //SpringSecurity保護機制 .and().csrf().disable(); } }