Springboot+SpringSecurity实现权限控制(六、开启记住我功能)

本文介绍如何在SpringBoot项目中结合SpringSecurity开启记住我功能,包括添加依赖,配置@Bean,以及前端测试流程。
摘要由CSDN通过智能技术生成

开启记住我功能

添加jar包

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

注入一个@Bean

  	获取配置的数据源
	@Autowired
    public DataSource dataSource;


@Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository=new JdbcTokenRepositoryImpl();
        //连接数据源
        tokenRepository.setDataSource(dataSource);
        //启动时是否创建表,第一次使用,之后注释掉,因为是用来创建数据库的表
        tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

然后在核心配置类中配置功能,重启服务,然后会发现表已经创建成功了,要把创建表的代码注释掉了

                //记住我
        	http.rememberMe()
                //自定义参数 默认remember-me
                //.rememberMeParameter("remember-me")
                //自定义失效时间,默认两周
                //.tokenValiditySeconds()
                //自定义功能实现逻辑
                //.rememberMeServices()
                //自动登录
                .userDetailsService(userDetalisServiceImpl)
                //指定存储位置
                .tokenRepository(tokenRepository);

在前端中

<form action="/login" method="post">
    <p>
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username">
    </p>
    <p>
        <label for="password">密码:</label>
        <input type="text" id="password" name="password">
    </p>
     <p>
        <label>记住我:</label>
        <input type="checkbox"  name="remember-me" value="true">
    </p>
    <p><input type="submit" value="登录"></p>
</form>
package com.jiangzhu.auth;

import com.jiangzhu.filter.JwtAuthenticationTokenFilter;
import com.jiangzhu.service.impl.UserDetalisServiceImpl;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.web.cors.CorsUtils;

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

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) //开启权限注解控制
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder(){
        //使用这么一个实现类,获取加密加盐的密码
        //而且每次运行就算是相同的字符串,生成的密码也是不一样的
        return new BCryptPasswordEncoder();
    }
    //修改密码的加密方式
    @Autowired
    private PasswordEncoder passwordEncoder;


    //登录认证
    @Resource
    private UserDetalisServiceImpl userDetalisServiceImpl;

    //异常处理
    private MyAuthenticationEntryPoint myAuthenticationEntryPoint ;

    //登录成功的处理方案
    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    //登录失败的处理方案
    @Autowired
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;

    //注销成功的处理方案
    @Autowired
    private MyLogoutSuccessHandler myLogoutSuccessHandler;

    //模拟用户账号被挤下线的处理方案
    @Autowired
    private MySessionInformationExpiredStrategy mySessionInformationExpiredStrategy;

    /**
     * 权限不足
     */
    @Resource
    private RestfulAccessDeniedHandler accessDeniedHandler;

    //jwt
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;


    @Autowired
    public DataSource dataSource;
    @Autowired
    private PersistentTokenRepository tokenRepository;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //替换默认的登录方式为自定义的登录认证方式
        auth.userDetailsService(userDetalisServiceImpl)
                //替换默认的密码认证方式
                .passwordEncoder(passwordEncoder);
    }



    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //第1步:解决跨域问题。cors 预检请求放行,让Spring security 放行所有preflight request(cors 预检请求)
        http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll();

        //第2步:让Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext
        http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().headers().cacheControl();
/**
 * 在 UsernamePasswordAuthenticationFilter 之前添加 JwtAuthenticationTokenFilter
 */
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);


        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
        //登录
        http.formLogin()
                //允许所有用户
                .permitAll()
                //登录成功
                .successHandler(myAuthenticationSuccessHandler)
                //登录失败
                .failureHandler(myAuthenticationFailureHandler);
        //注销
        http.logout()
                //允许所有用户
                .permitAll()
                //注销成功
                .logoutSuccessHandler(myLogoutSuccessHandler)
                //登出之后删除cookie
                .deleteCookies("JSESSIONID");

        //限制账号的会话管理
        http.sessionManagement()
                //同一账号同时登录最大用户数
                .maximumSessions(1)
                //如果为true,那么之后不能再登录,如果为false,登录之后会将之前的账号挤下线
                .maxSessionsPreventsLogin(false)
                //会话信息过期策略会话信息过期策略(账号被挤下线)
                .expiredSessionStrategy(mySessionInformationExpiredStrategy);

        //异常处理(权限拒绝,登录失效等)
        http.exceptionHandling()
                //用来解决匿名用户访问无权限资源时的异常 因为是通过authenticated认证的
                .authenticationEntryPoint(myAuthenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler);

        http.authorizeRequests()
                .antMatchers("/bb").hasAuthority("home:index")
                .anyRequest().authenticated();

        //记住我
        http.rememberMe()
                //自定义参数 默认remember-me
                //.rememberMeParameter("remember-me")
                //自定义失效时间,默认两周
                //.tokenValiditySeconds()
                //自定义功能实现逻辑
                //.rememberMeServices()
                //自动登录
                .userDetailsService(userDetalisServiceImpl)
                //指定存储位置
                .tokenRepository(tokenRepository);

    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository=new JdbcTokenRepositoryImpl();
        //连接数据源
        tokenRepository.setDataSource(dataSource);
        //启动时是否创建表,第一次使用,之后注释掉,因为是用来创建数据库的表
        //tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }
}

测试

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一念用户

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值