spring-security 实现记住我,免登录 - Persistent Token

时间 2019/1/20 18:17:09 加载中...

介绍

记住我功能,基本 Persistent Token 的实现。

相关文章
spring-security 实现记住我,免登录 - Hash-Based Token

练习

使用IDEA新建Maven项目

修改pom.xml,引入Spring Boot

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.sqber</groupId>
  7. <artifactId>RememberPersitent</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <parent>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-parent</artifactId>
  12. <version>2.0.1.RELEASE</version>
  13. </parent>
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-security</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.thymeleaf.extras</groupId>
  34. <artifactId>thymeleaf-extras-springsecurity4</artifactId>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-jdbc</artifactId>
  39. </dependency>
  40. <dependency>
  41. <groupId>mysql</groupId>
  42. <artifactId>mysql-connector-java</artifactId>
  43. </dependency>
  44. </dependencies>
  45. </project>

创建控制器和视图

我们创建一个简单的 HomeController

  1. package com.sqber.hashbased.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. @Controller
  5. public class HomeController {
  6. @GetMapping("/")
  7. public String home() {
  8. return "home/index";
  9. }
  10. @GetMapping("/login")
  11. public String login() {
  12. return "home/login";
  13. }
  14. }

一个首页,一个登录页

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
  3. xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
  4. <head>
  5. <title>Security with Spring Boot</title>
  6. </head>
  7. <body>
  8. <h1>首页</h1>
  9. </body>
  10. </html>
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <title>登录</title>
  5. </head>
  6. <body>
  7. <div th:if="${param.error}">
  8. <h1 style="color:red">用户名或密码错误</h1>
  9. </div>
  10. <div th:if="${param.logout}">
  11. <h1 style="color:blue">退出登录</h1>
  12. </div>
  13. <form th:action="@{/login}" method="post">
  14. <div>用户名: <input type="text" name="username"/> </div>
  15. <div>密码: <input type="password" name="password"/> </div>
  16. <div>记住我: <input type="checkbox" name="remember-me" /> </div>
  17. <div><input type="submit" value="登录"/></div>
  18. </form>
  19. </body>
  20. </html>

Security 配置

我们只配置一个 user 用户,且密码也为 user

  1. package com.sqber.persitent.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
  10. import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
  11. import javax.sql.DataSource;
  12. @Configuration
  13. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  14. @Autowired
  15. DataSource dataSource;
  16. @Override
  17. protected void configure(HttpSecurity http) throws Exception {
  18. http.authorizeRequests()
  19. .antMatchers("/resources/**")
  20. .permitAll()
  21. .anyRequest()
  22. .authenticated()
  23. .and()
  24. .formLogin()
  25. .loginPage("/login")
  26. .permitAll()
  27. .and()
  28. .rememberMe()
  29. .rememberMeCookieName("remember-me")
  30. .tokenValiditySeconds(24 * 60 * 60) // expired time = 1 day
  31. .tokenRepository(persistentTokenRepository())
  32. .and()
  33. .logout()
  34. .deleteCookies("JSESSIONID")
  35. .permitAll();
  36. }
  37. @Bean
  38. public BCryptPasswordEncoder passwordEncoder() {
  39. return new BCryptPasswordEncoder();
  40. }
  41. @Autowired
  42. public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  43. auth.inMemoryAuthentication().withUser("user").password(new BCryptPasswordEncoder().encode("user")).roles("USER");
  44. }
  45. @Bean
  46. public PersistentTokenRepository persistentTokenRepository() {
  47. JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
  48. tokenRepository.setDataSource(dataSource);
  49. return tokenRepository;
  50. }
  51. }

注意配置 BCryptPasswordEncoder,否则会报错:There is no PasswordEncoder mapped for the id “null”

数据库配置

打开 application.properties 文件,配置 mysql 数据库

  1. spring.datasource.url=jdbc:mysql://localhost:3306/testdb
  2. spring.datasource.username=root
  3. spring.datasource.password=123456

在本地数据库中新增表 persistent_logins

  1. create table persistent_logins (
  2. username varchar(64) not null,
  3. series varchar(64) primary key,
  4. token varchar(64) not null,
  5. last_used timestamp not null
  6. );

查看效果

在浏览器中打开 localhost:8080 ,则会跳转到 login 页面。 输入 user,user 后,并选择 记住我 ,登录。
我们会看到两个 cookie

删除掉 JSESSIONID 这个cookie后,重新刷新,不会跳转到登录页。

数据库表中也多了一条记录。

DEMO下载

完。

扫码分享
版权说明
作者:SQBER
文章来源:http://www.sqber.com/articles/spring-security-remember-me-persistent-token.html
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。