( •̀ ω •́ )✧SpringSecurity中级篇



目录

  • ( •̀ ω •́ )✧SpringSecurity中级篇
  • 一、基于表达式的访问控制⭐
  • 1、自定义方法
  • 2、修改配置文件SpringSecurityConfig.java
  • 3、配置用户权限
  • 二、 基于注解的访问控制⭐
  • 1、@Secured和@PreAuthorize小案例
  • 三、免登录RememberMe功能实现
  • 1、引入依赖
  • 2、配置数据源
  • 3、免登录具体配置RemmberConfig .java
  • 5、配置和静态页面添加
  • 四、Thymeleaf中SpringSecurity的集成
  • 1、引入依赖
  • 2、小Demo实现
  • 五、退出登录
  • 六、SpringSecurity中的CSRF
  • 1、 什么是CSRF?
  • 2、小Demo案例
  • 七、Oauth2认证⭐
  • 1、常用语术
  • 2、特点
  • 3、授权模式
  • ①、授权码模式⭐
  • ②、 密码模式



一、基于表达式的访问控制⭐

可以通过 access()实现和之前学习的权限控制完成相同的功能。.antMatchers.access(“表达式或方法”) 表达式范围很广如:.anyRequest.access(@类名.方法):通过url来判断访问哪里,与获取的权限集合进行判断是否有权限(适合项目的开发)。

sp_close_session 没权限_java

自定义方法Demo:

1、自定义方法

①编写Serviece层SecurityAccess.java

@Service
public class SecurityAccess {
	//自定义方法
    public boolean authority(HttpServletRequest request, Authentication authentication){
        //获取权限列表
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        if(!CollectionUtils.isEmpty(authorities)){
            //获取uri
            String uri=request.getRequestURI();
            //通过uri获取权限码
            SimpleGrantedAuthority simple=new SimpleGrantedAuthority(uri);
            if(authorities.contains(simple)){
                return true;
            }
        }
        return false;
    }
}

2、修改配置文件SpringSecurityConfig.java
@SpringBootConfiguration
/*表达式、方法权限控制*/
public class SpringSecurityConfig4 extends WebSecurityConfigurerAdapter {
    //引入handle
    @Autowired
    SecuritySuccessHandle securitySuccessHandle;
    @Autowired
    SecurityFailHandle securityFailHandle;
    @Autowired
    SecurityAccessDeniedHandler securityAccessDeniedHandler;
    @Autowired
    SecurityAccess securityAccess;

    //配置passwordEncode的实现类
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //重写方法配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        http.csrf().disable();
        //配置登录页面
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                //登陆成功handle
                .successHandler(securitySuccessHandle)//Post请求
                //登录失败handle
                .failureHandler(securityFailHandle)
                //配置登录参数
                .usernameParameter("userName")
                .passwordParameter("passWord");
        //权限配置
        http.authorizeRequests()

                //一下允许访问
                .antMatchers("/login.html","/login").permitAll()
                //资源不被任何人访问
                .antMatchers("/denyall.html").denyAll()
                //access()通过Uri判断
                .anyRequest().access("@securityAccess.authority(request,authentication)");

//        对403情况的处理
                http.exceptionHandling()
                        .accessDeniedHandler(securityAccessDeniedHandler);

    }
}
3、配置用户权限
@Service
/*自定义用户*/
public class SpringSecurityService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //判断用户名
        if(StringUtils.isEmpty(s)||!("admin".equals(s))){
            throw new UsernameNotFoundException("不存在此用户!");
        }
        //密码加密
        String pw=passwordEncoder.encode("123456");
        //返回一个用户
        return new User(s,pw, AuthorityUtils.commaSeparatedStringToAuthorityList("/tomain"));
    }
}
//=========================================================
//Controller设置了一个访问/tomain的处理
@GetMapping("/tomain")
    public String main(){
        return "欢迎登录";
    }

通过上面的配置,可得出,能访问的只有/tomain,下面进行测试

sp_close_session 没权限_SpringSecurity_02


sp_close_session 没权限_SpringSecurity_03


二、 基于注解的访问控制⭐
  • 首先需要在启动上加上注解: @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true),其中@Secured: 是专门用于判断是否具有角色的。能写在方法或类上。参数要以ROLE_开头。其次,@PreAuthorize@PostAuthorize都是方法或类级别注解,这里对@PreAuthorize进行解析

1、@Secured和@PreAuthorize小案例

SpringSecurityConfig5 .java文件:

