当前位置:   article > 正文

springboot集成安全框架springsecurity

springboot集成安全框架springsecurity

注意,在配置过滤器时 每个权限/角色配置操作前面都要写上请求路径
如: .anyRequest() 请求路径
.authenticated()//都需要认证操作 是权限/角色操作

在这里插入图片描述

三种用户认证方式(设置用户名密码的)

如果打开crsf防护需要在页面中加入下面代码

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
  • 1

加这个的目的是每次请求时都把csrf防护生成的随机token带上

第一种:通过配置文件(非查库)

应用添加security依赖后,在application配置文件中写入spring.security.user.name和spring.security.user.password即可,若注入成功 控制台不会报security框架自动生成的初始密码

# 应用名称
spring.application.name=spring-security-smalldemo
# 应用服务 WEB 访问端口
server.port=8080
#设置用户名密码方式一 配置文件
spring.security.user.name=lql
spring.security.user.password=mima

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第二种 通过配置类(非查库)

在配置类中编写如下即可

package com.li.config;

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.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**  设置用户名密码的第二种方式 配置类
 * @author liql
 * @date 2021/9/21
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //密码需要加密 不然报 Encoded password does not look like BCrypt 错误
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123456");
        //角色不能不设置,不然报错
        auth.inMemoryAuthentication().withUser("lql").password(password).roles("");

    }

    //不注入PasswordEncoder 会报下面的错误
    //java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

第三种 通过实现 UserDetailsService接口设置用户名密码(可查库)

分别定义一个配置类和接口实例类即可,
用户名密码查库操作可定义在该实例中只需要替换返回对象User中的参数为数据库查到的即可。

配置类

package com.li.config;

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.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**  设置用户名密码的第三种方式 通过实现 userDetailsService 接口
 * @author liql
 * @date 2021/9/21
 */
@Configuration
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

    }

    //不注入PasswordEncoder 会报下面的错误
    //java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

用户名密码写死

package com.li.config;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 配置第三种用户密码的方式的实现类  UserDetailsService接口是security框架的
 * @author liql
 * @date 2021/9/21
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //设置权限
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("roles");

        //第三个参数为设置权限,不能为空。
        return new User("lql", new BCryptPasswordEncoder().encode("123"), authorityList);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

通过查库获取用户名对应的密码

参数 username为登录界面输入的用户名,把查库拿到的密码传入到返回值中,security底层会自动将查库的密码与登录界面输入的密码做校验

package com.li.config;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 配置第三种用户密码的方式的实现类  UserDetailsService接口是security框架的
 * @author liql
 * @date 2021/9/21
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
    //定义一个安全类集合模拟数据库
    private static ConcurrentHashMap<String,String> mydb=new ConcurrentHashMap();
    static {
        mydb.put("lql", "111");
        mydb.put("xiaohong", "123");
    }

    /**
     *
     * @param username  该参数为登录界面输入的用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //设置权限
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("roles");

        //模拟通过数据库查密码
        String password=mydb.get(username);
        // if(查库没查到){
        //    throw new UsernameNotFoundException("用户名不存在")
        //  }

        //把数据库查到的密码传入进去 security框架底层会帮我们自动做校验 第三个参数为设置权限,不能为空。
        return new User(username, new BCryptPasswordEncoder().encode(password), authorityList);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

自定义设置登录页面

在原先的配置类中重写 void: configure(HttpSecurity http) 方法

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
  • 1
  • 2
  • 3
  • 4

重写后

   @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.formLogin().loginPage("/login.html") //登录界面
               .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
               .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
               .permitAll()// 无条件允许访问 不校验权限
                .and()
               .authorizeRequests()//后面写认证配置
               .anyRequest() //任何请求
               .authenticated()//都需要认证操作
//               .antMatchers("/","/test/hello").permitAll()  //设置哪些无条件允许访问 但必须先认证然后不校验权限  
               .and()
               .csrf().disable();//关闭csrf防护 关闭跨域保护
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

添加依赖和配置
spring.thymeleaf.prefix=classpath:/static

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4

login.html
页面 username password 参数名是固定的,因为在UsernamePasswordAuthenticationFilter过滤器中明确定义了
在这里插入图片描述

<!DOCTYPE html>
<!-- 需要添加
<html  xmlns:th="http://www.thymeleaf.org">
这样在后面的th标签就不会报错
 -->
<html  xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>xx</title>
</head>
<body>


<h1>表单提交</h1>
<!-- 表单提交用户信息,注意字段的设置,直接是*{} -->
<form action="/user/login"  method="post">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    <input type="text" name="username" />
    <input type="text" name="password" />
    <input type="submit" />
</form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

登录成功跳转页面

    @GetMapping("/index")
    @ResponseBody
    public String index(){

        return "登录成功";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

基于权限进行控制

给用户授权

在UserDetailsService的实例类里进行授权

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //设置权限
        List<GrantedAuthority> authorityList =
                AuthorityUtils
                 //该方法   commaSeparatedStringToAuthorityList 技能设置权限又能设置角色,设置角色时加前缀 ROLE_XXX , 多个权限和角色中间用逗号隔开
                .commaSeparatedStringToAuthorityList("perm_hello1,perm_hello2");

        //模拟通过数据库查密码
        String password=mydb.get(username);
        // if(查库没查到){
        //    throw new UsernameNotFoundException("用户名不存在")
        //  }
        //把数据库查到的密码传入进去 security框架底层会帮我们自动做校验 第三个参数为设置权限和角色,不能为空。
        return new User(username, new BCryptPasswordEncoder().encode(password), authorityList);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

设置访问路径的权限

在配置类里

    @Override
    protected void configure(HttpSecurity http) throws Exception {
 /*      http.formLogin().loginPage("/login.html") //登录界面
               .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
               .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
               .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
               .authorizeRequests()//后面写认证配置
               .anyRequest() //任何请求
               .authenticated()//都需要认证操作
//               .antMatchers("/","/test/hello").permitAll()  //设置哪些路径可以不用认证就能访问
               .and()
               .csrf().disable();//关闭csrf防护 关闭跨域保护*/

        http.formLogin().loginPage("/login.html") //登录界面
                .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
                .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
                .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
                .authorizeRequests()
                .antMatchers("/test/hello")
                .hasAnyAuthority("perm_hello")//满足该权限 ,只能写单个权限
                .antMatchers("/test/hello2")
                //满足下面权限的一个即可放行
                .hasAnyAuthority("perm_hello,perm_hello2")
                .anyRequest() //任何请求
                .authenticated()//都需要认证操作
                .and()
                .csrf().disable();//关闭csrf防护 关闭跨域保护;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

