spring security 自动登录 --- 心得
1.前言
仍然是使用cookie存储登录数据,但是存储的数据 由 spring security自动创建 ,当登出后自动删除cookie,
如果不登出也仍在生命周期内,关闭浏览器再打开将会自动登录,无需手动再登录。
2.操作
需要在设置有spring security 的spring boot 工程基础上【详细可查看我的其他随笔,有详细记载,具体操作这里不解释】加上下面配置
(1)
security 配置里有两种写法 【但是只能选择一种】
方法一: 使用注解风格的Java配置

完整的security配置
package com.example.security5500.securityConfig; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component; //这个加不加无所谓
@Configuration
//开启security自定义配置
@EnableWebSecurity
//开启 Controller层的访问方法权限,与注解@PreAuthorize("hasRole('ROLE_admin')")配合,会拦截注解了@PreAuthrize注解的配置
// 想要@PreAuthorize正确执行 ,权限关键字必须带前缀 ROLE_ ,后面的部分可以随便写!!!!靠,琢磨了4小时了 ,终于找到原因了
@EnableGlobalMethodSecurity(prePostEnabled = true)
//, securedEnabled = true
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { //实例自定义登录校验接口 【内部有 数据库查询】
@Autowired
private DbUserDetailsService dbUserDetailsService; // @Bean
// @Override
// protected AuthenticationManager authenticationManager() throws Exception {
// return super.authenticationManager();
// } //忽略拦截的静态文件路径
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(
"/js/**",
"/css/**",
"/img/**",
"/webjars/**");
} //拦截规则设置
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//允许基于使用HttpServletRequest限制访问
//即授权请求设置
.authorizeRequests()
//设置不拦截页面,可直接通过,路径访问 "/", "/index", 则不拦截,
.antMatchers("/", "/index", "/hhk/**")
//是允许所有的意思
.permitAll()
// //访问 /hai 需要admin权限 ,无权限则提示 403
// .antMatchers("/hai").hasAuthority("admin")
// //访问 /kk 需要admin或user权限 ,无权限则提示 403
// .antMatchers("/kk").hasAnyAuthority("admin", "user")
// //路径/admin/**所有的请求都需要admin权限 ,无权限则提示 403
// .antMatchers("/admin/**").hasAuthority("admin")
//其他页面都要拦截,【需要在最后设置这个】
.anyRequest().authenticated()
.and()
//设置自定义登录页面
//即开启登录设置
.formLogin()
//指定自定义登录页面的访问虚拟路径
.loginPage("/login")
.permitAll()
.and()
// 添加退出登录支持。当使用WebSecurityConfigurerAdapter时,这将自动应用。默认情况是,访问URL”/ logout”,使HTTP Session无效
// 来清除用户,清除已配置的任何#rememberMe()身份验证,清除SecurityContextHolder,然后重定向到”/login?success”
//即开启登出设置
.logout()
// //指定的登出操作的虚拟路径,需要以post方式请求这个 http://localhost:5500/mylogout 才可以登出 ,也可以直接清除用户认证信息达到登出目的
// .logoutUrl("/mylogout")
//使httpsession失效
.invalidateHttpSession(true)
//清除认证信息
.clearAuthentication(true)
//登出请求匹配器,新建一个蚂蚁路径请求匹配器 ,与 .logoutUrl("/mylogout")效果一样
.logoutRequestMatcher(new AntPathRequestMatcher("/mylogout"))
//登出成功后访问的地址
.logoutSuccessUrl("/home")
.permitAll()
.and()
//开启记住我设置,用于自动登录
.rememberMe()
//密钥
.key("unique-and-secret")
//存在cookie的用户名[用于cookie名]
.rememberMeCookieName("remember-me-cookie-name")
//生命周期,单位毫秒
.tokenValiditySeconds(24 * 60 * 60);
//登陆后"选择记住我" ,会生成cookie ,登出则会自动删除该cookie , 只要不登出且未超出生命周期 ,那么关闭浏览器后再次访问将自动登录
// [name] [value] [domain] [path] [expires/max-age] [size] [httponly] [priority]
//remember-me-cookie-name eGk6MTU5MTIwODAzNDk5MTozZWUyN2FlMmEwMWQxNDczMDhhY2ZkYTAxZWQ5ZWQ5YQ localhost / 2020-06-03T18:13:54.992Z 89 ✓ Medium } /**
* 添加 UserDetailsService, 实现自定义登录校验,数据库查询
*/
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
//注入用户信息,每次登录都会来这查询一次信息,因此不建议每次都向mysql查询,应该使用redis
//密码加密
builder.userDetailsService(dbUserDetailsService);
// .passwordEncoder(passwordEncoder());
} /**
* BCryptPasswordEncoder相关知识:
* 用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。
* 特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。
* BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
} // /**
// * 选择加密方式 ,密码不加密的时候选择 NoOpPasswordEncoder,不可缺少,否则报错
// * java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
// */
// @Bean
// public static PasswordEncoder passwordEncoder() {
// return NoOpPasswordEncoder.getInstance();
// } }
方法二: xml风格