@SpringBootConfiguration
/*注解权限控制*/
public class SpringSecurityConfig5 extends WebSecurityConfigurerAdapter {
    //引入handle
    @Autowired
    SecuritySuccessHandle securitySuccessHandle;
    @Autowired
    SecurityFailHandle securityFailHandle;
    @Autowired
    SecurityAccessDeniedHandler securityAccessDeniedHandler;

    //配置passwordEncode的实现类
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //重写方法配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        http.csrf().disable();
        //配置登录页面
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                //登陆成功handle
                .successHandler(securitySuccessHandle)//Post请求
                //登录失败handle
                .failureHandler(securityFailHandle)
                //配置登录参数
                .usernameParameter("userName")
                .passwordParameter("passWord");

        //权限配置
        http.authorizeRequests()
                //一下允许访问
                .antMatchers("/login.html","/login").permitAll()
                //资源不被任何人访问
                .antMatchers("/denyall.html").denyAll()
                //配置其他资源必须登录才能访问
                .anyRequest().authenticated();//放在最后

                //对403情况的处理
                http.exceptionHandling()
                        .accessDeniedHandler(securityAccessDeniedHandler);

    }
}
//没什么变化

MainController .java:

@RestController
public class MainController {

    @GetMapping("/tomain")
    public String main(){
        return "欢迎登录";
    }
    @PostMapping("/toagain")
    public String toagain(){
        return "登录失败,请重新<a href=\"/login.html\">登录</a>";
    }
/*注解角色访问*/
    @Secured({"ROLE_PP"})
    @GetMapping("zj")
    public String tozj(){
        return "注解权限访问!";
    }
/*注解权限码访问*/
    @PreAuthorize("hasAuthority('1000')")
    @GetMapping("ma")
    public String toma(){
        return "注解权限码访问!";
    }

最后在启动类上加上@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)即可


上面直接是对注解角色控制和权限码控制进行了,设置,/zj/ma只有角色是ROLE_PP和权限码是1000的用户才能访问,设置用户权限如下:.

sp_close_session 没权限_SpringSecurity_04

sp_close_session 没权限_CSRE_05


sp_close_session 没权限_java_06


下一关🏓


三、免登录RememberMe功能实现
  • 引入依赖mysql,mybatis(jdbc)
  • 配置数据源application.yml
  • 配置持久层和指定用户免登录

1、引入依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/>
    <!-- lookup parent from repository -->
  </parent>
  
  <dependencies>
    <!--spring security 组件-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!--web 组件-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- test 组件-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- mybatis 依赖 -->
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.1</version>
    </dependency>
    <!-- mysql 数据库依赖 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.18</version>
    </dependency>
  </dependencies>
  
   <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>

2、配置数据源

application.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security? useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root

3、免登录具体配置RemmberConfig .java

切记重新执行时,把创表语句注释掉,避免第二次创建表

/*配置持久层对象*/
@Configuration
    public class RemmberConfig {
        @Autowired
        private DataSource dataSource;
        @Bean
        public PersistentTokenRepository getPersistentTokenRepository(){
            JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
            jdbcTokenRepository.setDataSource(dataSource);
            //自动建表,第一次启动时需要,第二次启动时注释掉
            jdbcTokenRepository.setCreateTableOnStartup(true);
            //返回一个持久层对象
            return jdbcTokenRepository;
        }
    }
5、配置和静态页面添加

SpringSecurityConfig.java

// 记住我
        http.rememberMe()
                //失效时间,单位秒
                .tokenValiditySeconds(60*60*24*7)
                //登录逻辑交给哪个对象
                .userDetailsService(springSecurityService)
                // 持久层对象
                .tokenRepository(remmberConfig.getPersistentTokenRepository());

login.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
    用户名:<input type="text" name="userName" /><br/>
    密码:<input type="password" name="passWord" /><br/>
    <input type="checkbox" name="remember-me" value="true"/><br/>
    <input type="submit" value="登录" />
</form>
</body>
</html>

sp_close_session 没权限_Oauth2_07


这样便代表成功了,下次就不用登录喽


四、Thymeleaf中SpringSecurity的集成
1、引入依赖
<!--thymeleaf springsecurity5 依赖-->
    <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    </dependency>
    <!--thymeleaf依赖-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

引入命名空间:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" >

2、小Demo实现

sp_close_session 没权限_CSRE_08