基于角色访问

给用户设置角色

与设置权限的地方相同 ,在实例类中 设置权限的地方增加 ROLE_xxx 即可
加“ROLE_”前缀的原因是,在配置过滤器时 如写个角色为 “admin” 但是在底层会校验“ROLE_admin”;
在这里插入图片描述

  List<GrantedAuthority> authorityList =
                AuthorityUtils
                 //该方法   commaSeparatedStringToAuthorityList 技能设置权限又能设置角色,设置角色时加前缀 ROLE_XXX , 多个权限和角色中间用逗号隔开
                        //ROLE_admin 给用户设置 admin角色
                .commaSeparatedStringToAuthorityList("perm_hello1,perm_hello2,ROLE_admin");
  • 1
  • 2
  • 3
  • 4
  • 5

给路径设置角色

与设置路径的地方相同 在配置类中
增加

.antMatchers("/test/hello2")
                //满足下面角色的一个即可放行
                .hasRole("admin")
                 .antMatchers("/test/hello3")
                //满足其中的一个角色即可放行
                .hasAnyRole("admin,admin2")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
 @Override
    protected void configure(HttpSecurity http) throws Exception {
 /*      http.formLogin().loginPage("/login.html") //登录界面
               .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
               .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
               .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
               .authorizeRequests()//后面写认证配置
               .anyRequest() //任何请求
               .authenticated()//都需要认证操作
//               .antMatchers("/","/test/hello").permitAll()  //设置哪些路径可以不用认证就能访问
               .and()
               .csrf().disable();//关闭csrf防护 关闭跨域保护*/

        http.formLogin().loginPage("/login.html") //登录界面
                .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
                .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
                .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
                .authorizeRequests()
                .antMatchers("/test/hello")
                .hasAnyAuthority("perm_hello")//满足该权限 ,只能写单个权限
                .antMatchers("/test/hello2")
                //满足下面权限的一个即可放行
                .hasAnyAuthority("perm_hello,perm_hello2")
                .antMatchers("/test/hello2")
                //满足下面角色的一个即可放行
                .hasRole("admin")
                 .antMatchers("/test/hello3")
                //满足其中的一个角色即可放行
                .hasAnyRole("admin,admin2")
                .anyRequest() //任何请求
                .authenticated()//都需要认证操作
                .and()
                .csrf().disable();//关闭csrf防护 关闭跨域保护;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

自定义无权限时的返回页面

依然在配置过滤器的方法中加入 即可 页面
在这里插入图片描述

  //设置无权限时返回的页面
        http.exceptionHandling().accessDeniedPage("/test/unauthen");
  • 1
  • 2
   @GetMapping("/unauthen")
    @ResponseBody
    public String unauthen(){
        return "无权访问";
    }
  • 1
  • 2
  • 3
  • 4
  • 5

退出登录

在配置类中加上如下配置即可
在这里插入图片描述

 //配置退出
        http.logout()
                .logoutUrl("/logout") //输入该url表示退出
                .logoutSuccessUrl("/test/logout")//成功退出后跳转的页面
                .permitAll();
  • 1
  • 2
  • 3
  • 4
  • 5

基于注解配置

自动登录

自动登录的实现原理是:

  1. 浏览器请求登录
  2. 验证通过 给浏览器返回一个标记自动登录 token,并同时把这个token存入到数据库
  3. 下次登录 / 访问资源的时候,浏览器携带token进行请求,框架会拿到这个token与数据库存的token做对比,相同则放行,否则重新登录。

开发步骤

  1. 配置类注入数据源
//注入数据源 使用rememberme-me 时需要
    @Autowired
    private DataSource dataSource;
  • 1
  • 2
  • 3
  1. 配置类中创建操作数据库的对象
//配置操作数据库的对象
    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        //下面这个api需要导入 orm框架相关的架包 如 mybatisplus
        jdbcTokenRepository.setDataSource(dataSource);
        //下面这个api可以帮我们自动在数据库创建 rememberme-me  时需要的数据库表一般第一次使用的时候打开
        //如果表已经存在会报错
        //jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  1. 在配置类过滤器中配置自动登录的配置
 .and().
                rememberMe().
                tokenRepository(persistentTokenRepository())//引入操作数据库的类
                .tokenValiditySeconds(600)//设置有效时长,单位秒
                .userDetailsService(userDetailsService)
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 页面要配置 name=“remember_me”的输入框
<html  xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>xx</title>
</head>
<body>
<h1>表单提交</h1>
<form action="/user/login"  method="post">
    <input type="text" name="username" />
    <input type="text" name="password" />
    <input type="checkbox"name="remember-me"title="记住密码"/>记住密码<br/>
    <input type="submit" />
</form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

完整的配置类

package com.li.config;

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.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.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**  设置用户名密码的第三种方式 通过实现 userDetailsService 接口
 * @author liql
 * @date 2021/9/21
 */
@Configuration
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

    }

    //不注入PasswordEncoder 会报下面的错误
    //java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
 /*      http.formLogin().loginPage("/login.html") //登录界面
               .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
               .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
               .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
               .authorizeRequests()//后面写认证配置
               .anyRequest() //任何请求
               .authenticated()//都需要认证操作
//               .antMatchers("/","/test/hello").permitAll()  //设置哪些路径可以不用认证就能访问
               .and()
               .csrf().disable();//关闭csrf防护 关闭跨域保护*/

        http.formLogin().loginPage("/login.html") //登录界面
                .loginProcessingUrl("/user/login") //用户密码需要提交到的路径 该路径由security管理 不需要我们定义
                .defaultSuccessUrl("/test/index")//登录成功后跳转到的页面
                .permitAll()// 无条件允许访问 但必须先认证然后不校验权限
                .and()
                .authorizeRequests()
                .antMatchers("/test/hello")
                .hasAnyAuthority("perm_hello")//满足该权限 ,只能写单个权限
                .antMatchers("/test/hello2")
                //满足下面权限的一个即可放行
                .hasAnyAuthority("perm_hello,perm_hello2")
                .antMatchers("/test/hello2")
                //满足下面角色即可放行
                .hasRole("admin")
                .antMatchers("/test/hello3")
                //满足其中的一个角色即可放行
                .hasAnyRole("admin,admin2")
                .anyRequest() //任何请求
                .authenticated()//都需要认证操作
                //下面是开启记住我功能的配置
                .and().
                rememberMe().
                tokenRepository(persistentTokenRepository())//引入操作数据库的类
                .tokenValiditySeconds(600)//设置有效时长,单位秒
                .userDetailsService(userDetailsService)
                .and()
                .csrf().disable();//关闭csrf防护 关闭跨域保护;

        //设置无权限时返回的页面
        http.exceptionHandling().accessDeniedPage("/test/unauthen");
        //配置退出
        http.logout()
                .logoutUrl("/logout") //输入该url表示退出
                .logoutSuccessUrl("/test/logout")//成功退出后跳转的页面
                .permitAll();
    }

    //注入数据源 使用rememberme-me 时需要,要引入mysql驱动
    @Autowired
    private DataSource dataSource;
    //配置操作数据库的对象
    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        //下面这个api需要导入 orm框架相关的架包 如 mybatisplus
        jdbcTokenRepository.setDataSource(dataSource);
        //下面这个api可以帮我们自动在数据库创建 rememberme-me  时需要的数据库表一般第一次使用的时候打开
        //如果表已经存在会报错
        //jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号