3_SpringSecurity实现密码加密和自动登录功能

SpringSecurity登录的密码加密和设置自动登录功能

环境前提搭建

  1. SpringSecurity连接数据库实现用户角色登录验证
  2. 数据库中的密码修改成加密过的密码,可以用下面的测试类转换
 @Test
    void contextLoads() {
        BCryptPasswordEncoder bCryptPasswordEncoder= new BCryptPasswordEncoder();
        System.out.println(bCryptPasswordEncoder.encode("你的密码"));
    }

具体实现

登录的login.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/securitylogin}" method="post">
    用户名:<input type="text" name="username">
    <br>
    密码:<input type="password" name="password">
    <br>
    <input type="checkbox" name="remember-me" value="1">自动登录
    <!--通过阅读源码我们可以知道,name的名默认是remember-me也可以在SpringSecurity的配置文件里面改,但是value可以是:1,true,on和yes这4种-->
    <input type="submit" value="登陆">
</form>
</body>
</html>

SpringSecurity的配置类

package com.pning.studysecurity.config;


import com.pning.studysecurity.service.ISystemUser;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.annotation.Resource;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    ISystemUser iSystemUser;

//授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/toLogin").permitAll()
                .antMatchers("/leave_1/**").hasRole("vip1")
                .antMatchers("/leave_2/**").hasRole("vip2")
                .antMatchers("/leave_3/**").hasRole("vip3");
        http.formLogin().loginPage("/toLogin").loginProcessingUrl("/securitylogin");
        http.logout().deleteCookies("remove").invalidateHttpSession(true).logoutSuccessUrl("/toLogin");
        http.rememberMe().tokenValiditySeconds(60);//开启自动登录功能,并且设置过期时间为60秒
        http.csrf().disable();//关闭csrf,不然会拦截没有token的put,post,delete等非查询的方法
    }

    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(iSystemUser)
                .passwordEncoder(new BCryptPasswordEncoder());//添加加密类型
    }
}

通过用户名查询密码和角色的接口
在之前继承了UserDetailsService的接口的实现类中吧{noop}删除,表名我们已经对密码加了密

package com.pning.studysecurity.service.imp;

import com.pning.studysecurity.mapper.SystemUserMapper;
import com.pning.studysecurity.pojo.SystemUser;
import com.pning.studysecurity.service.ISystemUser;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SystemUserImp implements ISystemUser {

    @Resource
    SystemUserMapper systemUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SystemUser systemUser = systemUserMapper.selectSystemUserByUserName(username);
        if(systemUser!=null){
            List<SimpleGrantedAuthority> roles = new ArrayList<>();
            for (String roleName:systemUser.getRoles()){
                roles.add(new SimpleGrantedAuthority(roleName));
            }
            return new User(systemUser.getUsername(),systemUser.getPassworld(),roles);//取消{noop}的不加密形式
        }
        return null;
    }
}

验证
在这里插入图片描述

remember-me功能的token进行持久化

目前为止就完成了简单的自动登录功能,但是有个问题,就是现在的这个是cookie存放在用户浏览起这边的,如果在这个cookie未过期的时间中,有人把这个remember-me的cookie放在自己浏览器也是可以直接登陆的,而且这个cookie里面还有一些重要的信息,哪怕是加密过也是不安全的。
SpringSecurity为此提供了一个机制,就是在remember-me的cookie中设置一个没有意义的加密字符串,并且这个字符串存在数据库中,自动登录之前将这个字符串和数据库的字符串进行对比,两者一致才能成功自动登录。
注意的是:存储这个用于验证的字符串的数据库表必须是官方提供的那张表,字段什么都不能修改,如果修改的话将无法使用

CREATE TABLE persistent_logins (
	username VARCHAR(64) NOT NULL, 
	series VARCHAR(64) PRIMARY KEY, 
	token VARCHAR(64) NOT NULL, 
	last_used TIMESTAMP NOT NULL);

在SpringSecurity中配置
需要添加数据源和注入持久化token的组件

package com.pning.studysecurity.config;


import com.pning.studysecurity.service.ISystemUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.annotation.Resource;
import javax.sql.DataSource;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    ISystemUser iSystemUser;

    @Autowired
    private DataSource dataSource;//配置数据源

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/toLogin").permitAll()
                .antMatchers("/leave_1/**").hasRole("vip1")
                .antMatchers("/leave_2/**").hasRole("vip2")
                .antMatchers("/leave_3/**").hasRole("vip3");
        http.formLogin().loginPage("/toLogin").loginProcessingUrl("/securitylogin");
        http.logout().deleteCookies("remove").invalidateHttpSession(true).logoutSuccessUrl("/toLogin");
        http.rememberMe()
                .tokenValiditySeconds(60)
                .tokenRepository(persistentTokenRepository());//配置数据源
        http.csrf().disable();
    }

    //注入持久化token的组件
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        return jdbcTokenRepository;
    }

    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(iSystemUser)
                .passwordEncoder(new BCryptPasswordEncoder());//添加加密类型
    }


}

验证
在这里插入图片描述

源码自取

gitee上自取代码和数据库文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值