在项目 resources 中新建 templates 文件夹,在 templates 中新建demo.html 页面.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras- springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登录账号:<span sec:authentication="name"></span><br/>
登录用户名:<span sec:authentication="principal.username"></span><br/>
凭证:<span sec:authentication="credentials"></span><br/>
权限和角色:<span sec:authentication="authorities"></span><br/>
客户端地址:<span sec:authentication="details.remoteAddress"></span> <br/>
sessionId:<span sec:authentication="details.sessionId"></span><br/>

通过权限判断:
<button sec:authorize="hasAuthority('/insert')">新增</button>
<button sec:authorize="hasAuthority('/delete')">删除</button>
<button sec:authorize="hasAuthority('/update')">修改</button>
<button sec:authorize="hasAuthority('/select')">查看</button> <br/>
通过角色判断:
<button sec:authorize="hasRole('a')">新增</button>
<button sec:authorize="hasRole('b')">删除</button>
<button sec:authorize="hasRole('c')">修改</button>
<button sec:authorize="hasRole('d')">查看</button>
<a href="/logout">退出登录</a>
</body>
</html>

编写Controller层进行页面的跳转

@Controller
public class TestController {
    /*thyemleaf*/
    @RequestMapping("demo")
    public String todemo(){
        return "demo";
    }
}

设置角色权限,通过角色的权限不同,thymeleaf显示不同的内容!

//返回一个用户
 return new User(s,pw, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_b,ROLE_a,/insert ,/delete"));

结果:

sp_close_session 没权限_spring_09

小结:以上看出,通过角色和允许访问的uri不同,只显示了增加和删除以及用户信息,修改这些都没有显示,通过视图的设置实现了不同权限,看见不同的内容


五、退出登录

很简单只需要向项目发出/loginOut请求即可只要在页面中添加 /logout 的超链接即可,下面进行实现(添加超链接)。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras- springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登录账号:<span sec:authentication="name"></span><br/>
登录用户名:<span sec:authentication="principal.username"></span><br/>
凭证:<span sec:authentication="credentials"></span><br/>
权限和角色:<span sec:authentication="authorities"></span><br/>
客户端地址:<span sec:authentication="details.remoteAddress"></span> <br/>
sessionId:<span sec:authentication="details.sessionId"></span><br/>

通过权限判断:
<button sec:authorize="hasAuthority('/insert')">新增</button>
<button sec:authorize="hasAuthority('/delete')">删除</button>
<button sec:authorize="hasAuthority('/update')">修改</button>
<button sec:authorize="hasAuthority('/select')">查看</button> <br/>
通过角色判断:
<button sec:authorize="hasRole('a')">新增</button>
<button sec:authorize="hasRole('b')">删除</button>
<button sec:authorize="hasRole('c')">修改</button>
<button sec:authorize="hasRole('d')">查看</button>
<a href="/logout">退出登录</a>
</body>
</html>

sp_close_session 没权限_Oauth2_10

添加配置配置SpringSecurityConfig.java

http.logout()
                //退出的访问路径
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login.html");

sp_close_session 没权限_SpringSecurity_11

sp_close_session 没权限_SpringSecurity_12


六、SpringSecurity中的CSRF
1、 什么是CSRF?
  • CSRF(Cross-site request forgery)跨站请求伪造,也被称为“OneClick Attack” 或者
  • Session Riding。通过伪造用户请求访问受信任站点的非法请求访问。
    跨域:只要网络协议,ip 地址,端口中任何一个不相同就是跨域请求。
  • 客户端与服务进行交互时,由于 http 协议本身是无状态协议,所以引入了cookie进行记录客户端身份。在cookie中会存放session id用来识别客户端身份的。在跨域的情况下,session id可能被第三方恶意劫持,通过这个 session id 向服务端发起请求时,服务端会认为这个请求是合法的,可能发生很多意想不到的事情。

2、小Demo案例

前端页面使用thymeleaf模板,新建templates/login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
    <input type="hidden" th:value="${_csrf.token}" name="_csrf" th:if="${_csrf}"/>
    用户名:<input type="text" name="userName" /><br/>
    密码:<input type="password" name="passWord" /><br/>
    <input type="submit" value="登录" />
</form>
</body>
</html>

编写Controller层访问showLogin时跳转:

/*showLogin跳转*/
    @RequestMapping("showLogin")
    public String tologin(){
        return "login";
    }

记得注释掉ServiecSecurityConfig中:// http.csrf().disable();测试结果:

sp_close_session 没权限_SpringSecurity_13

这样就获取到token.通行令牌


七、Oauth2认证⭐

介绍:第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。大大节约了程序员的时间,提供便捷和效率。

sp_close_session 没权限_spring_14


1、常用语术

sp_close_session 没权限_java_15

2、特点
  • 优点:
    更安全,客户端不接触用户密码,服务器端更易集中保护
    广泛传播并被持续采用
    短寿命和封装的token
    资源服务器和授权服务器解耦
    集中式授权,简化客户端
    HTTP/JSON友好,易于请求和传递token
    考虑多种客户端架构场景
    客户可以具有不同的信任级别
  • 缺点:
    协议框架太宽泛,造成各种实现的兼容性和互操作性差
    不是一个认证协议,本身并不能告诉你任何用户信息。

3、授权模式
  • 授权码模式
  • 密码模式

①、授权码模式⭐

用户登录,通过配置用户,登录访问指定的授权服务器,授权服务器会返回给用户一个授权码,此时用户拿着授权码,访问oauth/token,去兑换令牌,获得令牌之后,再次访问资源服务器,此时拿去资源。

(1)依赖的引入

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/>
    <!-- lookup parent from repository -->
  </parent>
  
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

	  <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>

(2) 编写实体类User.java

public class User implements UserDetails {

    private String username;
    private String password;
    private List<GrantedAuthority> authorities;

    public User(String username, String password, List<GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

(3)编写UserService.java
配置用户账号密码

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    String password = passwordEncoder.encode("123456");
    return new User("admin",password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

(4) 编写UserController.java

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("/getCurrentUser")
    @ResponseBody
    public Object getCurrentUser(Authentication authentication) {
        return authentication.getPrincipal();
    }
}

(5)编写配置类Oauth2Config .java
Spring Security 配置类

@SpringBootConfiguration
@EnableWebSecurity
public class Oauth2Config extends WebSecurityConfigurerAdapter {

    //配置passwordEncode的实现类对象
    @Bean
    public PasswordEncoder getPE(){
        return new BCryptPasswordEncoder();
    }

    //配置权限

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        http.csrf() .disable()
                //放行请求
                .authorizeRequests()
                .antMatchers("/oauth/**", "/login/**", "/logout/**")
                .permitAll()
                //除以上请求都拦截
                .anyRequest() .authenticated()
                .and()
                //放行登录界面
                .formLogin() .permitAll();
    }
}

授权服务器配置AuthorizationServerConfig.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client_id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型
                .authorizedGrantTypes("authorization_code","password");
    }
}

