自定义登录页面
1. 创建登录Controller
java
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
}
2. 创建登录页面
编写login.html页面:
sh
<html>
<head>
<meta charset="utf8">
<title>用户登录</title>
</head>
<body>
<h1>登录表单</h1>
<div th:if="${param.error}" style="color:red">
错误的用户名和密码.
</div>
<form action="${ctx.contextPath}/login" method="post">
<div>
<!--name必须为"username"-->
<input type="text" name="username" placeholder="用户名"/>
</div>
<div>
<!--name必须为"password"-->
<input type="password" name="password" placeholder="密码"/>
</div>
<input type="submit" value="登录"/>
</form>
</body>
</html>
3. 配置SecurityFilterChain
java
@Configuration
public class WebSecurityConfig {
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
// 放开登录页面的访问权限
http.formLogin(formLogin -> formLogin.loginPage("/login").permitAll());
// api接口测试时关闭csrf校验
http.csrf((csrf) -> csrf.disable());
return http.build();
}
}
如果不加上permitAll()
,会导致/login路径会被认为是被保护的资源, 然后跳转到/login, 此时又被认为是被保护的资源,出现递归重定向问题,浏览器也会报错提示请求次数过多! 加上
permitAll()
后,运行测试:
4. 自定义用户信息参数
在用户登录页面上,默认的用户名和密码参数分为是username,password, 如果页面传入参数对不上则无法实际做登录逻辑,原因在于UsernamePasswordAuthenticationFilter中默认就是获取username,password名称的参数: 如果是前后端分离项目,登录的用户名密码参数和后端的不一样,而且不能修改,SpringSecurity也提供了解决办法:
java
@Configuration
public class WebSecurityConfig {
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
// 放开登录页面的访问权限
http.formLogin(formLogin -> {
formLogin.loginPage("/login")
.permitAll()
// 自定义请求参数名
.usernameParameter("myUsername")
.passwordParameter("mypoassword");
});
// api接口测试时关闭csrf校验
// http.csrf((csrf) -> csrf.disable());
return http.build();
}
}
如果注释防御csrf攻击的代码,重新运行会发现页面源码中会有csrfToken: