Spring Security-用户注销及记住我

news2025/2/25 2:26:42

用户注销

在配置类增加退出映射地址

 @Override
 protected void configure(HttpSecurity http) throws Exception {
     //退出/注销
     http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/hello").permitAll();
 }

完整代码:

 package com.config;
 ​
 import org.springframework.beans.factory.annotation.Autowired;
 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.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 ​
 @Configuration    //配置类
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         //退出/注销
         http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/hello").permitAll();
 ​
         //配置没有权限访问跳转的页面
         http.exceptionHandling().accessDeniedPage("/403.html");
 ​
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/test/index").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                 //       /user/login","/test/add" 面允许任意访问
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         //.antMatchers("/test/index").hasAnyAuthority("admins","abc")
                         //.antMatchers("/test/index").hasRole("sale")
                         .antMatchers("/test/index").hasAnyRole("sale","p22")
                         .anyRequest().permitAll()
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }

在static下 增加 success.html

 <h1> 登录成功</h1>
 <a href="/logout">退出</a>

修改配置类,登录成功后 跳转到 成功页面success.html

 package com.config;
 ​
 import org.springframework.beans.factory.annotation.Autowired;
 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.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 ​
 @Configuration    //配置类
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         //退出/注销
         http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/add").permitAll();
 ​
         //配置没有权限访问跳转的页面
         http.exceptionHandling().accessDeniedPage("/403.html");
 ​
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/success.html").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                 //       /user/login","/test/add" 面允许任意访问
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         //.antMatchers("/test/index").hasAnyAuthority("admins","abc")
                         //.antMatchers("/test/index").hasRole("sale")
                         .antMatchers("/test/index").hasAnyRole("sale","p22")
                         .anyRequest().permitAll()
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }

在成功页面添加 超链接, 写设置退出路径 

<a href="/logout">退出</a>

登录成功后,在成功页面点击退出 , 再去访问其他contoller不能进行访问

启动测试: 在地址栏输入 http://localhost:8080/login.html 输入正确用户名/密码 ,可以看到 success.html页面内容, 然后再打开一个浏览器窗口 , 在地址栏访问 localhost:8080/test/index

页面显示 hello index

然后 点击 成功页面的 退出 , 实际访问 /test/add

在刷新刚刚 另一个页面 localhost:8080/test/index , 发现 需要登录 ,

记住我 (7天内免登录) 自动登录

security 中实现

img

用户认证成功之后调用RemeberMeService根据用户名名生成Token由TokenRepository写入到数据库,同时也将Token写入到浏览器的Cookie中 重启服务之后,用户再次登入系统会由RememberMeAuthenticationFilter拦截,从Cookie中读取Token信息,与persistent_logins表匹配判断是否使用记住我功能。最中由UserDetailsService查询用户信息

具体实现

1.创建表:


 create table persistent_logins (
     `username` varchar(64) not null, 
     `series` varchar(64) not null, 
     `token` varchar(64) not null, 
     `last_used` timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
         primary key (`series`));
 ​

  1. 修改配置类,注入数据源, 配置操作数据库对象

    配置文件

     spring:
       datasource:
         driver-class-name: com.mysql.cj.jdbc.Driver
         url: jdbc:mysql://localhost:3306/ssm
         username: 自己的用户
         password: 自己的密码

    配置类

 
@Autowired
 private DataSource dataSource;   //注入数据源
 ​
 @Bean
 public PersistentTokenRepository persistentTokenRepository(){
     JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
     jdbcTokenRepository.setDataSource(dataSource);
     //启动时自动创建表  ,因为表已经创建  因此这里注释掉
     //jdbcTokenRepository.setCreateTableOnStartup(true);
     return jdbcTokenRepository;
 }

修改 配置类, 增加 remeberme配置

配置类完整代码

 package com.config;
 ​
 import org.springframework.beans.factory.annotation.Autowired;
 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.core.userdetails.UserDetailsService;
 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;
 ​
 @Configuration    //配置类
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
     @Autowired
     private DataSource dataSource;   //注入数据源
 ​
     //配置数据库对象
     @Bean
     public PersistentTokenRepository persistentTokenRepository(){
         JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
         jdbcTokenRepository.setDataSource(dataSource);
         //启动时自动创建表  ,因为表已经创建  因此这里注释掉
         //jdbcTokenRepository.setCreateTableOnStartup(true);
         return jdbcTokenRepository;
     }
 ​
 ​
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         //退出/注销
         http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/add").permitAll();
 ​
         //配置没有权限访问跳转的页面
         http.exceptionHandling().accessDeniedPage("/403.html");
 ​
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/success.html").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                 //       /user/login","/test/add" 面允许任意访问
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         //.antMatchers("/test/index").hasAnyAuthority("admins","abc")
                         //.antMatchers("/test/index").hasRole("sale")
                         .antMatchers("/test/index").hasAnyRole("sale","p22")
                         .anyRequest().permitAll()
                          //   记住我 设置
                          .and().rememberMe().tokenRepository(persistentTokenRepository())
                           // 设置有效时长 单位 秒
                           .tokenValiditySeconds(60)
                          .userDetailsService(userDetailsService)
             
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }

