一、理论知识部分
SpringSecurity 的官网文档地址:SpringSecurity
这里以24年3月份的 6.2.2 版本为例,记录一下学习过程。
1. SpringSecurity 是基于 Servlet Filters 的,而 Servlet Filters 中的流程如下:首先由客户端 Client 请求,请求后需要通过一个过滤链 FilterChain ,FilterChain 里面会有多个过滤器 Filter。
2. 我们可以自定义 Filter ,用来替代(Proxy) FilterChain 中的某个过滤节点,进而可以自定义一个过滤逻辑,这个逻辑就是 SpringSecurity 中的 SecurityFilterChain
3. SecurityFilterChain 又可以定义多个 SecurityFilter 过滤条件
4. 用户使用账号密码登录时,会携带用户名 username 和密码 password 信息,然后会找到认证管理器 AuthenticationManager 中的一个抽象类 UserDetailsService ,它管理着用户的信息,是认证和授权的地方。重写 UserDetailsService ,可以对客户端传过来的数据 UsernamePasswordAuthenticationToken 和数据库中的 username、password 进行比对,并授予权限 role。
5. 获取到权限后,即可通过授权过滤器 AuthorizationFilter 进行授权判断,比如规定某些页面只能由 ADMIN 权限的账号查看,一些权限只需要被授权了即可查看,及时是 GUEST 游客权限。
二、代码实现部分
1. 在pom.xml中引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2. 配置过滤链 SecurityFilterChian
PasswordEncoder 定义了密码的加密方式
HttpSecurity 创建了认证的规则,如 /admin 页面只能让具有 ADMIN 权限的账号访问。另外也配置登录页面和登出页面。
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/admin").hasRole("ADMIN").anyRequest().authenticated()).formLogin(login -> login.loginPage("/login").defaultSuccessUrl("/").permitAll()).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/login").permitAll());return http.build();}
}
3. 重写认证方法
这里的 userMapper.findUserByUsername 需要自己去关联数据库,返回账号 username,加密的密码 password ,以及权限 role 即可。这里的 User 类不是自定义的,得是 SpringSecurity 中的 User 类。
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@AutowiredUserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {UserEntity user = userMapper.findUserByUsername(username);return new User(user.getUsername(),new BCryptPasswordEncoder().encode(user.getPassword()), AuthorityUtils.createAuthorityList(user.getRole()));}
}
4. 补充好UserEntity、UserService、UserMapper 即可。自定义的页面用 Thymeleaf 编写或前后端分离都可以。
<dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>