环境搭建
依赖
<!--spring security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
有了这个依赖之后, Spring Boot的项目就启用了安全的模块, 包括一些基本的页面(如login.html, logout.html等)和一些功能(登录, 注销, 记住我等).
Security的配置类
@EnableWebSecurity //如果没有这个注解, 则该配置类不会被认定为Security的配置类! 继承WebSecurityConfigurerAdapter类.
@Configuration //配置类
public class SecurityConfig extends WebSecurityConfigurerAdapter {}
用户认证与授权
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.and()
.authorizeRequests()
.antMatchers("/").permitAll();
// 开启注销功能
http.logout().logoutSuccessUrl("/");
// 开启"记住我"功能
http.rememberMe();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
auth.inMemoryAuthentication().passwordEncoder(encoder)
.withUser("root").password(encoder.encode("123456")).roles("USER", "ADMIN")
.and()
.withUser("gao").password(encoder.encode("1234")).roles("USER");
}
}
带有HttpSecurity
参数的configure(), 表示将在Web应用中配置一些功能.
-
http.formLogin(): 开启登录功能. 此时如果用户没有登录, 则应用会跳转到登录页面.
-
http.authorizeRequests(): 验证用户的权限. 此处有两种写法:
-
http.authorizeRequests().antMatchers("/").permitAll();
-
http.authorizeRequests(authorizeRequests -> authorizeRequests.antMatchers("/").permitAll());
-
-
http.logout(): 开启用户登出(注销)功能.
-
http.rememberMe(): 开启"记住我"功能. "记住我"的原理是将过期时间写入到cookie中, 从cookie中可以看到一个名为"remember_me"的KV对.
带有AuthoenticationManagerBuilder
参数的configure(), 用于定义用户名, 密码和用户的权限.
- Spring Boot 5.0 需要配置密码的编码器.
- auth.inMemoryAuthentication(): 表示从内存中获取用户名, 密码, 权限等信息. 也就是下面几行代码配置的信息.
- 也可以从数据库中获取信息, 如使用
auth.jdbcAuthentication()
.
我们可以把这些链式函数拆开来看, 可以写作如下形式:
public void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
List list = new ArrayList<>((Collection) AuthorityUtils.createAuthorityList("ROLE_USER"));
User user = new User("jian", "pwd", list);
auth.inMemoryAuthentication().passwordEncoder(encoder).withUser(user);
}
Thymeleaf与Security的整合
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--thymeleaf-security整合包-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
要在html中添加:
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
这个整合包可以直接在thymeleaf中使用一些security的认证.
<div sec:authorize="isAuthenticated()"> <!--如果已登录, 则显示用户名和登出链接-->
<a>Username: <span sec:authentication="name"></span></a>
<a>Role(s): <span sec:authentication="principal.authorities"></span></a>
<a href="#" th:href="@{/logout}">Log out</a>
</div>
<div sec:authorize="!isAuthenticated()"> <!--如果没有登录, 则跳转到登录页面-->
<a href="#" th:href="@{/login}">Log in</a>
</div>
<div sec:authorize="hasRole('ADMIN')"> <!--如果有xx权限, 则显示xx. 这样可以实现一些动态效果.-->
<p>ADMIN</p>
</div>