Spring Security - 配置登录页


配置登录页
我们要实现:
- 自定义哪些资源可以访问,哪些资源不可以访问
- 自定义登录页,而不是使用默认的登录页,且登录失败后,有提示信息
- 自定义成功之后的跳转(比如跳转到第一个导航菜单)
登录页和首页不需要登录,其它需要登录
新建一个 security 目录来存放和登录相关的类。
新增 WebSecurityConfig 来重写 WebSecurityConfigurerAdapter 的 configure 方法
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/account/login", "/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
// 修改了 loginPage 后,表单的 action 也需要是这个
// 如果 action 还是 /login ,如何定位问题呢?
// 开启日志,查看日志情况
.loginPage("/account/login")
// failureForward 会将 ? 后面的去掉
//.failureForwardUrl("/account/login?error=ture")
.failureUrl("/account/login?error=true")
.defaultSuccessUrl("/menu/first");
//.defaultSuccessUrl("http://www.baidu.com");
}
}
Spring Security 默认的登录页面是 /login ,登录提交的表单请求的也是 /login,请求是 POST 请求。
我们通过 .loginPage("/account/login")
修改了登录页,同时登录提交的表单也变成了 /account/login
.failureUrl("/account/login?error=true")
意思是登录失败后,还是跳转到 /account/login 页面,不过加了一个 error=true 的参数。
.defaultSuccessUrl("menu/first")
意思是登录成功后,跳转到 menu/first 这个页面
.antMatchers("/account/login", "/").permitAll()
.anyRequest().authenticated()
意思是 account/login 和 / 都不需要登录也可以访问,除此之外,其它的都需要登录。
注意: 登录页要设置允许访问,否则就导致死循环。
访问登录页,登录页没权限访问,所以请去登录,访问登录页,没权限访问,请去登录,就死循环了。
错误:localhost 将您重定向的次数过多。
localhost 将您重定向的次数过多。
尝试清除 Cookie.
ERR_TOO_MANY_REDIRECTS
解决办法:登录页修改为不需要认证也可以访问
登录页
添加 account 控制器,并添加 login 接口和对应的登录页面。
登录页面用到 thymeleaf 相关知识(thymeleaf 的知识单独总结)
页面具体内容如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<form method="post" action="/account/login">
<input type='hidden' name='_csrf' th:value="${_csrf.token}"/>
<div style="color:red;" th:if="${param.error}"
th:text="${session.SPRING_SECURITY_LAST_EXCEPTION.message == 'Bad credentials' ? '用户名或密码错误' : session.SPRING_SECURITY_LAST_EXCEPTION.message}"></div>
用户名:<input type="text" name="username" th:value="*{username}">
密码:<input type="text" name="password" th:value="*{password}">
<button type="submit">登录</button>
</form>
</div>
业务:用户已经登录时,访问登录页,跳转到系统首页
在访问登录页时,判断是否已经登录(且不是匿名登录),如果已经登录,则跳转到导航首页
@GetMapping("/account/login")
public String login() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth.isAuthenticated() && auth.getClass() != AnonymousAuthenticationToken.class) {
return "redirect:/menu/first";
}
return "account/login";
}
测试
访问 /book 页面(之前项目中的一个页面),会跳转到登录页。输入错误的用户名和密码会有正常的错误提示。
*昵称:
*邮箱:
个人站点:
*想说的话: