zoukankan      html  css  js  c++  java
  • 02. Spring Security rememberMe

    02. Spring Security rememberMe

    参考:

    https://blog.csdn.net/yuanlaijike/article/details/80249869

    接着上一讲

    修改login.html

    使用简单的记住我, 但是不安全

    #login.html

        <div class="form">
            <h3>账户登录</h3>
            <input type="text" placeholder="用户名" name="username" required="required"/>
            <input type="password" placeholder="密码" name="password" required="required"/>
            <!--        自动登入设置的name必须是remember-me-->
            <label><input type="checkbox" name="remember-me"/>自动登录</label>
            <button type="submit">登录</button>
        </div>
    

    添加rememberMe()

    #配置类

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/login").permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/").permitAll()
                    .and()
                    .logout()
                    .and()
                    .rememberMe();
        }
    

    默认cookie存储2周

    Spring security 还提供了另一种相对更安全的实现机制

    在客户端的 Cookie 中,仅保存一个无意义的加密串(与用户名、密码等敏感数据无关),然后在数据库中保存该加密串-用户信息的对应关系,自动登录时,用 Cookie 中的加密串,到数据库中验证,如果通过,自动登录才算通过。

    #基本原理

    当浏览器发起表单登录请求时,当通过 UsernamePasswordAuthenticationFilter 认证成功后,会经过 RememberMeService,在其中有个 TokenRepository,它会生成一个 token,首先将token 写入到浏览器的 Cookie 中,然后将 token、认证成功的用户名写入到数据库中。

    当浏览器下次请求时,会经过 RememberMeAuthenticationFilter,它会读取 Cookie 中的 token,交给 RememberMeService 从数据库中查询记录。如果存在记录,会读取用户名并去调用 UserDetailsService,获取用户信息,并将用户信息放入Spring Security 中,实现自动登陆。

    RememberMeAuthenticationFilter 在整个过滤器链中是比较靠后的位置,也就是说在传统登录方式都无法登录的情况下才会使用自动登陆。

    #代码实现

    首先需要创建一张表来存储 token 信息:

    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;
    
    

    在 WebSecurityConfig 中注入 dataSource ,创建一个 PersistentTokenRepository 的Bean:

    @Autowired
    private DataSource dataSource;
    
     @Bean
     public PersistentTokenRepository persistentTokenRepository(){
         JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
         tokenRepository.setDataSource(dataSource);
         // 如果token表不存在,使用下面语句可以初始化该表;若存在,请注释掉这条语句,否则会报错。
    //        tokenRepository.setCreateTableOnStartup(true);
         return tokenRepository;
     }
    
    

    如果使用setCreateTableOnStartup(true)则会再当前库中生成一个表名为persistent_logins的表

    修改配置中的登入设置

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/login").permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/").permitAll()
                    .and()
                    .logout().permitAll()
                    .and()
                    //记住我默认2周
                    .rememberMe()
                    //设置token有效时间
                    .tokenValiditySeconds(60)
                    .tokenRepository(persistentTokenRepository());
                    .userDetailsService(userDetailsService);
    
  • 相关阅读:
    POJ_1485_dp
    POJ_1376_bfs
    [noi1994]海盗
    [noi1755]Trie
    [luogu3733]八纵八横
    [noi1774]array
    [noi1773]function
    [noi1754]SA
    [noi1779]D
    [bzoj4873]寿司餐厅
  • 原文地址:https://www.cnblogs.com/kikochz/p/12892443.html
Copyright © 2011-2022 走看看