项目地址:https://gitee.com/xxxiaowu/springsecurity-mybatis
*记住我功能在网站上是比较常见的功能,它大致就是我们在勾选了记住我这个按钮,在多长时间之内,用户不需要登陆就可以访问资源。
这个功能在SpringSecurit 里边大致就是,我们点击记住我之后,Spring Security会生成一个token标识,然后将该token标识持久化到数据库,并且生成一个与该token相对应的cookie返回给浏览器。当用户过段时间再次访问系统时,如果该cookie没有过期,Spring Security便会根据cookie包含的信息从数据库中获取相应的token信息,然后帮用户自动完成登录操作
在application.yaml中配置数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/security?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
导入相关的依赖
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入jdbc驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--导入mybatis-spring-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--springboot-security安全-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后在SecurityConfig中配置token持久化对象
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private UserService userService;
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
jdbcTokenRepository.setCreateTableOnStartup(false);//false是我们自己手动配置
return jdbcTokenRepository;
}
...............
}
PersistentTokenRepository为一个接口类,这里我们用的是数据库持久化,所以实例用的是PersistentTokenRepository的实现类JdbcTokenRepositoryImpl。
JdbcTokenRepositoryImpl需要指定数据源,所以我们将配置好的数据源对象DataSource注入进来并配置到JdbcTokenRepositoryImpl的dataSource属性中。createTableOnStartup属性用于是否启动项目时创建保存token信息的数据表,这里设置为false,我们自己手动创建。
通过查看JdbcTokenRepositoryImpl,我们会发现它需要创建一个数据库,用来存储这些信息
创建数据库的sql语句如下
CREATE TABLE persistent_logins (
username VARCHAR (64) NOT NULL,
series VARCHAR (64) PRIMARY KEY,
token VARCHAR (64) NOT NULL,
last_used TIMESTAMP NOT NULL
);
配置登录页面
这里的name属性,默认要设置成remember-me
的,如果设置成其它的,需要在SecurityConfig中进行设置
<div class="field">
<input type="checkbox" name="remember"> 记住我
</div>
在SecurityConfig中开启记住我功能
//添加页面权限
@Override
protected void configure(HttpSecurity http) throws Exception {
//请求授权的规则
http.authorizeRequests()
//首页所有人都能访问
.antMatchers("/")
.permitAll()
//权限为vip1的用户只能访问level1下的所有页面
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3")
//没有权限返回登录页面,测试url请求的是/login ,我们自定义了登录页面请求的url为 toLogin
.and().
formLogin().
loginPage("/toLogin")
//开启注销功能 ,注销成功后跳转带主页
.and().
logout().
logoutSuccessUrl("/")
//开启网站的记住我功能,默认保存时间是14天 rememberMeParameter 默认是,remember-me
.and()
.rememberMe()
.rememberMeParameter("remember")
.tokenRepository(persistentTokenRepository()) //配置token的持久化仓库
.tokenValiditySeconds(90)//配置记住我的时间,以秒为单位
.userDetailsService(userService) //业务处理的逻辑
//防止网站攻击:解决注销是出现404页面,也可以采用post的方式注销页面
.and()
.csrf()
.disable();
}
这样成功了