3.在登录页面 增加复选框

登陆页面添加记住我复选款(name必须是remember-me)

修改 static 下的 login.html

 <form action="/user/login" method="post">
     <input type="text" name="username" placeholder="输入用户名"/><br/>
     <input type="password" name="password" placeholder="输入密码"/><br/>
     <input type="checkbox" name="remember-me"/> 自动登录<br/>
     <input type="submit" value="注册"/>
 </form>

启动 测试

进入登录页面: http:/localhost:8080/login.html ,输入正常的用户名及密码

等时间差不过 到点 后 ,关闭浏览器, 在访问登录成功页面 ,直接跳转到 登录页面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1391426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MSVS C# Matlab的混合编程系列1 - 看似简单的问题引出

前言&#xff1a; 问题提出&#xff0c;如何把Matlab(本文简称MT)的算法集成到Visual Studio(本文简称VS)里面运行&#xff1f; 本文&#xff0c;通过编制一个MT中最简单的加法函数&#xff0c;我们把他做成 MSVS C#能够使用的动态库&#xff0c;说明了MSVS C# 和 MT集成的最…

TCP连接TIME_WAIT

TCP断开过程: TIME_WAIT的作用: TIME_WAIT状态存在的理由&#xff1a; 1&#xff09;可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时&#xff0c;最后的ACK是由主动关闭端发出的&#xff0c;如果这个最终的ACK丢失&#xff0c;服务器将重发最终的FIN&#xf…

超竞化更全能 ROG游戏手机8系列新品正式发布

超竞化更全能 ROG游戏手机8系列新品正式发布 北京时间1月16日晚19:00&#xff0c;ROG 2024新品发布会正式召开&#xff0c;并推出多款新品装备。其中&#xff0c;全新的ROG游戏手机8系列正式发布。该系列产品以“超竞化&#xff0c;更全能”的态度将硬核游戏与日常使用完美结合…

Configure Virtual Serial Port Driver串口模拟器VSPD

背景 串口通讯想必做硬件开发和软件的人来说都相当了解&#xff0c;以前的电脑&#xff0c;基本标配都包含一个串口。但现在的电脑&#xff0c;基本都没有配置串口了&#xff0c;如果要使用串口的功能&#xff0c;基本就要用一个USB转串口的硬件模块。 虚拟串口&#xff08;虚…

P9852 [ICPC2021 Nanjing R] Windblume Festival 题解(SPJ)

[ICPC2021 Nanjing R] Windblume Festival 单击此处下载原神 题面翻译 给一个长度为 n n n 环形整数序列 a a a, 每次操作可以任意选择一个下标 x x x&#xff0c;令 $ a_x a_x - a_{(x\bmod n)1}$&#xff0c;之后移除 a ( x m o d n ) 1 a_{(x\bmod n)1} a(xmodn)1​…

深度学习引领信息检索革新:从传统方法到神经网络信息检索的探索

目录 前言1 信息检索背景概述1.1 信息检索基本任务1.2 信息检索是NLU典型应用 2 信息检索任务定义2.1 检索阶段2.2 排序阶段2.3 关键技术和算法 3 评价指标3.1 MRR&#xff08;平均倒数排名&#xff09;3.2 MAP&#xff08;平均精度均值&#xff09;3.3 NDCG&#xff08;归一化…

Qt应用开发(安卓篇)——Linux下Qt15.5.2配置Android

目录 一、前言 二、Qt安装 三&#xff1a;JDK安装 四&#xff1a;安装SDK&#xff0c;NDK 五、其他事项 六、新建项目 一、前言 看网上教程&#xff0c;多数是windows环境下的&#xff0c;配置也很简单&#xff0c;想不到自己配置的时候却遇到很多问题&#xff0c;传了一…

如何保证新加入的依赖版本与当前项目的其他相关依赖版本兼容?或者如何确保依赖版本升级后适合当前项目?或者如何保证新引入的依赖版本适合当前项目?

