爱收集资源网

两大安全框架分享

网络整理 2022-04-28 15:00

前言

安全框架没有合适权限访问项目,我们一般直接使用最流行的两个安全框架:SpringSecruity、Shiro,但是有时候我们只是想用一些简单的、低级的权限控制,又不想那么多拦截器/过滤器,那么就需要一个简单的权限验证工具

权限控制无非就是:前端控件是否可见,是否允许请求/访问URL,本文分享一个简单的URL访问权限验证,支持/、/*、/*/a、/**等。

代码

package cn.huanzi.qch.util;
import java.util.Arrays;
/**
 * 一个简单的URL访问权限校验工具类
 */
public class UrlSecurityUtil {
    /**
     * 检查requestUri是否包含在urls中
     */
    public static boolean checkUrl(String requestUri,String[] urls){
        //对/进行特殊处理
        if("/".equals(requestUri) && !Arrays.asList(urls).contains(requestUri)){
            return false;
        }
        String[] requestUris = requestUri.split("/");
        for (int i = 0; i < urls.length; i++) {
            if(check(requestUris,urls[i].split("/"))){
                return true;
            }
        }
        return false;
    }
    private static boolean check(String[] requestUris,String[] urls){
        for (int i1 = 0; i1 < requestUris.length; i1++) {
            //判断长度
            if (i1 >= urls.length){
                return false;
            }
            //处理/*、/**情况
            if("**".equals(urls[i1])){
                return true;
            }
            if("*".equals(urls[i1])){
                continue;
            }
            //处理带后缀
            if(requestUris[i1].contains(".") && urls[i1].contains(".")){
                String[] split = requestUris[i1].split("\\.");
                String[] split2 = urls[i1].split("\\.");
                // *.后缀的情况
                if("*".equals(split2[0]) && split[1].equals(split2[1])){
                    return true;
                }
            }
            //不相等
            if(!requestUris[i1].equals(urls[i1])){
                return false;
            }
        }
        return true;
    }
}

测试,效果

    public static void main(String[] args) {
        //无需权限即可访问的URL
        String[] urls = {"/a/js/*.js","/a/img/**"};
        //给用户配置的URL访问权限
        HashMap user = new HashMap<>();
        user.put("username","张三");
        user.put("urls",new String[]{"/","/a/css/*/common.css","/b/b1","/c/*","/d/**"});
        //满足其中一种情况,就允许访问
        String[] urlz = {
                "/",
                "/a/css/a/common.css",
                "/a/css/a/a1/common.css",
                "/a/js/layui.js",
                "/a/js/layui.css",
                "/a/img/a/a.jpg",
                "/a/img/a1.png",
                "/b/b1",
                "/b/b2",
                "/c/c1",
                "/c/c1/c2",
                "/d/d1/d2",
        };
        for (String url : urlz) {
            boolean flag = UrlSecurityUtil.checkUrl(url,urls) ||
                    UrlSecurityUtil.checkUrl(url,(String[])user.get("urls"));
            System.out.println(url+","+(flag ? "允许访问!" : "无权访问..."));
        }
    }

后记

通过基本的 URL 权限控制,您可以配置一个权限键对应多个 URL,然后将权限键分配给用户:

{
    "ROLE_SA":{
        "/a/a1",
        "/b/*",
    },
    "ROLE_USER":{
        "/c/c1",
        "/d/*",
    }
}

有了权限键基础后,可以配置一个角色对应多个权限键没有合适权限访问项目,然后给用户分配角色:

{
    "部门经理":{
        "ROLE_SA",
        "ROLE_USER",
    },
    "普通员工":{
        "ROLE_USER",
    }
}

从高层建筑到平坦的地面,基于这些基础,我们可以推进一套自己的安全框架!

框架