1、预置演示环境

这个演示环境继续沿用
SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境。

2、自定义配置类之请求授权详解

http.authorizeRequests()主要是对url进行访问权限控制,通过这个方法来实现url授权操作。
http.authorizeRequests()也支持链式写法,举例:
http.authorizeRequests() .url匹配规则1.权限控制方法1 .url匹配规则2.权限控制方法2...
如图
匹配顺序规则

​在所有匹配规则中取所有规则的交集。配置顺序影响了之后授权效果。

越是具体的应该放在前面,越是笼统的应该放到后面。

访问控制包含访问控制url匹配访问控制方法角色判断权限判断

2.1 访问控制url匹配

2.1.1 anyRequest()

anyRequest(),表示匹配所有的url请求

配置类代码示例:

http.authorizeRequests()// 匹配所有的请求,并且所有请求都需要登录认证.anyRequest().authenticated();

2.1.2 antMatcher(String regx)

  • 1)antMatcher(String regx),传递一个ant表达式参数,表示匹配所有满足ant表达式的请求

ant表达式中特殊字符解释

规则 解释说明
匹配一个字符
* 匹配0个或多个字符
** 匹配0个或多个目录

配置类代码示例:

http.authorizeRequests()// 允许登录页面匿名访问.antMatchers("/showLogin", "/errPage").anonymous()// 所有的静态资源允许匿名访问.antMatchers("/css/**","/js/**","/images/**","/fonts/**","/favicon.ico").anonymous()// 其他所有的请求都需要登录认证.anyRequest().authenticated();
  • 2)antMatcher(HttpMethod.*, String regx),传递一个请求方法类型参数加ant表达式参数,表示匹配所有满足ant表达式的指定请求方式的url

请求方式的枚举类如下:

配置类代码示例:

http.authorizeRequests()// 允许GET请求登录页面匿名访问.antMatchers(HttpMethod.GET, "/showLogin", "/errPage").anonymous();

2.1.3 regexMatchers(String regexPattern)

  • 1)regexMatchers(String regexPattern) 传递一个参数
    使用正则表达式进行匹配。和antMatchers()主要的区别就是参数,antMatchers()参数是ant表达式,而regexMatchers()参数是正则表达式。
    演示案例: 使用正则表达式放行一个名称以demo结尾的js文件,让用户可以匿名访问
http.authorizeRequests()// 匹配所有名称以demo结尾的js并允许匿名访问.regexMatchers(".+demo[.]js").anonymous();

  • 2)regexMatchers(HttpMethod.*, String regexPattern) 传递两个参数

演示案例: 使用正则表达式放行一个名称以demo结尾的js文件,让用户可以通过get请求匿名访问

http.authorizeRequests()// 匹配所有名称以demo结尾的js并允许匿名GET请求访问.regexMatchers(HttpMethod.GET, ".+demo[.]js").anonymous();

2.2 访问控制方法

在2.1中我们把spring security框架中怎么匹配请求url的方法都做了介绍, 现在我们说说spring security框架中提供的访问控制的方法,看看这些方法都有什么用,演示一下

方法名称 方法作用
permitAll() 表示所匹配的URL任何人都允许访问
anonymous() 表示可以匿名访问匹配的URL。和permitAll()效果类似,只是设置为anonymous()的url会执行filterChain中的filter
denyAll() 表示所匹配的URL都不允许被访问。
authenticated() 表示所匹配的URL都需要被认证才能访问
rememberMe() 允许通过remember-me登录的用户访问
access() SpringEl表达式结果为true时可以访问
fullyAuthenticated() 用户完全认证可以访问(非remember-me下自动登录)
hasRole() 如果有参数,参数表示角色,则其角色可以访问
hasAnyRole() 如果有参数,参数表示角色,则其中任何一个角色可以访问
hasAuthority() 如果有参数,参数表示权限,则其权限可以访问
hasAnyAuthority() 如果有参数,参数表示权限,则其中任何一个权限可以访问
hasIpAddress() 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问

访问控制方法都很简单, 只要匹配到url后直接在后面追加调用这个方法就行了,链式调用特别简单,不演示了。

2.3 角色、权限判断

说说需要传递参数的几个方法hasRole(), hasAnyRole(),hasAuthority(),hasAnyAuthority()等方法的使用,演示一下
之前我们预置了两个用户,给用户也设置了权限, 我们现在用这两个用户来演示一下角色和权限的访问控制

2.3.1 hasRole()

演示案列: 具有admin权限的用户才可以访问role.html

添加一个role.html

Controller类如下:

package com.kkarma.web.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class LoginController {@GetMapping("showLogin")public String showLogin(){return "login";}@RequestMapping("home")public String home(){return "home";}@RequestMapping("errPage")public String errPage(){return "error_page";}@RequestMapping("role")public String role(){return "role";}
}

配置类如下

http.authorizeRequests()// admin角色才可以访问/role.antMatchers(HttpMethod.GET, "/role").hasRole("admin")

admin用户登录后可以正常访问/role

common用户登录后可以无法访问/role, 无权限

2.3.2 hasAnyRole()

配置类如下

http.authorizeRequests()// admin或superAdmin角色才可以访问/role.antMatchers(HttpMethod.GET, "/role").hasAnyRole("admin","superAdmin")

2.3.3 hasAuthority()

修改了配置类中预置用户的代码, 给用户预置了权限

    /*** 在内存中预置两个演示用户admin和common*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password(bCryptPasswordEncoder().encode("123456")).roles("admin", "superAdmin").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("system,system:user,system:user:list")).and().withUser("common").password(bCryptPasswordEncoder().encode("123456")).roles("common").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("good,good:cate,good:cate:list"));

配置类如下

http.authorizeRequests()// 用户具有system:user权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasAuthority("system:user")

2.3.4 hasAnyAuthority()

配置类如下

http.authorizeRequests()// 用户具有system:user权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasAnyAuthority("system", "system:user")

2.3.5 access()

上面实现的访问控制的方法都可以使用access()来代替,因为他们本质上都是调用了access(),见下图

配置类如下

http.authorizeRequests()// 用户具有system:user权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").access("hasAuthority('system'"))// 用户具有system:user或system权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").access("hasAnyAuthority('system', 'system:user'"))

2.4 使用注解进行角色权限控制

首先如果要启动spring security提供的角色权限注解的话,需要在配置类上添加
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)注解,这样才能开启
@Secured和@PreAuthorize注解

2.4.1 @Secured注解的使用

package com.kkarma.web.controller;import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class LoginController {@GetMapping("showLogin")public String showLogin(){return "login";}@Secured("admin")@RequestMapping("home")public String home(){return "home";}@RequestMapping("errPage")public String errPage(){return "error_page";}@RequestMapping("role")public String role(){return "role";}@PreAuthorize("hasRole('admin')")@RequestMapping("index")public String index(){return "index";}
}

这里出现了一个bug, 控制器的方法上添加了@Secured(“ROLE_admin”)注解之后,访问仍提示403,这是为什么呢?后面再说这个问题怎么解决。

2.4.2 @PreAuthorize注解的使用

package com.kkarma.web.controller;import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class LoginController {@GetMapping("showLogin")public String showLogin(){return "login";}@RequestMapping("home")public String home(){return "home";}@RequestMapping("errPage")public String errPage(){return "error_page";}@RequestMapping("role")public String role(){return "role";}// 直接在类或者方法上添加@PreAuthorize()并传递权限判断方法的字符串和参数@PreAuthorize("hasRole('admin')")@RequestMapping("index")public String index(){return "index";}
}

2.4.3 @postAuthorize注解的使用

这个注解的主要作用就是将权限判断后置, 什么意思呢, @Secured和@PreAuthorize这两个注解都是对于request来进行判断, 而@postAuthorize这个注解是基于response的响应来进行授权操作的。
比如用户发来一个请求,服务器响应了一个数据, 我就针对这个响应数据跟我的预期结果是不是相符, 如果相符, 说明有权限访问, 如果不相符,说明权限不足,这里简单演示一下
演示代码很简单,一个字符串数据包含inout两个元素,随机获取一个元素,当取出的元素是in时允许用户访问,其他则无权限

package com.kkarma.web.controller;import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Random;@Controller
public class LoginController {@GetMapping("showLogin")public String showLogin(){return "login";}//    @Secured("admin")@RequestMapping("home")public String home(){return "home";}@RequestMapping("errPage")public String errPage(){return "error_page";}@RequestMapping("role")public String role(){return "role";}@PreAuthorize("hasRole('admin')")@RequestMapping("index")public String index(){return "index";}@PostAuthorize("returnObject=='in'")@RequestMapping("getStr")@ResponseBodypublic String getString() {String[] arr = {"in", "out"};return arr[new Random().nextInt(2)];}
}

响应结果获取到"in",匹配,说明you权限访问

响应结果获取到"out",不匹配,说明权限不足, 抛出403异常

2.5 自定义403异常返回处理

首先, 自定义403异常处理器

package com.kkarma.handler;import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.setHeader("Content-Type","application/json;charset=utf-8");PrintWriter out = response.getWriter();out.write("{\"code\":\"403\",\"msg\":\"权限不足,无法访问!\"}");out.flush();out.close();}
}

其次, 在spring security自定义配置类中注入该处理器对象,并通过http设置

package com.kkarma.config;import com.kkarma.handler.CustomAccessDeniedHandler;
import com.kkarma.web.service.impl.MyUserDetailsServiceImpl;
import org.apache.coyote.Adapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
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.WebSecurityConfigurer;
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.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {@Autowiredprivate CustomAccessDeniedHandler accessDeniedHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {/*** 配置csrf开启关闭,默认是开启的*/// http.csrf().disable();/*** 表单登录相关的配置*/http.formLogin()// 前端登录表单用户名别名, 从参数user中获取username参数取值.usernameParameter("user")// 前端登录表单密码别名, 从参数passwd中获取password参数取值.passwordParameter("passwd")// 当http请求的url是/login时,进行我们自定义的登录逻辑.loginProcessingUrl("/login")// 自定义登录的前端控制器.loginPage("/showLogin")// 设置登录成功的跳转链接// .successForwardUrl("/home");// 通过successHandler处理器进行登录成功之后的逻辑处理.successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {System.out.println("登录成功,页面即将跳转...");Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();authorities.forEach(System.out::println);response.sendRedirect("/home");}})// 设置登录失败的跳转链接// .failureForwardUrl("/errPage");// 通过failureHandler处理器进行登录失败之后的逻辑处理.failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {e.printStackTrace();System.out.println("登录失败,页面即将跳转到默认失败页...");response.sendRedirect("/errPage");}}).and()// 403权限不足异常使用自定义403处理器处理.exceptionHandling().accessDeniedHandler(accessDeniedHandler);/*** http请求是否要登录认证配置*/http.authorizeRequests()// 允许GET请求登录页面匿名访问.antMatchers(HttpMethod.GET, "/showLogin", "/errPage").anonymous()// 匹配所有名称以demo结尾的js并允许匿名访问.regexMatchers(HttpMethod.GET, ".+demo[.]js").anonymous()// 用户具有admin角色时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasRole("admin")// 用户具有system:user权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasAuthority("system:user")// 所有的静态资源允许匿名访问.antMatchers("/css/**","/js/**","/images/**","/fonts/**","/favicon.ico").anonymous()// 其他所有的请求都需要登录认证.anyRequest().authenticated();}/*** 在内存中预置两个演示用户admin和common*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password(bCryptPasswordEncoder().encode("123456")).roles("admin", "superAdmin").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("system,sytem:user,system:user:list")).and().withUser("common").password(bCryptPasswordEncoder().encode("123456")).roles("common").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("good,good:cate,good:cate:list"));}/*** 强散列哈希加密实现*/@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();}
}

