248.Spring Boot+Spring Security:基于URL动态权限:准备工作

Posted SpringBoot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了248.Spring Boot+Spring Security:基于URL动态权限:准备工作相关的知识,希望对你有一定的参考价值。

说明

(1)JDK版本:1.8

(2)Spring Boot 2.0.6

(3)Spring Security 5.0.9

(4)Spring Data JPA 2.0.11.RELEASE

(5)hibernate5.2.17.Final

(6)mysqlDriver 5.1.47

(7)MySQL 8.0.12

 

需求缘起

       在上一节说明了几种方案,但是不管是选择哪一种方案,权限持久化相关操作总是少不了的,本节先做下准备工作。

 

一、准备工作

1.1 创建实体类Permission

创建实体类,用于存储权限的信息:

package com.kfit.permission.bean;

import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

@Entity
public class Permission {
    @Id @GeneratedValue
    private long id;//主键.

    private String name;//权限名称.

    private String description;//权限描述.  

    /**
     *  注意:Permission 表的url通配符为两颗星,比如说 /user下的所有url,应该写成 /user/**;
     */

    private String url;//授权链接

    private long pid;//父节点id.


    // 角色 - 权限是多对多的关系
    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="RolePermission",joinColumns= {@JoinColumn(name="permission_id")} , inverseJoinColumns= {@JoinColumn(name="role_id")})
    private List<Role> roles;

    public long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

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

    public long getPid() {
        return pid;
    }

    public void setPid(long pid) {
        this.pid = pid;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
}

说明:这里使用@ManyToMany建立权限和角色的多对多的关系。

 

1.2 创建持久化PermissionRepository

       创建持久化PermissionRepository:

package com.kfit.permission.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.kfit.permission.bean.Permission;

public interface PermissionReporitory extends JpaRepository<PermissionLong> {

}

 

1.3 初始化数据

       在DataInit中初始化权限的信息:

//p.1 inject permission repository
@Autowired 
    private PermissionReporitory permissionReporitory;


//p.2 permission.save
        //permission.
        Permission permission1 = new Permission();
        permission1.setUrl("/hello/helloUser");
        permission1.setName("普通用户URL");
        permission1.setDescription("普通用户的访问路径");
        permission1.setRoles(roles);
        permissionReporitory.save(permission1);

        Permission permission2 = new Permission();
        permission2.setUrl("/hello/helloAdmin");
        permission2.setName("管理员URL");
        permission2.setDescription("管理员的访问路径");
        List<Role> roles2 = new ArrayList<>();
        roles2.add(adminRole);
        permission2.setRoles(roles2);
        permissionReporitory.save(permission2);


启动测试下,会自动创建表:

248.Spring Boot+Spring Security:基于URL动态权限:准备工作

       我们看下permission和role_permission的数据:


 

1.4 加载权限信息

       我们将保存的权限信息在程序启动的时候,加载到一个Map中,这里使用@PostConstruct进行启动初始化。

       先提供一个接口PermissionService:

public interface PermissionService {

    public Map<String, Collection<ConfigAttribute>> getPermissionMap();

}


       具体的实现PermissionServiceImpl:

package com.kfit.permission.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.stereotype.Service;

import com.kfit.permission.bean.Permission;
import com.kfit.permission.bean.Role;
import com.kfit.permission.repository.PermissionReporitory;
import com.kfit.permission.service.PermissionService;

@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private PermissionReporitory permissionReporitory;

    private Map<String, Collection<ConfigAttribute>> permissionMap =null;

    @PostConstruct
    public void initPermissions() {
        System.out.println("PermissionServiceImpl.initPermissions()");
        permissionMap = new HashMap<>();
        Collection<ConfigAttribute> collection;
        ConfigAttribute cfg;

        List<Permission> permissions = permissionReporitory.findAll();
        for(Permission p:permissions) {
            collection = new ArrayList<ConfigAttribute>();
            for(Role r:p.getRoles()) {
                cfg = new SecurityConfig("ROLE_"+r.getName());
                collection.add(cfg);
            }
            permissionMap.put(p.getUrl(),collection);
        }
        System.out.println(permissionMap);
    }

    @Override
    public Map<String, Collection<ConfigAttribute>> getPermissionMap() {
if(permissionMap.size()==0) initPermissions();
        return permissionMap;
    }
}

说明:这里map中的value是Collection<ConfigAttribute>的原因是在SecurityMetadataSource接口的getAttributes方法的返回值就是Collection<ConfigAttribute>类型,这样方便在匹对正确的情况下直接返回。

       启动可以看到控制台的打印信息:

{
/hello/helloAdmin=[ROLE_admin, ROLE_normal], 

/hello/helloUser=[ROLE_normal]
}

 

历史文章













我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

à悟空学院:http://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/R3QepWG

Spring Cloud视频:http://t.cn/R3QeRZc

SpringBoot Shiro视频:http://t.cn/R3QDMbh

SpringBoot交流平台:http://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/R1pSojf

SpringSecurity5.0视频:http://t.cn/EwlLjHh

Sharding-JDBC分库分表实战:http://t.cn/E4lpD6e

以上是关于248.Spring Boot+Spring Security:基于URL动态权限:准备工作的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 之注解

Spring boot??????????????????Spring boot??????MySql,Mybatis???PageHelper??????

Spring Boot 事物回滚

使用 Spring Boot 时如何使用 SpringTemplateEngine

jboss spring boot

spring boot微服务通用部署启动脚本