前言
和前面的文章隔了很长时间才更新Spring Security系列,主要原因一个是之前太忙了,把项目都忙完了,赶上春节假期,就慢慢研究。Spring Security的体系非常复杂,一口吃不了热豆腐,没办法速成,也不是三两句话就能讲清楚。即使复制别人的配置,但需要稍作修改的时候怎么办?Spring Security看似简洁的配置,其实包含了大量默认配置内容,也存在很多可以扩展的空间。所以首先得会用基本的配置,然后还要窥探源码,了解其内部原理,才能玩转这个框架。
在《Spring Security学习(一)——快速开始》中我们看到即使什么都不配置,Spring Security也会为我们提供一个默认的登录页。所以会有几个疑问:1、我们如何自定义登录页?2、是否有其他登陆方式?
虽然现在Vue+SpringBoot体系下基本不需要配置这个内容,不过作为学习的角度,了解怎么回事还是很有必要的,能看懂很多例子的配置是怎么回事。
我们的代码可以基于《Spring Security学习(一)——快速开始》之上添加,建应用的步骤直接参考前文即可,本文不再赘述。
登陆提交账号密码的三种方式
Spring Security提供了三种提交账号密码给框架的方式。如果我们不用vue,只用thymeleaf做页面的话,就可以使用这个功能。这三种方式为:表单方式、httpBasic方式、摘要方式。
在配置这几种方式前,我们先新建一个Spring Security的配置类WebSecurityConfig:
@EnableWebSecurity
public class WebSecurityConfig{
}
后面Spring Security的相关配置都会在WebSecurityConfig类进行配置
表单方式
表单方式的认证过程,我们通过官网的图稍微说明一下:
上图是表单认证重定向过程的步骤:
- 第一步用户要访问 /private 路径,经过SecurityFilterChain的过滤;
- FilterSecurityInterceptor判断用户未登陆,则抛出异常AccessDeniedException;
- ExceptionTranslationFilter重定向到登录页,这个登录页由AuthenticationEntryPoint配置,通常会以LoginUrlAuthenticationEntryPoint作为其实现;
- 浏览器请求登录页访问;
- 应用返回具体的登录页。
这个过程不复杂,会涉及到一些拦截器、过滤器等。这告诉我们存在哪些扩展空间,当然我们暂时还不需要用到。我们可以看到想要Spring Security要怎么认证,我们就给它配置什么样的SecurityFilterChain就可以了。
默认登录页的配置方式
如果我们仅仅希望使用默认登录页的效果,以下配置就可以了:
@EnableWebSecurity
public class WebSecurityConfig{
@Bean
public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
}
7-8行配置意思是对于任意请求都要进行认证。如果不配置这个的话,Spring Security就不会拦截任何访问。第9行就是配置默认登录页。配置非常简便。
自定义登录页的配置方式
如果我们不想用默认的登录页呢?配置也很简单:
@EnableWebSecurity
public class WebSecurityConfig{
@Bean
public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
);
return http.build();
}
}
仅仅改成10-13行的配置就可以了。当然我们还要写一个自定义的登录页,以及访问登录页的controller。下面在resources/templates下新建loginPage.html登录页:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Please Log In</title>
</head>
<body>
<h1>请登录</h1>
<div th:if="${param.error}">
Invalid username and password.</div>
<div th:if="${param.logout}">
You have been logged out.</div>
<form th:action="@{/login}" method="post">
<div>
<input type="text" name="username" placeholder="Username"/>
</div>
<div>
<input type="password" name="password" placeholder="Password"/>
</div>
<input type="submit" value="Log in" />
</form>
</body>
</html>
我们还要修改一下配置,让应用能找到页面的位置,修改application.yml,增加thymeleaf的路径配置:
spring:
thymeleaf:
prefix: classpath:/templates/
之后建一个controller返回登陆页:
@Controller
public class LoginController {
@GetMapping("/login")
String login() {
return "loginPage";
}
}
启动程序,访问http://localhost:8080/hello会重定向到/login路径返回自定义登录页:
由于我们没配置账号密码,所以使用《Spring Security学习(一)——快速开始》里说的默认账号密码,账号user,密码是应用启动时随机生成的,在控制台可以查看。
httpBasic方式
除了表单方式,也可以用默认的httpBasic方式,在WebSecurityConfig中配置:
@EnableWebSecurity
public class WebSecurityConfig{
@Bean
public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
第10行改成配置为httpBasic方式。然后我们访问http://localhost:8080/hello:
浏览器会弹出登陆框让我们让我们输入账号密码。
摘要方式
这块暂时没有研究,因为Spring Security官方文档一开头就说不建议在现代应用中使用这种安全方案,所以就不作介绍了。
小结
本文主要总结了Spring Security中提交账号的方式,其中自定义登录页可以适用于thymeleaf为前端的轻应用。不过对于使用vue作为前端的应用不需要配置登陆提交方式。后面的文章会继续Spring Security研究其他方面的内容。