Spring Security

一.新建项目

1.导入依赖

Spring Security已经被Spring boot进行集成,使用时直接引入启动器即可。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.访问界面

导入spring-boot-starter-security启动器后,Spring Security已经生效,默认拦截全部请求,如果用户没有登录,跳转到内置登录页面。

在浏览器输入:http://localhost:8080/xxxxx后会显示下面页面

默认的username为user,password打印在控制台中。

3.可以自定义用户名和密码
1
2
spring.security.user.name=smallming
spring.security.user.password=smallming

二.看不到 UsernameNotFoundException 异常

在 Spring Security 中,用户名查找失败对应的异常是:

  • UsernameNotFoundException

密码匹配失败对应的异常是:

  • BadCredentialsException

但是我们在登录失败的回调中,却总是看不到 UsernameNotFoundException 异常,无论用户名还是密码输入错误,抛出的异常都是 BadCredentialsException。

在登录中有一个关键的步骤,就是去加载用户数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
try {
user = retrieveUser(username,
(UsernamePasswordAuthenticationToken) authentication);
}
catch (UsernameNotFoundException notFound) {
logger.debug("User '" + username + "' not found");
if (hideUserNotFoundExceptions) {
thrownew BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials"));
}
else {
throw notFound;
}
}
}

从这段代码中,我们看出,在查找用户时,如果抛出了 UsernameNotFoundException,这个异常会被捕获,捕获之后,如果 hideUserNotFoundExceptions 属性的值为 true,就抛出一个 BadCredentialsException。相当于将 UsernameNotFoundException 异常隐藏了,而默认情况下,hideUserNotFoundExceptions 的值就为 true。

看到这里就明白为什么无论用户还是密码写错,你收到的都是 BadCredentialsException 异常。

一般来说这个配置是不需要修改的。

三.注销操作

1
2
3
4
5
6
7
// 配置退出登录
http.logout()
.invalidateHttpSession(true) // 回收HttpSession对象。退出之前调用HttpSession.invalidate() 默认 true
.clearAuthentication(true) // 退出之前,清空Security记录的用户登录标记。 默认 true
// .addLogoutHandler() // 增加退出处理器。
.logoutSuccessUrl("/toLogin") // 配置退出后,进入的请求地址。 默认是loginPage?logout
.logoutUrl("/logout"); // 配置退出登录的路径地址。和页面请求地址一致即可。

退出成功处理器。

也可以自己进行定义退出成功处理器。只要实现了LogoutSuccessHandler接口。与之前的登录成功处理器和登录失败处理器极其类似。