xml源码
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <http>
<!--设置不拦截的路径-->
<!-- 登录路径-->
<intercept-url pattern="/login" access="permitAll()"/>
<!-- 静态文件路径-->
<intercept-url pattern="/js/**" access="permitAll()"/>
<intercept-url pattern="/css/**" access="permitAll()"/>
<intercept-url pattern="/img/**" access="permitAll()"/>
<intercept-url pattern="/webjars/**" access="permitAll()"/>
<!-- 设置路径需要的指定权限 -->
<intercept-url pattern="/hai" access="hasAuthority('admin')"/> <!-- 其他路径都需要拦截认证-->
<intercept-url pattern="/**" access="isAuthenticated()"/>
<!--Spring Security 4.0以后默认开启宽展请求伪造保护,这里配置禁用,不安全的操作。-->
<csrf disabled="true"/> <!-- 表单登录指定路径-->
<form-login
login-page="/login"/>
<!-- 登出操作-->
<!-- 分别是清除session , 指定登出路径 ,指定登出成功后路径-->
<logout
invalidate-session="true"
logout-url="/logout"
logout-success-url="/login?logout"/>
<!-- 记住我[自动登录]设置 -->
<!-- 三个参数分别是 密钥 ,存在cookie的用户名[用于cookie名] ,存放的生命周期[单位毫秒] -->
<remember-me
key="unique-and-secret"
remember-me-cookie="remember-me-cookie-name"
token-validity-seconds="86400"/>
</http> <!-- //在内存中进行注册公开内存的身份验证信息
// // 在内存中添加 用户名 ,密码 , 权限-->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user"
password="password"
authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager> </beans:beans>
需要在启动类导入xml文件
package com.example.security5500; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; @SpringBootApplication
//设置mapper接口包位置
@MapperScan(basePackages = "com.example.security5500.dao")
//
// 当使用xml的方式配置时,开启此注解,将会注释掉WebSecurityConfig文件配置,该xml功能有同等效果
// @ImportResource("classpath:security/spring-security-config.xml")
public class Security5500Application { public static void main(String[] args) {
SpringApplication.run(Security5500Application.class, args);
} }
使用xml 则不可以使用 注解 @EnableWebSecurity ,会导致失效
(2)在前端的自定义login.html 表单里添加“记住我”的单选框标签 ,name属性不可更改

完整源码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security自定义</title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<!-- 表单的name属性不可变 -->
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div class="form-group">
<label>
<input id="remember-me"
name="remember-me"
type="checkbox"/> 记住我
</label>
</div>
<div><input type="submit" value="Sign In"/></div>
</form> <hr>
<br>
lalallalalal但是开发建设士大夫立刻
</body>
</html>
3.测试
(1)启动 ,进入登录页面

(2)勾选记住我登录 ,此时cookie只有一个jsession数据


登陆后查看cookie ,多了个cookie数据

(2)关闭浏览器再打开该网址 ,会发现可直接进入,不需要手动输入账户密码登录
(3)登出后,查看cookie ,会发现cookie数据没有了,只剩下jsession

