springboo整合security——权限设置

本文详细介绍了如何在Spring Boot项目中实现基于URL的权限管理,包括数据库表设计、实体类、Mapper、Service的创建,以及如何使用PermissionEvaluator进行权限验证。

一、数据准备

1.1 创建permission 表

创建一张permission表

CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `url` varchar(255) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  `permission` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

初始化两条数据

INSERT INTO chapter03.permission(id, url, role_id, permission) VALUES (1, ‘/admin’, 1, ‘c,r,u,d’);
INSERT INTO chapter03.permission(id, url, role_id, permission) VALUES (2, ‘/admin’, 2, ‘r’);

1.2 创建 entity、Mapper、Service

(1)、创建permission实体

package com.sl.entity;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

/**
 * @author shuliangzhao
 * @Title: Permission
 * @ProjectName spring-boot-learn
 * @Description: TODO
 * @date 2019/8/6 19:22
 */
public class Permission implements Serializable {

    private Integer id;

    private String url;

    private Integer roleId;

    private String permission;

    private List<String> permissions;

    public List<String> getPermissions() {
        return Arrays.asList(this.permission.trim().split(","));
    }

    public void setPermissions(List<String> permissions) {
        this.permissions = permissions;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }
}

这里需要注意的时相比于数据库,多了一个 permissions 属性,该字段将 permission 按逗号分割为了 list。
(2)、创建permissionMapper

@Mapper
public interface PermissionMapper {

    @Select("SELECT * FROM permission where role_id = #{id}")
    List<Permission> selectListById(Integer id);
}

(3)、创建permissionService

@Service
public class PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    public List<Permission> selectListById(Integer id) {
         return permissionMapper.selectListById(id);
    }
}

1.3 修改接口

@Controller
public class LoginController {
    ...

    @RequestMapping("/admin")
    @ResponseBody
    @PreAuthorize("hasPermission('/admin','r')")
    public String printAdminR() {
        return "如果你看见这句话,说明你访问/admin路径具有r权限";
    }

    @RequestMapping("/admin/c")
    @ResponseBody
    @PreAuthorize("hasPermission('/admin','c')")
    public String printAdminC() {
        return "如果你看见这句话,说明你访问/admin路径具有c权限";
    }
}
让我们修改下我们要访问的接口,@PreAuthorize("hasPermission('/admin','r')")是关键,参数1指明了访问该接口需要的url,参数2指明了访问该接口需要的权限。

二、PermissionEvaluator

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @Override
    public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
        // 获得loadUserByUsername()方法的结果
        /*String userName = (String) authentication.getPrincipal();
        User user = userService.selectByName(userName);*/
        // 获得loadUserByUsername()中注入的角色
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        // 遍历用户所有角色
        for (GrantedAuthority authority:authorities) {
            String roleName = authority.getAuthority();
            Integer rId = roleService.selectByName(roleName).getId();
            // 得到角色所有的权限
            List<Permission> permissions = permissionService.selectListById(rId);

            // permissions
            for (Permission per:permissions) {
                //获取权限集
                List<String> permissions1 = per.getPermissions();
                if (targetUrl.equals(per.getUrl()) && permissions1.contains(permission)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

在 hasPermission() 方法中,参数 1 代表用户的权限身份,参数 2 参数 3 分别和 @PreAuthorize(“hasPermission(’/admin’,‘r’)”) 中的参数对应,即访问 url 和权限。

思路如下:

  1. 通过 Authentication 取出登录用户的所有 Role
  2. 遍历每一个 Role,获取到每个Role的所有 Permission
  3. 遍历每一个 Permission,只要有一个 Permission 的 url 和传入的url相同,且该 Permission 中包含传入的权限,返回 true
  4. 如果遍历都结束,还没有找到,返回false

下面就是在 WebSecurityConfig 中注册 CustomPermissionEvaluator

@Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setPermissionEvaluator(customPermissionEvaluator);
return defaultWebSecurityExpressionHandler;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值