系列博文
项目已上传至guthub 传送门
JavaWeb-SpringSecurity初认识 传送门
JavaWeb-SpringSecurity在数据库中查询登陆用户 传送门
JavaWeb-SpringSecurity自定义登陆页面 传送门
JavaWeb-SpringSecurity实现需求-判断请求是否以html结尾 传送门
JavaWeb-SpringSecurity自定义登陆配置 传送门
JavaWeb-SpringSecurity图片验证ImageCode 传送门
JavaWeb-SpringSecurity记住我功能 传送门
JavaWeb-SpringSecurity使用短信验证码登陆 传送门
在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();
}
}
来源:oschina
链接:https://my.oschina.net/u/4361197/blog/3361620