1 RememberMeServices 源码解析
描述: 实现自动登录核心类。查看UsernamePasswordAuthenticationFilter(认证)过滤器。
描述: RememberMeServices 会创建token并且会存入cookie中。
描述: 创建token有两种方式,基于内存,基于数据库、这里看基于数据库。
描述: JdbcTokenRepositoryImpl该类封装了很多sql语句,用于操作token。第一条比较重要,建表语句。
CREATE TABLE persistent_logins (
username VARCHAR ( 64 ) NOT NULL,
series VARCHAR ( 64 ) PRIMARY KEY,
token VARCHAR ( 64 ) NOT NULL,
last_used TIMESTAMP NOT NULL
)
总结: RememberMeServices 自动登录流程:
(1) 认证成功
(2) 创建token,写入cookie,存入数据库。
(3) 带着有效cookie访问接口时,RememberMeAuthenticationFilter会通过cookie获取到用户信息,进而进行放行。
2 代码实现
2.1 配置文件修改
描述: 配置PersistentTokenRepository
描述: 配置remember
package com.rosh.security.config;
import com.rosh.security.service.RoshUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;
/**
* @Description: Spring Security 自定义配置类
* @Author: rosh
* @Date: 2021/4/13 21:16
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 用户自定义认证
*/
@Autowired
@Qualifier("roshUserDetailService")
private RoshUserDetailService roshUserDetailService;
/**
* 数据源
*/
@Autowired
private DataSource dataSource;
/**
* 配置JdbcTokenRepositoryImpl
*/
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
return jdbcTokenRepository;
}
/**
* 配置登录用户名、密码及角色
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(roshUserDetailService).passwordEncoder(passwordEncoder());
}
/**
* 配置加密方式,官方推荐加密方式为BCrypt
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 自定义页面配置、登录访问配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout().logoutUrl("/logout").logoutSuccessUrl("/user/logout").permitAll();
http.exceptionHandling().accessDeniedPage("/unauth.html");
http.formLogin()
//配置登录页面
.loginPage("/login.html")
//登录访问路径
.loginProcessingUrl("/user/login").permitAll()
//登录成功访问接口
.defaultSuccessUrl("/success.html")
//登录失败访问的接口
.failureForwardUrl("/user/login/failed")
//配置url访问权限,登录url可以直接访问,不需要认证
.and().authorizeRequests().antMatchers("/login.html", "/user/login/failed").permitAll()
//当前用户必须有admin角色才能访问
.antMatchers("/admin/*").hasRole("admin")
//当前主体拥有admin、customer角色才能访问
.antMatchers("/customer/*").hasAnyRole("admin", "customer")
//其余url需要认证才能访问
.anyRequest().authenticated()
/**
* remember 设置 ,token有效时间为3天
*/
.and().rememberMe().tokenRepository(persistentTokenRepository()).tokenValiditySeconds(60 * 60 * 24 * 3).userDetailsService(roshUserDetailService)
//关闭csrf
.and().csrf().disable();
}
}
2.2 登录页面
描述: name必须是remember-me
2.3 测试
访问接口:http://localhost:8888/admin/hello
退出浏览器,继续访问当前接口http://localhost:8888/admin/hello 依旧能访问
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15081.html