登录实现记住我功能

文章目录

  • 原理
  • 实现
    • 登录页面添加记住我checkbox
    • BrowserSecurityConfig 中初始化 PersistentTokenRepository
    • BrowserProperties 加入记住时间属性
    • BrowserSecurityConfig configure配置
    • 上一节的错误 启动报错
    • 测试

原理

登录实现记住我功能_第1张图片
登录实现记住我功能_第2张图片

实现

登录页面添加记住我checkbox

登录实现记住我功能_第3张图片

        
            记住我
        

注意 name=“remember-me” 是固定的

BrowserSecurityConfig 中初始化 PersistentTokenRepository

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

································
    @Autowired
    private DataSource dataSource;
······························
    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        //tokenRepository.setCreateTableOnStartup(true);
        //启动时建立这张表persistent_logins,也可以吧创建表语句拿去手动执行
        //只能执行一次,第二次需要关掉,否则报错MySQLSyntaxErrorException: Table 'persistent_logins' already exists
        return tokenRepository;
    }
    ································

其中DataSource为demo application中配置的数据源

登录实现记住我功能_第4张图片

BrowserProperties 加入记住时间属性

public class  BrowserProperties {
    ·····················
	private int rememberMeSecodes = 3600;//秒
	························

BrowserSecurityConfig configure配置

首先引入UserDetailsService

    @Qualifier("myUserDetailsService")
    @Autowired
    private UserDetailsService userDetailsService;//也要引入userDetailsService

config方法

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //http.formLogin()   //指定身份认证的方式为表单登录
        //http.httpBasic()

        ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
        validateCodeFilter.setAuthenticationFailureHandler(whaleAuthenctiationFailureHandler);//设置错误过滤器

        validateCodeFilter.setSecurityProperties(securityProperties);
        validateCodeFilter.afterPropertiesSet();


        http.addFilterBefore(validateCodeFilter,UsernamePasswordAuthenticationFilter.class)
                .formLogin()
//                .loginPage("/signIn.html") //指定登录页面的url
//                .loginPage("/anthentication/require") //指定登录页面的url
                .loginPage(securityProperties.getBrowser().getLoginPage()) //指定登录页面的url
                .loginProcessingUrl("/authentication/form")
                .successHandler(whaleAuthenticationSuccessHandler)
                .failureHandler(whaleAuthenctiationFailureHandler)
                .permitAll()
                .and()

            .rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSecodes())
                .userDetailsService(userDetailsService)


                .and()
                .authorizeRequests() //对请求授权
//                .antMatchers("/signIn.html","/code/image").permitAll() //加一个匹配器 对匹配的路径不进行身份认证
                .antMatchers(securityProperties.getBrowser().getLoginPage(),"/code/image").permitAll() //加一个匹配器 对匹配的路径不进行身份认证
                .anyRequest()        //任何请求
                .authenticated()    //安全认证
                .and()
                .cors().disable().csrf().disable();// 禁用跨站攻击
                // 默认都会产生一个hiden标签 里面有安全相关的验证 防止请求伪造 这边我们暂时不需要 可禁用掉
                //任何请求都必须经过表单验证才能进行访问

       /* http.csrf().disable().cors().disable().headers().disable()
                .authorizeRequests()
                .antMatchers("/signIn.html").permitAll() // 配置不需要身份认证的请求地址
                .anyRequest().authenticated() // 其他所有访问路径需要身份认证
                .and()
                .formLogin()
                .loginPage("/signIn.html") // 指定登录请求地址
                .loginProcessingUrl("/authentication/form")
                .permitAll();
        */


    }

上一节的错误 启动报错

登录实现记住我功能_第5张图片
如果demo中的application中注释掉

#whale.security.code.image.url = /user,/user/*

configurls会为null,直接循环会报错,应该先判空,,否则系统启动报错 控制台打印如下错误信息

2019-05-17 08:40:23.998  WARN 5808 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.NullPointerException

测试

登录实现记住我功能_第6张图片
登录成功后,重新启动服务
登录实现记住我功能_第7张图片
说明登录信息是保存到数据库的

再看下数据库
登录实现记住我功能_第8张图片

AbstractAuthenticationProcessingFilter
登录实现记住我功能_第9张图片

class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
登录实现记住我功能_第10张图片
1创建新token放到数据库中
2将token写入浏览器中

RememberMeAuthenticationFilter

登录实现记住我功能_第11张图片
PersistentTokenBasedRememberMeServices
登录实现记住我功能_第12张图片
登录实现记住我功能_第13张图片
最后又回到userdetailservice

你可能感兴趣的:(Spring,Security)