重启项目, 再次访问/getStr, 当无权限访问时就是使用自定义的403进行处理响应。

2.6 用户退出

通过spring security框架我们可以自己自定义用户退出逻辑

具体的配置类信息

package com.kkarma.config;import com.kkarma.handler.CustomAccessDeniedHandler;
import com.kkarma.web.service.impl.MyUserDetailsServiceImpl;
import org.apache.coyote.Adapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
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.WebSecurityConfigurer;
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.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {@Autowiredprivate CustomAccessDeniedHandler accessDeniedHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {/*** 配置csrf开启关闭,默认是开启的*/http.csrf().disable();/*** 表单登录相关的配置*/http.formLogin()// 前端登录表单用户名别名, 从参数user中获取username参数取值.usernameParameter("user")// 前端登录表单密码别名, 从参数passwd中获取password参数取值.passwordParameter("passwd")// 当http请求的url是/login时,进行我们自定义的登录逻辑.loginProcessingUrl("/login")// 自定义登录的前端控制器.loginPage("/showLogin")// 设置登录成功的跳转链接// .successForwardUrl("/home");// 通过successHandler处理器进行登录成功之后的逻辑处理.successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {System.out.println("登录成功,页面即将跳转...");Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();authorities.forEach(System.out::println);response.sendRedirect("/home");}})// 设置登录失败的跳转链接// .failureForwardUrl("/errPage");// 通过failureHandler处理器进行登录失败之后的逻辑处理.failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {e.printStackTrace();System.out.println("登录失败,页面即将跳转到默认失败页...");response.sendRedirect("/errPage");}}).and()// 403权限不足异常使用自定义403处理器处理.exceptionHandling().accessDeniedHandler(accessDeniedHandler);// 用户退出登录处理配置http.logout().// 设置用户退出的urllogoutUrl("/logout")// 用户退出成功之后的跳转链接.logoutSuccessUrl("/showLogin")// 自定义用户的退出逻辑处理器, 可以处理认证信息、session、cookies等信息.addLogoutHandler(new LogoutHandler() {@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {// 这里可以自定义用户退出的处理逻辑System.out.println("退出成功...");}})// 是否清除认证状态,默认为true.clearAuthentication(true)// 是否销毁HttpSession对象,默认为true.invalidateHttpSession(true);/*** http请求是否要登录认证配置*/http.authorizeRequests()// 允许GET请求登录页面匿名访问.antMatchers(HttpMethod.GET, "/showLogin", "/errPage").anonymous()// 匹配所有名称以demo结尾的js并允许匿名访问.regexMatchers(HttpMethod.GET, ".+demo[.]js").anonymous()// 用户具有admin角色时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasRole("admin")// 用户具有system:user权限时允许访问/role.antMatchers(HttpMethod.GET, "/role").hasAuthority("system:user")// 所有的静态资源允许匿名访问.antMatchers("/css/**","/js/**","/images/**","/fonts/**","/favicon.ico").anonymous()// 其他所有的请求都需要登录认证.anyRequest().authenticated();}/*** 在内存中预置两个演示用户admin和common*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password(bCryptPasswordEncoder().encode("123456")).roles("admin", "superAdmin").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("system,sytem:user,system:user:list")).and().withUser("common").password(bCryptPasswordEncoder().encode("123456")).roles("common").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("good,good:cate,good:cate:list"));}/*** 强散列哈希加密实现*/@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();}
}

在首页home.html添加一个退出链接, 演示一下效果

重启项目, 测试一下
登录成功

点击用户退出,成功跳转到登录页面

这中间可能会出现退出登录抛出异常404,这是因为默认开启了csrf, 在配置类中关闭csrf重启即可解决

SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解相关推荐

  1. SpringSecurity权限管理框架系列(七)-SpringSecurity自定义配置类中自定义Filter的使用详解

    1.Filter请求过滤器 filter请求过滤器可以帮助我们进行HttpServletRequest请求和HttpServletResponse响应的过滤 在自定义的Filter过滤器中我们可以对我 ...

  2. Spring Security系列教程-Spring Security核心API讲解

    前言 经过前面几个章节的学习,一一哥 带大家实现了基于内存和数据库模型的认证与授权,尤其是基于自定义的数据库模型更是可以帮助我们进行灵活开发.但是前面章节的内容,属于让我们达到了 "会用&q ...

  3. Spring Security 框架详解

    SECURITY Spring Security框架 Spring Security框架主要解决了认证与授权的相关问题. 添加依赖 在Spring Boot项目中,需要使用Spring Securit ...

  4. 【Spring Security】Spring Security框架详解

    文章目录 前言 一.框架概述 Spring Security的架构 Spring Security的主要特点 二.认证 HTTP Basic认证 表单登录 OpenID Connect 三.授权 基于 ...

  5. SpringSecurity权限管理系统实战—六、SpringSecurity整合JWT

    文章目录 系列目录 前言 一.无状态登录 二.JWT介绍 1.什么是jwt 头部(Header) 载荷(Payload) 签名(Signature) 2.JWT工作流程 3.简单实现 三.整合JWT ...

  6. 关于Spring Security框架 关于单点登录sso

    1.Spring Security的作用 Spring Security主要解决了认证和授权相关的问题. 认证(Authenticate):验证用户身份,即登录. 授权(Authorize):允许用户 ...

  7. java 接口权限控制_手把手教你搞定权限管理,结合Spring Security实现接口的动态权限控制!...

    SpringBoot实战电商项目mall(30k+star)地址:github.com/macrozheng/- 摘要 权限控管理作为后台管理系统中必要的功能,mall项目中结合Spring Secu ...

  8. Spring Security框架

    Spring Security框架 关于用户身份认证与授权 Spring Security是用于解决认证与授权的框架. 添加依赖 <!-- Spring Boot Security:处理认证与授 ...

  9. spring security框架中在页面通过标签获取用户信息

    2019独角兽企业重金招聘Python工程师标准>>> spring security框架中,通过<@sec.authentication property="nam ...

最新文章

  1. 流量调整和限流技术 【转载】
  2. Web-Rtmp: 使用 WebSocket 在网页上播放 RTMP 直播流
  3. 使用python将数据导出excel表格
  4. PHP中cURL错误号对照[转]
  5. mysql star item 失败_解决CentOS7下MySQL服务启动失败的问题.md
  6. 关于E-Prime 2.0 无法呈现音频的一种解决方案
  7. win7变成xp风格了怎么改回_win7桌面怎么改成xp风格
  8. python实现bt下载器_10行 Python代码使用磁力链接批量下载种子
  9. @Transaction注解及失效详解
  10. 样条插值(Spline)
  11. Java软件工程师职位分析
  12. Python3从搜狐国际新闻抓取---完整版
  13. 迅为4418/6818开发板 Yocto 系统烧写
  14. Excel如何对合并单元格数据进行排序
  15. 【web实战-业务逻辑】评论点赞逻辑
  16. 【论文】联邦学习区块链 论文集(一)
  17. 故障电弧检测技术现状及难点
  18. 【历史上的今天】12 月 7 日:历史上第一次直播回放;唱片协会起诉 Napster;最大的梅森素数被发现
  19. 自动化攻击背景下的过去、现在与未来
  20. Mac开发利器之程序员编辑器MacVim学习总结

热门文章

  1. 余额宝收益创新低:存10万一天赚不到7块
  2. Redmi Note 8 Pro 救砖之路
  3. python打开csv文件乱码_python3写入csv乱码怎么解决
  4. Task01:概览西瓜书+南瓜书第1、2章(2天)
  5. 在vue项目或者react项目中实现图形验证码功能
  6. 词袋模型与TF-IDF模型
  7. DHL测试新包裹站,只需要一个App
  8. JS的对象与内置对象详细介绍
  9. 终极之shell-zsh全解析
  10. 担心鞋子开裂?3D打印能让材料自我修复了!| 技术前沿洞察