美文网首页
5.实现功能:记住我

5.实现功能:记住我

作者: 呆叔么么 | 来源:发表于2019-12-23 23:41 被阅读0次
原理
增加配置BrowserProperties
com.imooc.security.core.properties.BrowserProperties
package com.imooc.security.core.properties;

/**
 * @Author:LovingLiu
 * @Description:
 * @Date:Created in 2019-12-22
 */
public class BrowserProperties {
    private String loginPage = "/imooc-signIn.html"; // 指定默认跳转页面

    private LoginType loginType = LoginType.JSON; // 指定登录方式

    private int rememberMeSeconds = 3600; // 记住我的有效期

    public String getLoginPage() {
        return loginPage;
    }

    public void setLoginPage(String loginPage) {
        this.loginPage = loginPage;
    }

    public LoginType getLoginType() {
        return loginType;
    }

    public void setLoginType(LoginType loginType) {
        this.loginType = loginType;
    }

    public int getRememberMeSeconds() {
        return rememberMeSeconds;
    }

    public void setRememberMeSeconds(int rememberMeSeconds) {
        this.rememberMeSeconds = rememberMeSeconds;
    }
}

修改配置类BrowserSecurityConfig
com.imooc.security.browser.BrowserSecurityConfig

package com.imooc.security.browser;

import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.ValidateCodeFilter;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
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.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * @Author:LovingLiu
 * @Description: Security安全配置的适配器
 * @Date:Created in 2019-12-18
 */
@Configuration
@EnableWebSecurity
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler imoocAuthenticationFailureHandler;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(); // 推荐使用 BCrypt 的加密的形式
    }

    @Autowired
    private DataSource dataSource;

    @Autowired
    private MyUserDetailService userDetailService;

    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // tokenRepository.setCreateTableOnStartup(true); // 系统启动时自动创建表(仅仅限制第一次系统启动,启动一次之后注解掉)
        return tokenRepository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
        validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler);
        validateCodeFilter.setSecurityProperties(securityProperties);
        validateCodeFilter.afterPropertiesSet(); // 设置配置的属性

        http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class). // 添加自定义过滤器
                formLogin(). // 声明验证方式为表单登录
                    loginPage("/authentication/require"). // 自定义登录界面
                    loginProcessingUrl("/authentication/form"). // 指定接收username/password的请求路径
                    successHandler(imoocAuthenticationSuccessHandler). // 使用自定义成功处理器
                    failureHandler(imoocAuthenticationFailureHandler). // 使用自定义失败处理器
                    and(). //
                rememberMe().
                    tokenRepository(persistentTokenRepository()). // 返回jdbcTokenRepository的实现
                    tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds()). // 配置有效时间
                    userDetailsService(userDetailService). // 使用声明的用户
                and().
                    authorizeRequests(). // 对请求进行授权
                    antMatchers("/authentication/require","/authentication/form","/code/image",securityProperties.getBrowser().getLoginPage()).permitAll().// 配置不进行认证请求
                    anyRequest(). // 任意请求
                    authenticated(). // 都需要身份认证
                and().
                    csrf().disable(); // 关闭跨站请求防护
    }
}

Filter 执行顺序

RememberMeAuthenticationFilter在过滤器链中的执行顺序
1.1UsernamePasswordAuthenticationFilter接受到认证请求
当认证成功后,会调用一个叫做RemeberMeService的服务,这个是SpringSecurity提供的服务,它主要做两件事情,生成一个Token,然后分别写入数据库和Cookie中去,如下图代码所示:
源码

1.2第二次服务请求
此时是有RememberMeAuthenticationFilter来处理该请求(前提:其他过滤器放行),Filter会读取Cookie中的Token,然后继续由RemeberMeServiceTokenRepository来查找数据库中的相关信息,如果查询到了,此时会调用UserDetailsService来获取用户信息。RememberMeAuthenticationFilter所处的位置是在倒数第二个Filter的位置。只要前面的Filter过滤掉了,都会经过它来判断是否需要免密登录。

相关文章

网友评论

      本文标题:5.实现功能:记住我

      本文链接:https://www.haomeiwen.com/subject/stmtoctx.html