package com.usthe.sureness.matcher.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
* Improved dictionary matching tree
* support regular: str*str, *, **
* the * in str*str can match zero or more character eg: *.html -> content.html
* the * can match zero or one directory
* the ** can match zero or more directories
* Match priority: Raw string > str*str > * > **
* @author tomsun28
* @date 19:25 2019-01-18
*/
public class TirePathTree {
private static final Logger logger = LoggerFactory.getLogger(TirePathTree.class);
private static final String NODE_TYPE_PATH_NODE = "pathNode";
private static final String NODE_TYPE_MAY_PATH_END = "mayPathEnd";
private static final String NODE_TYPE_METHOD = "methodNode";
private static final String NODE_TYPE_FILTER_ROLES = "rolesNode";
private static final String URL_PATH_SPLIT = "/";
private static final String MATCH_ALL_METHOD = "*";
private static final String MATCH_ONE_PATH = "*";
private static final String MATCH_MULTI_PATH = "**";
private static final int PATH_NODE_NUM_3 = 3;
private static final int PATH_NODE_NUM_2 = 2;
private static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/+");
/**
* str - Pattern.compile(str)
*/
private static final Map<String, Pattern> PATTERN_MAP = new HashMap<>(8);
/**
* root node
*/
private volatile Node root;
public TirePathTree() {
this.root = new Node("root");
}
/**
* build dictionary matching tree
* @param paths resource path set
*/
public synchronized void buildTree(Set<String> paths) {
if (logger.isDebugEnabled()) {
logger.debug("sureness - start buildTree...");
}
clearTree();
for (String path : paths) {
insertNode(path, this.root);
}
if (logger.isDebugEnabled()) {
logger.debug("sureness - buildTree finish");
}
}
/**
* rebuild and update dictionary matching tree
* Concurrency type:RCU -- read copy update
* Ensure that reading is not affected during reconstruction
* @param paths resources paths set
*/
public synchronized void rebuildTree(Set<String> paths) {
if (logger.isDebugEnabled()) {
logger.debug("sureness - start rebuildTree..., try rcu current way");
}
Node buildRoot = new Node("root");
for (String path : paths) {
insertNode(path, buildRoot);
}
this.root = buildRoot;
if (logger.isDebugEnabled()) {
logger.debug("sureness - rebuildTree finish");
}
}
/**
* clear dictionary matching tree
*/
public void clearTree() {
if (logger.isDebugEnabled()) {
logger.debug("sureness - clearTree");
}
root.getChildren().clear();
}
/**
* Get the number of resources (URL+METHOD) in the current matching tree
* @return int resource number
*/
public int getResourceNum() {
int resourceNum = 0;
// Breadth First Search - bfs
Queue<Node> resourceList = new LinkedList<>();
resourceList.add(root);
while (!resourceList.isEmpty()) {
Node currentNode = resourceList.poll();
if (currentNode.getMethodChildren() != null && !currentNode.getMethodChildren().isEmpty()) {
resourceNum += currentNode.getMethodChildren().size();
}
if (currentNode.getChildren() != null && !currentNode.getChildren().isEmpty()) {
resourceList.addAll(currentNode.getChildren().values());
}
}
if (logger.isDebugEnabled()) {
logger.debug("sureness - current PathTree resource num is: {}", resourceNum);
}
return resourceNum;
}
/**
* Use the resource path to match supported roles in tree
* @param path /api/v2/host/detail===get
* @return java.lang.String roles eg: [role1,role2]
*/
public String searchPathFilterRoles(String path) {
if (path == null || "".equals(path)) {
return null;
}
if (logger.isTraceEnabled()) {
logger.trace("sureness - searchPathFilterRoles, path is {}", path);
}
if (!path.startsWith(URL_PATH_SPLIT)) {
path = URL_PATH_SPLIT.concat(path);
}
path = PATH_SPLIT_PATTERN.matcher(path).replaceAll("/");
path = path.substring(1).toLowerCase();
String[] tmp = path.split("===");
if (tmp.length != PATH_NODE_NUM_2) {
return null;
}
String[] urlPac = tmp[0].split("/");
String method = tmp[1];
// Pattern matching * **
Node current = root;
return searchPathRoleInChildren(current, urlPac, -1, method);
}
/**
* Find the leaf node of the corresponding branch from the current node
* @param current current node
* @param urlPac urlPath arr
* @param currentFlow current Flow
* @param method http method: post get delete put...
* @return match return roles eg:[role,role2], else return null
*/
private String searchPathRole(Node current, String[] urlPac, int currentFlow, String method) {
if (current == null || urlPac == null || currentFlow >= urlPac.length
|| currentFlow < 0 || method == null || "".equals(method)) {
return null;
}
String currentNodeData = current.getData();
// fast fail
if (isNoMatchString(currentNodeData, urlPac[currentFlow])) {
return null;
}
if (currentFlow == urlPac.length - 1 && (NODE_TYPE_MAY_PATH_END.equals(current.getNodeType()))) {
Node methodNode = current.getMethodChild(method);
if (methodNode != null) {
if (NODE_TYPE_METHOD.equals(methodNode.getNodeType())) {
return methodNode.getChildren().keySet().iterator().next();
}
} else {
Node nextNode = current.getMethodChild(MATCH_ALL_METHOD);
if (nextNode != null && NODE_TYPE_METHOD.equals(nextNode.getNodeType())) {
return nextNode.getChildren().keySet().iterator().next();
}
nextNode = current.getChildren().get(MATCH_ONE_PATH);
if (nextNode != null && NODE_TYPE_MAY_PATH_END.equals(nextNode.getNodeType())) {
methodNode = nextNode.getMethodChild(method);
methodNode = methodNode == null ? nextNode.getMethodChild(MATCH_ALL_METHOD) : methodNode;
if (methodNode != null && NODE_TYPE_METHOD.equals(methodNode.getNodeType())) {
return methodNode.getChildren().keySet().iterator().next();
}
}
nextNode = current.getChildren().get(MATCH_MULTI_PATH);
if (nextNode != null && NODE_TYPE_MAY_PATH_END.equals(nextNode.getNodeType())) {
methodNode = nextNode.getMethodChild(method);
methodNode = methodNode == null ? nextNode.getMethodChild(MATCH_ALL_METHOD) : methodNode;
if (methodNode != null && NODE_TYPE_METHOD.equals(methodNode.getNodeType())) {
return methodNode.getChildren().keySet().iterator().next();
}
}
}
}
String matchRole = null;
if (currentNodeData.equals(urlPac[currentFlow]) || isPatternStr(currentNodeData)) {
matchRole = searchPathRoleInChildren(current, urlPac, currentFlow, method);
if (matchRole != null) {
return matchRole;
}
}
if (currentNodeData.equals(MATCH_
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
本项目是一个基于Java的面向REST API的高性能认证鉴权框架设计源码,共包含626个文件,其中包括227个Java文件、125个Markdown文件等。系统采用了Java、CSS、JavaScript、HTML和Kotlin等技术,为用户提供了一个功能强大的API安全保护解决方案。系统设计注重性能和安全性,采用了模块化的开发方式,便于后续的扩展和维护。
资源推荐
资源详情
资源评论
收起资源包目录
基于Java的面向REST API高性能认证鉴权框架设计源码 (616个子文件)
application.conf 167B
custom.css 8KB
navbar.css 3KB
styles.module.css 3KB
Robot.module.css 3KB
highlight.module.css 2KB
Sponsor.module.css 1KB
LogoCarousel.module.css 1KB
hero.css 653B
Section.module.css 366B
docsearch.css 339B
buttons.css 302B
Feature.module.css 198B
.dockerignore 75B
spring.factories 177B
Dockerfile.fast-jar 2KB
.gitignore 353B
.gitignore 308B
.gitignore 233B
.gitignore 46B
index.html 4KB
index.html 4KB
index.html 245B
org.springframework.boot.autoconfigure.AutoConfiguration.imports 111B
TirePathTree.java 18KB
SurenessAutoConfiguration.java 14KB
SurenessAutoConfiguration.java 13KB
JsonWebTokenUtil.java 11KB
ClassScanner.java 11KB
SimulateController.java 8KB
TirePathTreeTest.java 7KB
SimulateController.java 7KB
SimulateController.java 7KB
DigestSubject.java 7KB
RoleController.java 6KB
DefaultSurenessConfig.java 5KB
DefaultPathRoleMatcher.java 5KB
SurenessJakartaServletFilter.java 5KB
SurenessConfiguration.java 5KB
DigestProcessor.java 5KB
SurenessFilter.java 5KB
SurenessFilterExample.java 5KB
SurenessFilterExample.java 5KB
SurenessFilterExample.java 5KB
SurenessSecurityManager.java 5KB
JwtSubject.java 5KB
SurenessConfiguration.java 5KB
SurenessConfiguration.java 5KB
SurenessFilterExample.java 5KB
PasswordSubject.java 5KB
CustomTokenSubject.java 5KB
SurenessSecurityManagerTest.java 5KB
ServletUtil.java 4KB
Application.java 4KB
SessionSubject.java 4KB
AccountController.java 4KB
AccountServiceImpl.java 4KB
DigestSubjectJakartaServletCreator.java 4KB
DigestSubjectServletCreator.java 4KB
CustomTokenProcessor.java 4KB
RoleServiceImpl.java 4KB
SurenessProperties.java 4KB
DigestSubjectSpringReactiveCreator.java 4KB
SurenessFilter.java 4KB
DigestSubjectJaxRsCreator.java 4KB
ResourceController.java 4KB
SurenessProperties.java 4KB
DocumentResourceDefaultProvider.java 4KB
DigestSubjectSolonCreator.java 4KB
DigestSubjectSolonCreator.java 4KB
DefaultPathRoleMatcherTest.java 4KB
SurenessConfiguration.java 4KB
AnnotationPathTreeProvider.java 4KB
SurenessConfiguration.java 4KB
SurenessFilter.java 4KB
GlobalExceptionHandler.java 4KB
SurenessConfiguration.java 4KB
JsonWebTokenUtilTest.java 4KB
XssSqlUtil.java 4KB
AuthResourceDaoTest.java 3KB
PasswordProcessor.java 3KB
SurenessCommonUtil.java 3KB
SurenessConfiguration.java 3KB
AuthRoleResourceBindDaoTest.java 3KB
JwtProcessor.java 3KB
SinglePrincipalMap.java 3KB
BasicSubjectJakartaServletCreator.java 3KB
BasicSubjectServletCreator.java 3KB
BasicSubjectSpringReactiveCreator.java 3KB
BasicSubjectReactiveCreator.java 3KB
ResourceServiceImpl.java 3KB
NoneSubject.java 3KB
SurenessFilter.java 3KB
DefaultProcessorManager.java 3KB
MicronautSurenessFilterExample.java 3KB
BasicSubjectJaxRsCreator.java 3KB
AuthUserRoleBindDaoTest.java 3KB
DocumentResourceAccess.java 3KB
SurenessFilterExample.java 3KB
SurenessSubjectFactoryTest.java 3KB
共 616 条
- 1
- 2
- 3
- 4
- 5
- 6
- 7
资源评论
沐知全栈开发
- 粉丝: 4743
- 资源: 3374
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Qt开发知识、经验总结 包括Qss,数据库,Excel,Model/View等
- IV数据.xlsx
- 一些深度学习中的小例子,适合新手学习使用
- foldcraftlauncher_262944.apk
- 珍藏多年的基于matlab实现潮流计算程序源代码集合,包含多个潮流计算程序.rar
- 使用FPGA实现串-并型乘法器
- 基于matlab实现针对基于双曲线定位的DV-Hop算法中误差误差出一种基于加权双曲线定位的DV-Hop改进算法.rar
- 基于matlab实现由遗传算法开发的整数规划,车辆调度问题.rar
- 电视家7.0(对电视配置要求高).apk
- 免费计算机毕业设计-基于JavaEE的医院病历管理系统设计与实现(包含论文+源码)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功