<properties>
<jjwt.version>0.9.0</jjwt.version>
<spring-security-jwt.version>1.0.9.RELEASE</spring-security-jwt.version>
</properties>
<!-- springsecurity-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>${spring-security-jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
package com.springcloud.blog.admin.config;
import com.springcloud.blog.admin.security.UserAuthenticationProvider;
import com.springcloud.blog.admin.security.UserPermissionEvaluator;
import com.springcloud.blog.admin.security.handler.*;
import com.springcloud.blog.admin.security.jwt.JWTAuthenticationTokenFilter;
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.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.web.access.expression.DefaultWebSecurityExpressionHandler;
/**
* SpringSecurity配置类
* @Author youcong
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启权限注解,默认是关闭的
public class SecurityConfig extends WebSecurityConfigurerAdapter {
*
* 自定义登录成功处理器
@Autowired
private UserLoginSuccessHandler userLoginSuccessHandler;
*
* 自定义登录失败处理器
UserLoginFailureHandler userLoginFailureHandler;
*
* 自定义注销成功处理器
UserLogoutSuccessHandler userLogoutSuccessHandler;
*
* 自定义暂无权限处理器
UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
*
* 自定义未登录的处理器
UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;
*
* 自定义登录逻辑验证器
UserAuthenticationProvider userAuthenticationProvider;
*
* 加密方式
* @Author youcong
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
*
* 注入自定义PermissionEvaluator
DefaultWebSecurityExpressionHandler userSecurityExpressionHandler(){
DefaultWebSecurityExpressionHandler handler = DefaultWebSecurityExpressionHandler();
handler.setPermissionEvaluator( UserPermissionEvaluator());
return handler;
}
*
* 配置登录验证逻辑
@Override
protected void configure(AuthenticationManagerBuilder auth){
这里可启用我们自己的登陆验证逻辑
auth.authenticationProvider(userAuthenticationProvider);
}
*
* 配置security的控制逻辑
* @Author youcong
* @Param http 请求
configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
不进行权限验证的请求或资源(从配置文件中读取)
.antMatchers(JWTConfig.antMatchers.split(",")).permitAll()
.antMatchers("/*").permitAll()
其他的需要登陆后才能访问
.anyRequest().authenticated()
.and()
配置未登录自定义处理类
.httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
.and()
配置登录地址
.formLogin()
.loginProcessingUrl(/login/userLogin)
配置登录成功自定义处理类
.successHandler(userLoginSuccessHandler)
配置登录失败自定义处理类
.failureHandler(userLoginFailureHandler)
.and()
配置登出地址
.logout()
.logoutUrl(/login/userLogout 配置用户登出自定义处理类
.logoutSuccessHandler(userLogoutSuccessHandler)
.and()
配置没有权限自定义处理类
.exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
.and()
开启跨域
.cors()
.and()
取消跨站请求伪造防护
.csrf().disable();
基于Token不需要session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
禁用缓存
http.headers().cacheControl();
添加JWT过滤器
http.addFilter( JWTAuthenticationTokenFilter(authenticationManager()));
}
}
package com.springcloud.blog.admin.config;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
*
* JWT配置类
* @Author youcong
@Getter
@Component
@ConfigurationProperties(prefix = jwt)
JWTConfig {
*
* 密钥KEY
*/
static String secret;
*
* TokenKey
String tokenHeader;
*
* Token前缀字符
String tokenPrefix;
*
* 过期时间
Integer expiration;
*
* 不需要认证的接口
String antMatchers;
setSecret(String secret) {
this.secret = secret;
}
setTokenHeader(String tokenHeader) {
this.tokenHeader = tokenHeader;
}
setTokenPrefix(String tokenPrefix) {
this.tokenPrefix = tokenPrefix;
}
setExpiration(Integer expiration) {
this.expiration = expiration * 1000;
}
setAntMatchers(String antMatchers) {
this.antMatchers = antMatchers;
}
}
# JWT配置
jwt:
# 密匙KEY
secret: JWTSecret
# HeaderKEY
tokenHeader: Authorization
# Token前缀字符
tokenPrefix: challenger-
# 过期时间 单位秒 1天后过期=86400 7天后过期=604800
expiration: 86400
# 配置不需要认证的接口
antMatchers: /index*,/login/**,/favicon.ico
# 有效时间
validTime: 7
package com.springcloud.blog.admin.security.handler;
import com.springcloud.blog.admin.config.JWTConfig;
import com.springcloud.blog.admin.security.entity.SelfUserEntity;
import com.springcloud.blog.admin.utils.AccessAddressUtil;
import com.springcloud.blog.admin.utils.JWTTokenUtil;
import com.springcloud.blog.admin.utils.RedisUtil;
import com.springcloud.blog.admin.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
*
* @Description 登录成功处理类
* @Author youcong
@Component
UserLoginSuccessHandler implements AuthenticationSuccessHandler {
*
* 登录成功返回结果
* @Author youcong
onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response,Authentication authentication){
组装JWT
SelfUserEntity selfUserEntity = (SelfUserEntity) authentication.getPrincipal();
String token = JWTTokenUtil.createAccessToken(selfUserEntity);
token = JWTConfig.tokenPrefix + token;
封装返回参数
Map<String,Object> resultData = new HashMap<>();
resultData.put(code",200);
resultData.put(msg登录成功token2.UserLoginFailureHandler.java
package com.springcloud.blog.admin.security.handler;
import com.springcloud.blog.admin.utils.ResultUtil;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
*
* @Description 登录失败处理类
* @Author youcong
UserLoginFailureHandler implements AuthenticationFailureHandler {
*
* 登录失败返回结果
* @Author youcong
onAuthenticationFailure(HttpServletRequest request,AuthenticationException exception){
这些对于操作的处理类可以根据不同异常进行不同处理
if (exception instanceof UsernameNotFoundException){
System.out.println(【登录失败】"+exception.getMessage());
ResultUtil.responseJson(response,ResultUtil.resultCode(500,1)">用户名不存在));
}
(exception instanceof LockedException){
System.用户被冻结 (exception instanceof BadCredentialsException){
System.密码错误));
}
ResultUtil.responseJson(response,1)">登录失败));
}
}
3.UserLogoutSuccessHandler.java
package com.springcloud.blog.admin.security.handler;
import com.springcloud.blog.admin.utils.DateUtil;
import com.springcloud.blog.admin.utils.RedisUtil;
import com.springcloud.blog.admin.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
*
* 登出成功处理类
* @Author youcong
UserLogoutSuccessHandler implements LogoutSuccessHandler {
*
* 用户登出返回结果
* 这里应该让前端清除掉Token
* @Author youcong
onLogoutSuccess(HttpServletRequest request,Authentication authentication){
Map<String,1)">登出成功);
SecurityContextHolder.clearContext();
ResultUtil.responseJson(response,ResultUtil.resultSuccess(resultData));
}
}
4.UserAuthAccessDeniedHandler.java
package com.springcloud.blog.admin.security.handler;
import com.springcloud.blog.admin.utils.ResultUtil;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
*
* @Description 暂无权限处理类
* @Author youcong
UserAuthAccessDeniedHandler implements AccessDeniedHandler {
*
* 暂无权限返回结果
* @Author youcong
handle(HttpServletRequest request,AccessDeniedException exception){
ResultUtil.responseJson(response,1)">403,1)">未授权));
}
}
5.UserAuthenticationEntryPointHandler.java
package com.springcloud.blog.admin.security.handler;
import com.springcloud.blog.admin.utils.ResultUtil;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
*
* 用户未登录处理类
* @Author youcong
UserAuthenticationEntryPointHandler implements AuthenticationEntryPoint {
*
* 用户未登录返回结果
* @Author youcong
commence(HttpServletRequest request,AuthenticationException exception){
ResultUtil.responseJson(response,1)">401,1)">未登录));
}
}
6.UserAuthenticationProvider.java
自定义登录验证这个类,需要根据实际情况重写。通常来说改动不大。
package com.springcloud.blog.admin.security;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.springcloud.blog.admin.entity.Usermeta;
import com.springcloud.blog.admin.entity.Users;
import com.springcloud.blog.admin.security.entity.SelfUserEntity;
import com.springcloud.blog.admin.service.UsermetaService;
import com.springcloud.blog.admin.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
*
* 自定义登录验证
*
* @Author youcong
UserAuthenticationProvider implements AuthenticationProvider {
@Autowired
UsersService usersService;
@Autowired
UsermetaService usermetaService;
@Override
Authentication authenticate(Authentication authentication) throws AuthenticationException {
获取表单输入中返回的用户名
String userName = (String) authentication.getPrincipal();
获取表单中输入的密码
String password = (String) authentication.getCredentials();
查询用户是否存在
SelfUserEntity userInfo = usersService.getUserInfo(userName);
if (userInfo.getUsername() == null || userInfo.getUsername() == "") {
throw new UsernameNotFoundException();
}
我们还要判断密码是否正确,这里我们的密码使用BCryptPasswordEncoder进行加密的
if (! BCryptPasswordEncoder().matches(password,userInfo.getPassword())) {
new BadCredentialsException(密码不正确);
}
还可以加一些其他信息的判断,比如用户账号已停用等判断
if (userInfo.getStatus().equals(1)) {
new LockedException(该用户已被冻结 角色集合
Set<GrantedAuthority> authorities = new HashSet<>();
EntityWrapper<Usermeta> roleWrapper = new EntityWrapper<>();
roleWrapper.eq(user_idmeta_keywp_user_level);
查询用户角色
List<Usermeta> sysRoleEntityList = usermetaService.selectList(roleWrapper);
for (Usermeta sysRoleEntity: sysRoleEntityList){
authorities.add(new SimpleGrantedAuthority(ROLE_" + sysRoleEntity.getMetaValue()));
}
userInfo.setAuthorities(authorities);
进行登录
UsernamePasswordAuthenticationToken(userInfo,password,authorities);
}
@Override
public boolean supports(Class<?> authentication) {
true;
}
}
7.UserPermissionEvaluator.java
package com.springcloud.blog.admin.security;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.springcloud.blog.admin.entity.Usermeta;
import com.springcloud.blog.admin.service.UsermetaService;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
*
* 自定义权限注解验证
* @Author youcong
UserPermissionEvaluator implements PermissionEvaluator {
@Autowired
UsermetaService usermetaService;
*
* hasPermission鉴权方法
* 这里仅仅判断PreAuthorize注解中的权限表达式
* 实际中可以根据业务需求设计数据库通过targetUrl和permission做更复杂鉴权
* 当然targetUrl不一定是URL可以是数据Id还可以是管理员标识等,这里根据需求自行设计
* @Author youcong
* @Param authentication 用户身份(在使用hasPermission表达式时Authentication参数默认会自动带上)
* @Param targetUrl 请求路径
* @Param permission 请求路径权限
* @Return boolean 是否通过
boolean hasPermission(Authentication authentication,Object targetUrl,Object permission) {
获取用户信息
Usermeta selfUserEntity =(Usermeta) authentication.getPrincipal();
查询用户权限(这里可以将权限放入缓存中提升效率)
Set<String> permissions = ();
EntityWrapper<Usermeta> roleWrapper = );
List<Usermeta> sysMenuEntityList = (Usermeta sysMenuEntity:sysMenuEntityList) {
permissions.add(sysMenuEntity.getMetaValue());
}
权限对比
(permissions.contains(permission.toString())){
;
}
;
}
@Override
false;
}
}
五、编写实体类
package com.springcloud.blog.admin.security.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
*
* SpringSecurity用户的实体
* 注意:这里必须要实现UserDetails接口
*
* @Author youcong
*/
SelfUserEntity implements Serializable,UserDetails {
private static final long serialVersionUID = 1L;
*
* 用户ID
Long userId;
*
* 用户名
String username;
*
* 密码
String password;
*
* 状态
String status;
*
* 显示名称
String displayName;
*
* 用户参数
private Map<String,String> userParamMap;
*
* 用户角色
private Collection<GrantedAuthority> authorities;
*
* 账户是否过期
private boolean isAccountNonExpired = ;
*
* 账户是否被锁定
private boolean isAccountNonLocked = *
* 证书是否过期
private boolean isCredentialsNonExpired = *
* 账户是否有效
private boolean isEnabled = ;
static long getSerialVersionUID() {
serialVersionUID;
}
Long getUserId() {
userId;
}
setUserId(Long userId) {
this.userId = userId;
}
@Override
String getUsername() {
username;
}
setUsername(String username) {
this.username = username;
}
@Override
String getPassword() {
password;
}
setPassword(String password) {
this.password = password;
}
void setAuthorities(Collection<GrantedAuthority> authorities) {
this.authorities = authorities;
}
setEnabled(boolean enabled) {
isEnabled = enabled;
}
setStatus(String status) {
this.status = status;
}
String getStatus() {
String getDisplayName() {
displayName;
}
setDisplayName(String displayName) {
this.displayName =public Map<String,1)"> getUserParamMap() {
userParamMap;
}
void setUserParamMap(Map<String,1)"> userParamMap) {
this.userParamMap = userParamMap;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
authorities;
}
@Override
boolean isAccountNonExpired() {
isAccountNonExpired;
}
@Override
boolean isAccountNonLocked() {
isAccountNonLocked;
}
@Override
boolean isCredentialsNonExpired() {
isCredentialsNonExpired;
}
@Override
boolean isEnabled() {
isEnabled;
}
}
六、编写JWT接口请求拦截器
package com.springcloud.blog.admin.security.jwt;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.springcloud.blog.admin.config.JWTConfig;
import com.springcloud.blog.admin.security.entity.SelfUserEntity;
import com.springcloud.blog.admin.utils.CollectionUtil;
import com.springcloud.blog.admin.utils.JWTTokenUtil;
import com.springcloud.blog.admin.utils.RedisUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;
import javax.servlet.FilterChain;
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.List;
import java.util.Map;
*
* JWT接口请求校验拦截器
* 请求接口时会进入这里验证Token是否合法和过期
*
* @Author youcong
JWTAuthenticationTokenFilter extends BasicAuthenticationFilter {
JWTAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
doFilterInternal(HttpServletRequest request,FilterChain filterChain) throws ServletException,IOException {
获取请求头中JWT的Token
String tokenHeader = request.getHeader(JWTConfig.tokenHeader);
if (null != tokenHeader && tokenHeader.startsWith(JWTConfig.tokenPrefix)) {
try {
截取JWT前缀
String token = tokenHeader.replace(JWTConfig.tokenPrefix,1)">);
解析JWT
Claims claims = Jwts.parser()
.setSigningKey(JWTConfig.secret)
.parseClaimsJws(token)
.getBody();
获取用户名
String username = claims.getSubject();
String userId = claims.getId();
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(userId)) {
获取角色
List<GrantedAuthority> authorities = new ArrayList<>();
String authority = claims.get(authorities).toString();
StringUtils.isEmpty(authority)) {
List<Map<String,String>> authorityMap = JSONObject.parSEObject(authority,List.);
for (Map<String,1)"> role : authorityMap) {
StringUtils.isEmpty(role)) {
authorities.add(new SimpleGrantedAuthority(role.authority)));
}
}
}
组装参数
SelfUserEntity selfUserEntity = SelfUserEntity();
selfUserEntity.setUsername(claims.getSubject());
selfUserEntity.setUserId(Long.parseLong(claims.getId()));
selfUserEntity.setAuthorities(authorities);
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken(selfUserEntity,userId,authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (ExpiredJwtException e) {
System.Token过期);
} (Exception e) {
System.Token无效);
}
}
filterChain.doFilter(request,response);
;
}
}
七、SpringSecurity用户的业务实现
package com.springcloud.blog.admin.security.service;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.springcloud.blog.admin.entity.Users;
import com.springcloud.blog.admin.security.entity.SelfUserEntity;
import com.springcloud.blog.admin.service.UsersService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
*
* SpringSecurity用户的业务实现
*
* @Author youcong
SelfUserDetailsService implements UserDetailsService {
@Autowired
UsersService usersService;
*
* 查询用户信息
*
* @Author youcong
* @Param username 用户名
* @Return UserDetails SpringSecurity用户信息
SelfUserEntity loadUserByUsername(String username) throws UsernameNotFoundException {
EntityWrapper<Users> wrapper = ();
邮箱正则表达式
String expr = ^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$;
是否为邮箱
(username.matches(expr)) {
wrapper.eq(user_emailelse {
wrapper.eq(user_login 查询用户信息
Users sysUserEntity = usersService.selectOne(wrapper);
if (sysUserEntity != null 组装参数
SelfUserEntity selfUserEntity = SelfUserEntity();
BeanUtils.copyProperties(sysUserEntity,selfUserEntity);
selfUserEntity;
}
;
}
}
八、Spring Security常用注解
1.@Secured
当@EnableGlobalMethodSecurity(securedEnabled=true)的时候,@Secured可以使用。
@PostMapping(/helloUser)
@Secured({ROLE_normalROLE_admin})
initDashboard() {
Map<String,Object> result = ();
result.put(ResponseDict.RESPONSE_TITLE_KEY,1)">仪表盘初始化);
result.put(ResponseDict.RESPONSE_DATA_KEY,dashboardService.initDashboard());
ResultUtil.resultSuccess(result);
}
说明:拥有normal或者admin角色的用户都可以方法helloUser()方法。另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“。
2.@PreAuthorize
Spring的 @PreAuthorize/@PostAuthorize 注解更适合方法级的安全,也支持Spring 表达式语言,提供了基于表达式的访问控制。
当@EnableGlobalMethodSecurity(prePostEnabled=true)的时候,@PreAuthorize可以使用:
@PostMapping(/initDashboard)
@PreAuthorize(hasRole('100') initDashboard() {
Map<String,1)">();
result.put(ResponseDict.RESPONSE_TITLE_KEY,1)">);
result.put(ResponseDict.RESPONSE_DATA_KEY,dashboardService.initDashboard());
ResultUtil.resultSuccess(result);
}
3.@PostAuthorize
@PostAuthorize 注解使用并不多,在方法执行后再进行权限验证,适合验证带有返回值的权限,Spring EL 提供 返回对象能够在表达式语言中获取返回的对象returnObject。
当@EnableGlobalMethodSecurity(prePostEnabled=true)的时候,@PostAuthorize可以使用:
@GetMapping(/getUserInfo)
@PostAuthorize( returnObject!=null && returnObject.username == authentication.name User getUserInfo() {
Object pricipal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user;
if(anonymousUser.equals(pricipal)) {
user = ;
} {
user = (User) pricipal;
}
user;
}
九、测试
(1)登录测试,拿到token,如图:

?
?

(2)请求中如果不携带token的话,请求其它接口就会显示没有登录的提示,如图:

?
?

(3)正确的请求应当携带token,就像下面这样,如图:

?
?

(4)没有权限请求,如图:

?
?

(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!