系列博文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(); } }