spring security 自动登录 --- 心得的更多相关文章
- Spring Security 自定义登录认证(二)
一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Se ...
- spring security简单登录的认证
一.思路 1.先导入相关配置(使用spring security校验之后,登录拦截的配置) 2.创建一个 WebSecurityConfig 继承 WebSecurityConfigurerAdapt ...
- Spring Security 基础登录实例
1 新建Java Web项目 导入Jar: 2 修改web.xml <?xml version="1.0" encoding="UTF-8"?> & ...
- (二)spring Security 自定义登录页面与校验用户
文章目录 配置 security 配置下 MVC 自定义登录页面 自定义一个登陆成功欢迎页面 效果图 小结: 使用 Spring Boot 的快速创建项目功能,勾选上本篇博客需要的功能:web,sec ...
- Spring Boot整合Spring Security自定义登录实战
本文主要介绍在Spring Boot中整合Spring Security,对于Spring Boot配置及使用不做过多介绍,还不了解的同学可以先学习下Spring Boot. 本demo所用Sprin ...
- springboot中使用spring security,登录url就出现403错误
参考链接:https://segmentfault.com/q/1010000012743613 有两个controller,一个是所有用户可以访问的@RequestMapping("use ...
- Spring Security在登录验证中增加额外数据(如验证码)
在使用Spring Security框架过程中,经常会有这样的需求,即在登录验证时,附带增加额外的数据,如验证码.用户类型等.下面将介绍如何实现. 注:我的工程是在Spring Boot框架基础上的, ...
- Spring Security 自定义登录页面
SpringMVC + Spring Security,自定义登录页面登录验证 学习参考:http://www.mkyong.com/spring-security/spring-security-f ...
- springboot集成spring security实现登录和注销
文章目录 一.导入坐标 二.Users实体类及其数据库表的创建 三.controller,service,mapper层的实现 四.核心–编写配置文件 五.页面的实现 运行结果 一.导入坐标 < ...
随机推荐
- 详解 java 异常
Throwable 可以用来表示任何可以作为异常抛出的类(注意,是类不是接口),分为两种: Error(注意!error也是可以throw的,但是不建议) 和 Exception. 其中 Error ...
- Mysql配置文件 客户端
[client] #默认链接的端口 port=3306 #默认链接的socket的位置 socket=/var/lib/mysql.sock #默认编码格式 default-character-set ...
- Jenkins优化
目录 一.修改 JVM 的内存配置 二.修改jenkins 主目录 一.修改 JVM 的内存配置 Jenkins 启动方式有两种方式,一种是以 Jdk Jar 方式运行,一种是将 War 包放在 To ...
- EmmyLua 注解功能
前言 网上配置 EmmyLua 的方法很多,此处就不做赘述(因此前提是你已经安装配置完EmmyLua) 本文仅是对 EmmyLua插件 内 注解功能 用法的代码演示.因为网上大部分EmmyLua配置教 ...
- IDE Goland DEBUG报错(could not launch process: decoding dwarf section info at offset 0x0: too short)
背景: 在升级GO版本到1.11后发现Goland的Debug报错,如下:could not launch process: decoding dwarf section info at offset ...
- flutter 学习笔记
常用属性 container 填充padding,边距margins,边框borders,背景色color, decoration: 渐变gradient-Alignment(x,y),圆角borde ...
- Linux启动、停止宝塔
启动 /etc/init.d/bt start 停止 /etc/init.d/bt stop
- js控制滚动条在最底部位置
window.scrollTo(0, document.body.scrollHeight) 如果需要始终保持在最底部,可以循环调用该方法 如果是div的 /*滚动条到地步*/ function to ...
- JAVA使用LocalDate获取当前日期所在季度的开始日期和结束日期
需要使用jdk1.8及以上 /** * 获取当前日期所在季度的开始日期和结束日期 * 季度一年四季, 第一季度:1月-3月, 第二季度:4月-6月, 第三季度:7月-9月, 第四季度:10月-12月 ...
- 【LeetCode】1085. Sum of Digits in the Minimum Number 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...