SPRINGBOOT SECURITY 权限控制 -- @PREAUTHORIZE 的使用
SPRINGBOOT SECURITY 权限控制 -- @PREAUTHORIZE 的使用
1. 说明
security 鉴权方式常用的有两种配置,1、配置文件中配置;2、使用注解标注;他们都是基于 acess 表达式,如果需要自定义逻辑的鉴权认证,只需要自定义 access 表达式即可。本文只选取注解的方式,来讲解默认的 access 和自定义的 access 表达式
2.基于注解的使用
2.1 使用前提条件:
注解默认不可用,通过开启注解:在配置类中开启注解 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Secured:专门判断用户是否具有角色,可以写在方法或类上,参数以 ROLE_ 开头
@PreAuthorize\PostAuthorize: PreAuthorize 访问的类或方法执行前判断权限,而 PostAuthorize 在执行之后,Post 基本不用;允许与 ROLE_ 开头。
2.2 基于默认的access表达式
在登录的时候,需要将用户权限返回给security;security才能实现权限控制功能;
具体步骤:
登录时,实现 UserDetailService,重写 loadUserByUsername(String userName)方法。根据 userName 来实现自己的业务逻辑返回 UserDetails 的实现类,需要自定义 User 类实现 UserDetails,比较重要的方法是 getAuthorities(),用来返回该用户所拥有的权限
@Datapublic class LoginUser implements UserDetails, Serializable { ... @Override public Collection<? extends GrantedAuthority> getAuthorities() { // 根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过 if (!permissions.isEmpty()) { List<GrantedAuthority> list = new ArrayList<GrantedAuthority>(); for (String temp : permissions) { GrantedAuthority au = new SimpleGrantedAuthority(temp); list.add(au); } return list; } return null; } }
然后在需要权限控制的controller方法上,添加注解@PreAuthorize("hasAuthority('..*')");其中@PreAuthorize括号中就是access表达式。具体默认的有哪些请参考官网。
@RestController@RequestMapping("test")public class TestController { @Autowired private ISysUserService userService; @Autowired private PermissionService permissionService; @PreAuthorize("hasAuthority('*.*.*')") @RequestMapping("userList") public ResultVo queryUserList() { List<SysUser> list = userService.list(); List<UserVo> result = list.stream().map(item -> permissionService.getUserInfo(item)).collect(Collectors.toList()); return ResultVo.success(result); } }
2.3 自定义access表达式
自定义权限认证业务逻辑,然后将该方法标注到注解上
package com.nanboone.framework.security.service;import java.util.Set;import com.nanboone.common.utils.ServletUtils;import com.nanboone.framework.security.domain.LoginUser;import com.nanboone.framework.token.JwtTokenUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.CollectionUtils;/** * AuthorityPermissionService:自定义access表达式,鉴权验证。 * 可以将自定义的access添加到配置类中:http.anyRequest.access(aps.hasPermission(xxx,xxx)); * 也可以直接使用注解@PreAuthorize:@PreAuthorize(aps.hasPermission(xxx)); * * @Author: dangbo * @Date: 2021/5/20 10:12 */@Service("aps")public class AuthorityPermissionService { @Autowired JwtTokenUtils jwtTokenUtils; public boolean hasPermission(String permissions) { if (StringUtils.isEmpty(permissions)) { return false; } // 用户信息对象 LoginUser loginUser = jwtTokenUtils.getLoginUser(ServletUtils.getRequest()); if (loginUser == null || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; } Set<String> authorities = loginUser.getPermissions(); for (String permission : permissions.split(",")) { if (StringUtils.isNotEmpty(permission) && hasPermissions(authorities, permission)) { return true; } } return false; } private boolean hasPermissions(Set<String> authorities, String permission) { return authorities.contains("*.*.*") || authorities.contains(permission.trim()); } }@RestController@RequestMapping("test")public class TestController { @Autowired private ISysUserService userService; @Autowired private PermissionService permissionService; @PreAuthorize("@aps.hasPermission('*.*.*')") @RequestMapping("userList") public ResultVo queryUserList() { List<SysUser> list = userService.list(); List<UserVo> result = list.stream().map(item -> permissionService.getUserInfo(item)).collect(Collectors.toList()); return ResultVo.success(result); } }
来源:https://www.cnblogs.com/dxiaodang/p/14793984.html