第二篇 spring security简单实现自动登录

上一篇文章介绍了spring security的简单使用,这一章介绍自动登录的简单实现。

spring security自动登录是通过登录时生成并保存相关加密串,在下次登录失效时再访问时直接从拉取保存的加密串进行自动登录验证来实现,再次访问不需要再显式地进行用户名密码登录。框架中自动登录加密串存储主要基于关系型数据库实现。

目录

一、实现原理

1. 加密串存储

2. 再次访问

二、具体实现

1. 创建数据表

2. 配置WebSecurityConfigurerAdapter

3. 添加自动登录复选框

附录


一、实现原理

1. 加密串存储

在认证成功之后将加密串分别保存到浏览器的cookies中和数据库表中。

2. 再次访问

当再次访问时,获取cookies信息,拿着cookies中的加密串到数据库进行比对,如果比对成功并查询到对应信息,认证成功,可以登录。

* 自动登录过程框架内部已经实现

示意图:

二、具体实现

1. 创建数据表

表结构必须与框架中要求的结构一致。框架中实现了自动建表功能,但是出于安全考虑,系统中配置的数据库账号一般要求不具备建表权限,建议手动建表。

表结构按照JdbcTokenRepositoryImpl建表语句:

2. 配置WebSecurityConfigurerAdapter

基于上一篇配置做拓展。

配置自动登录需要注入数据源和数据库操作对象,在配置中开启remember me自动登录,并设置自动登录Token过期时间和用户权限等用户基本信息来源业务类。

(1)准备(见附录)

(2)注入数据源

    @Autowired
    private DataSource dataSource;

 (3)注入操作数据库对象

    /**
     * 自动登录Token仓储
     * @return PersistentTokenRepository
     */
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        // 自动建表,不建议开启
        // jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

(4)配置自动登录

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ... ...
        // 自动登录
        http.rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(120)
                .userDetailsService(userDetailService);
    }

3. 添加自动登录复选框

在登录页面配置自动登录复选框,框架要求以“remember-me”做name。

    <input type="checkbox" name="remember-me"/>自动登录

(1)查看效果:

登录后Cookies有了remember-me:

 数据库添加了记录:

 自行勾选自动登录后重启系统,重新访问要求登录的页面/接口以验证。

(2)查看勾选前后访问参数区别

不勾选(无remember-me参数): 

勾选(有remember-me参数):

 这可以为后续前后端完全分离项目自动登录提供思路。

附录

基于第一篇配置做拓展。

添加依赖:

    <properties>
        ... ...
        <spring.boot.version>2.2.1.RELEASE</spring.boot.version>
        <druid.version>1.1.10</druid.version>
        <mysql.version>5.1.46</mysql.version>
        <mybatis.version>1.3.2</mybatis.version>
    </properties>

    <dependencies>
        ... ...
        <!-- jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- mysql connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
    </dependencies>

application.yml添加数据源和mybatis配置:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
    username: root
    password: root
    initialSize: 5 #初始化连接大小
    minIdle: 5     #最小连接池数量
    maxActive: 20  #最大连接池数量
    maxWait: 60000 #获取连接时最大等待时间,单位毫秒
    timeBetweenEvictionRunsMillis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    minEvictableIdleTimeMillis: 300000   #配置一个连接在池中最小生存的时间,单位是毫秒
    validationQuery: SELECT 1 from DUAL  #测试连接
    testWhileIdle: true                  #申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性
    testOnBorrow: false                  #获取连接时执行检测,建议关闭,影响性能
    testOnReturn: false                  #归还连接时执行检测,建议关闭,影响性能
    poolPreparedStatements: false        #是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭

    maxPoolPreparedStatementPerConnectionSize: 20 #开启poolPreparedStatements后生效
    filters: stat,wall,slf4j #配置扩展插件,常用的插件有=>stat:监控统计  log4j:日志  wall:防御sql注入
    connectionProperties: 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000' #通过connectProperties属性来打开mergeSql功能;慢SQL记录

mybatis:
  configuration:
    map-underscore-to-camel-case: true  #开启驼峰命名,l_name -> lName
    jdbc-type-for-null: NULL
    lazy-loading-enabled: true
    aggressive-lazy-loading: true
    cache-enabled: true #开启二级缓存
    call-setters-on-nulls: true #map空列不显示问题
  mapper-locations:
  - classpath:mybatis/*.xml

druid连接池:

@Configuration
public class DruidConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    @Bean
    public ServletRegistrationBean<StatViewServlet> statViewServlet() {
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        //设置ip白名单
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        //设置ip黑名单,优先级高于白名单
        servletRegistrationBean.addInitParameter("deny", "192.168.0.19");
        //设置控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "root");
        servletRegistrationBean.addInitParameter("loginPassword", "root");
        //是否可以重置数据
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> statFilter() {
        //创建过滤器
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter());
        //设置过滤器过滤路径
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略过滤的形式
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大迪吃小迪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值