资源服务器配置ResourceServerConfig.java

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/user/**");//配置需要保护的资源路径
    }
}

测试结果

获取授权码:
http://localhost:8080/oauth/authorize?response_type=code&client_id=admin&redirect_uri=http://www.baidu.com&scope=all

sp_close_session 没权限_java_16

sp_close_session 没权限_CSRE_17

获取到授权码后,使用PostMan软件进行http://localhost:8080/oauth/token访问,并配置:》》》

sp_close_session 没权限_CSRE_18


sp_close_session 没权限_spring_19


sp_close_session 没权限_spring_20


发送请求后获取到令牌-----》》》》》》:

sp_close_session 没权限_Oauth2_21


配置上令牌进行访问:http://localhost:8080/user/getCurrentUser,通过令牌获取资源

sp_close_session 没权限_spring_22


如果修改token令牌则会报错


②、 密码模式

密码模式与授权模式相似,但相对而言密码模式相对简单,它只需要通过密码账号直接发送过去,就可以获得一个令牌通行证,即可获取到用户信息,使用的场景比如;微信和QQ ,两者都是一家产业,所以用户数据互通,完全不需要授权码去验证,免去了中间的繁琐,但也注定密码模式的格局小了,所以这里大致了解一下(重点还是授权码模式)。
小案例演示:(1) 只需要在授权码模式的基础上稍微修改即可

在Spring Security Config.java配置文件增加内容

@Bean
    @Override//身份验证管理器
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    //授权服务器配置类中需要用到AuthenticationManager接口,所以在这里配置他的实现类

(2) AuthorizationServerConfig.java增加内容:

@Autowired
 private AuthenticationManager authenticationManager;//认证管理器

 /**
     * 密码模式
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService);
    }

测试:

sp_close_session 没权限_Oauth2_23


sp_close_session 没权限_CSRE_24

sp_close_session 没权限_java_25

这样就测出来啦,可以将其存放在Redis中方便使用 完~