如何保证新加入的依赖版本与当前项目的其他相关依赖版本兼容&#xff1f;或者如何确保依赖版本升级后适合当前项目&#xff1f;或者如何保证新引入的依赖版本适合当前项目&#xff1f; 如题&#xff0c;可通过maven仓库找出各个版本之间的对应关系举例 如题&#xff0c;可通过m…

哈希(包含闭散列和开散列实现)

STL提供了两种关联式容器——树型和哈希关联式容器&#xff0c;本章就是关于哈希关联式容器的介绍。 unordered_map unordered_map介绍 unordered_map是一种储存键值对(key,value)的关联式容器&#xff0c;能够通过key快速索引到其对应的value容器中&#xff0c;key值用于唯…

系统性学习vue-vuex

系统性学习vue-vuex 理解vuexvuex工作原理搭建vuex环境案例Vuex的开发者工具使用getters配置项mapState与mapGettersmapActions和mapMutationsvuex模块化namespace 理解vuex 概念&#xff1a; 专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xf…

黄金t+d与黄金期货交易的区别

在金融投资领域中&#xff0c;黄金是一种重要的避险工具和财富保值增值手段。对于投资者来说&#xff0c;了解并熟悉不同的黄金交易方式是至关重要的。其中&#xff0c;黄金TD和黄金期货交易是两种常见的黄金交易形式。那么&#xff0c;它们之间具体有哪些区别呢&#xff1f; 了…

WebGL中开发VR(虚拟现实)应用

WebGL&#xff08;Web Graphics Library&#xff09;是一种用于在浏览器中渲染交互式3D和2D图形的JavaScript API。要在WebGL中开发VR&#xff08;虚拟现实&#xff09;应用程序&#xff0c;您可以遵循以下一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&a…

OpenJDK 和 OracleJDK 哪个jdk更好更稳定,正式项目用哪个呢?关注者

OpenJDK 和 OracleJDK&#xff1a;哪个JDK更好更稳定&#xff0c;正式项目应该使用哪个呢&#xff1f;我会从&#xff0c;从开源性质、更新和支持、功能差异等方面进行比较&#xff0c;如何选择&#xff0c;哪个jdk更好更稳定&#xff0c;正式项目用哪个呢&#xff0c;进行比较…

select子句简单查询

Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 目录 数据查询 起别名 连接 ​编辑 去重 ​编辑 另外补充几个不常用的命令 如果要进行查询,那么需要使用数据操纵语言&#xff08;Data Manipulation Language&#xff0c;DML&am…

yum仓库详解(命令+搭建)

目录 一、初步了解yum 1、yum简介 2、yum实现过程 二、yum配置文件及命令 1、 yum配置文件 1.1 主配置文件 1.2 仓库设置文件 1.3 日志文件 2、yum命令详解 三、搭建仓库的方法 1、搭建本地yum仓库 2、搭建阿里云仓库&#xff08;http方式外网环境&#xff09; 3、f…

搜索经典题——填充 9*9矩阵

题目&#xff1a;给定一个九行九列矩阵&#xff0c;填充矩阵元素&#xff0c;要求&#xff1a; 1、每一行每一列&#xff0c;每个小九宫格&#xff08;图片画粗的地方就是&#xff09;不能包含相同元素 2、每一行&#xff0c;每一列&#xff0c;每个小九宫格均会完整出现1-9的数…

pycharm学生认证免费使用专业版

进入pycharm官网Monthly and yearly plans with JetBrains Toolboxhttps://www.jetbrains.com/store/?fromMenu#discounts ​​​ 按照要求填写&#xff0c;但是如果遇到这个提示&#xff0c;恭喜你&#xff0c;你的学校获得了美国商务部认证。 ​ 遇到这个不要慌&#…

Spring Boot - Application Events 的发布顺序_ApplicationStartingEvent

文章目录 概述Code源码分析 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#xff0c;使得应用程序中的不同组件可以独立地改变和复用逻辑&#xff0c;而无需直接进行通信。 …

残差网络 ResNet

目录 1.1 ResNet 2.代码实现 1.1 ResNet 如上图函数的大小代表函数的复杂程度&#xff0c;星星代表最优解&#xff0c;可见加了更多层之后的预测比小模型的预测离真实最优解更远了&#xff0c; ResNet做的事情就是使得模型加深一定会使效果变好而不是变差。 2.代码实现 impo…

java版微信小程序商城 免 费 搭 建 java版直播商城平台规划及常见的营销模式有哪些?电商源码/小程序/三级分销

涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …