浏览器开发记住我功能
因为我已经实现过Oauth认证,在那种情况下已经实现记住我功能(token有效期),所以这里只是简单记录一下,功能实现即可(用户登录的token一般存储在Redis中)。
原理:
配置BrowserSecurityConfig:
package com.cong.security.browser;
import com.cong.security.core.code.ValidateCodeFilter;
import com.cong.security.core.constant.SecurityConstant;
import com.cong.security.core.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.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.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;
/**
* @Description TODO
* @Author single-聪
* @Date 2020/1/7 18:00
* @Version 1.0.1
**/
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
// 成功处理器
@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
// 失败处理器
@Autowired
private AuthenticationFailureHandler myAuthenticationFailureHandler;
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
// 设置数据源
jdbcTokenRepository.setDataSource(dataSource);
// 初次建表
// jdbcTokenRepository.setCreateTableOnStartup(true);
return jdbcTokenRepository;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setMyAuthenticationFailureHandler(myAuthenticationFailureHandler);
validateCodeFilter.setSecurityProperties(securityProperties);
// 初始化方法
validateCodeFilter.afterPropertiesSet();
// 使用表单登录进行身份认证
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)// 图形验证码过滤器加入链
.formLogin()
.loginPage(SecurityConstant.DEFAULT_UNAUTHENTICATION_URL)// 自定义登录页面
.loginProcessingUrl("/login")// 自定义用户名密码登录请求路径
.successHandler(myAuthenticationSuccessHandler) // 自定义成功处理器
.failureHandler(myAuthenticationFailureHandler)// 自定义失败处理器
.and()
.rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(3600)// 设置默认值3600S
.userDetailsService(userDetailsService)// 登录借口
.and()
.authorizeRequests()
.antMatchers("/code/*", SecurityConstant.DEFAULT_UNAUTHENTICATION_URL, securityProperties.getBrowser().getLoginPage()).permitAll() // 放开,防止反复重定向
.anyRequest() // 任何请求
.authenticated()// 需要身份认证
.and()
.csrf().disable(); //跨站请求伪造
}
}
如果UserDetailsService注入失败:
启动类上添加如下内容:
编写login.html页面:
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>
图形验证码
</td>
<td>
<input type="text" name="imageCode"/>
<img src="/code/image">
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="remember-me" value="true"/>记住我
</td>
<td>
<button type="submit">登录</button>
</td>
</tr>
</table>
第一次启动项目之后jdbcTokenRepository.setCreateTableOnStartup(true);
命令会创建persistent_logins
数据库表,登录之后关闭浏览器重新打开访问接口即不需要再次登录。
后期浏览器模块时发放token,用户拿token访问可以达到同样的效果。