Spring Security 自动登录源码分析

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 依旧能访问
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

响彻天堂丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值