Spring Security中的自动登录

实现原理

  1. 认证成功后通过cookie向浏览器中存入加密字符串,并且向数据库中存入加密字符串和用户信息字符串。
  2. 再次访问获取cookie信息,使用加密字符串到数据库中进行比对,如果查询到对应的信息,认证成功,可以登录。

spring security底层实现

在这里插入图片描述

具体实现

Spring Security中的用户注销的基础上进行修改。
创建数据表

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`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

然后,在配置类中注入数据源,配置操作数据库对象,并且配置自动登录。
SecurityConfig.java

package com.rixin.springsecuritydemo3.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); 启动时创建persistent_logins表
        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/hello").permitAll();

        //配置没有权限访问跳转自定义页面
        http.exceptionHandling().accessDeniedPage("/unauth.html");


        //自定义用户登录页面
        http.formLogin()
                .loginPage("/login.html") //登录页面设置
                .loginProcessingUrl("/user/login") //登录访问路径
                .defaultSuccessUrl("/success.html").permitAll() //登录成功后的跳转路径
                .and().authorizeRequests() //定义哪些url被保护,哪些不被保护
                    .antMatchers("/","/test/hello","/user/login").permitAll() //访问这些路径不需要认证
                    //.antMatchers("/test/index").hasAuthority("admins") //当前登录用户,只有具有admins权限才可以访问这个路径
                    //.antMatchers("/test/index").hasAnyAuthority("admins,manager")
                    //.antMatchers("/test/hello").hasRole("sale")
                    .antMatchers("/test/hello").hasAnyRole("sale")


                .anyRequest().authenticated()
                //
                .and().rememberMe().tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(3600) //设置有效时长,单位秒
                .userDetailsService(userDetailsService) //设置userDetailsService底层来操作数据库


                .and().csrf().disable(); //关闭csrf防护

    }
}

最后在登录页面添加记住我复选框:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/user/login" method="post">
        username:<input type="text" name="username"/>
        password:<input type="password" name="password"/>
        <input type="submit" value="login"/>
        <input type="checkbox" name="remember-me" title="记住我"/>自动登录
    </form>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值