提交 4d43a69e 编写于 作者: “ChineseTony“

Merge branch 'master' of https://github.com/dromara/sureness

...@@ -9,4 +9,4 @@ jobs: ...@@ -9,4 +9,4 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: tomsun28/issues-translate-action@v2.5 - uses: tomsun28/issues-translate-action@v2.6
...@@ -21,7 +21,7 @@ jobs: ...@@ -21,7 +21,7 @@ jobs:
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn -B package --file pom.xml
- name: Release Maven package - name: Release Core Maven package
uses: samuelmeuli/action-maven-publish@v1.4.0 uses: samuelmeuli/action-maven-publish@v1.4.0
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
...@@ -30,3 +30,13 @@ jobs: ...@@ -30,3 +30,13 @@ jobs:
nexus_password: ${{ secrets.NEXUS_PASSWORD }} nexus_password: ${{ secrets.NEXUS_PASSWORD }}
directory: core/ directory: core/
server_id: tom server_id: tom
- name: Release Spring-Boot-Starter Maven package
uses: samuelmeuli/action-maven-publish@v1.4.0
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
nexus_username: ${{ secrets.NEXUS_USERNAME }}
nexus_password: ${{ secrets.NEXUS_PASSWORD }}
directory: support/spring-boot-starter-sureness/
server_id: tom
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
> A simple and efficient jvm security framework that focus on the protection of REST API. > A simple and efficient jvm security framework that focus on the protection of REST API.
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Maven](https://img.shields.io/badge/Maven%20Central-1.0.4-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core) [![Maven](https://img.shields.io/badge/Maven%20Central-1.0.5-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core)
![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks) ![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks)
[![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness) [![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness)
![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red) ![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red)
...@@ -94,11 +94,11 @@ When use maven or gradle build project, add coordinate ...@@ -94,11 +94,11 @@ When use maven or gradle build project, add coordinate
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</dependency> </dependency>
``` ```
``` ```
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.4' compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.5'
``` ```
#### 🐵 Use the Default Configuration to Configure Sureness #### 🐵 Use the Default Configuration to Configure Sureness
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
> 面向`REST API`的高性能认证鉴权框架 > 面向`REST API`的高性能认证鉴权框架
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Maven](https://img.shields.io/badge/Maven%20Central-1.0.4-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core) [![Maven](https://img.shields.io/badge/Maven%20Central-1.0.5-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core)
![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks) ![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks)
[![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness) [![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness)
![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red) ![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red)
...@@ -100,11 +100,11 @@ ...@@ -100,11 +100,11 @@
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</dependency> </dependency>
``` ```
``` ```
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.4' compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.5'
``` ```
#### 🐵 使用默认配置来配置Sureness #### 🐵 使用默认配置来配置Sureness
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>sureness</name> <name>sureness</name>
<inceptionYear>2019</inceptionYear> <inceptionYear>2019</inceptionYear>
<url>https://github.com/tomsun28/sureness</url> <url>https://github.com/dromara/sureness</url>
<description> <description>
Sureness is a simple and efficient open-source security framework that focus on protection for restful api. Sureness is a simple and efficient open-source security framework that focus on protection for restful api.
</description> </description>
...@@ -34,13 +34,13 @@ ...@@ -34,13 +34,13 @@
<scm> <scm>
<connection> <connection>
scm:git:https://github.com/tomsun28/sureness.git scm:git:https://github.com/dromara/sureness.git
</connection> </connection>
<developerConnection> <developerConnection>
scm:git:https://github.com/tomsun28/sureness.git scm:git:https://github.com/dromara/sureness.git
</developerConnection> </developerConnection>
<url>https://github.com/tomsun28/sureness</url> <url>https://github.com/dromara/sureness</url>
<tag>1.0.2</tag> <tag>1.0.5</tag>
</scm> </scm>
<properties> <properties>
......
...@@ -5,6 +5,7 @@ import com.usthe.sureness.util.SurenessConstant; ...@@ -5,6 +5,7 @@ import com.usthe.sureness.util.SurenessConstant;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import static java.util.Objects.isNull;
/** /**
* attach auth success subject info with servlet request session * attach auth success subject info with servlet request session
...@@ -18,7 +19,7 @@ public class AttachSessionServletHandler implements SuccessHandler{ ...@@ -18,7 +19,7 @@ public class AttachSessionServletHandler implements SuccessHandler{
if (request instanceof HttpServletRequest) { if (request instanceof HttpServletRequest) {
HttpServletRequest servletRequest = (HttpServletRequest) request; HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpSession httpSession = servletRequest.getSession(); HttpSession httpSession = servletRequest.getSession();
if (httpSession.isNew() || httpSession.getAttribute(SurenessConstant.PRINCIPAL) == null) { if (isHttpSessionValid(httpSession)) {
httpSession.setAttribute(SurenessConstant.PRINCIPAL, subjectSum.getPrincipal()); httpSession.setAttribute(SurenessConstant.PRINCIPAL, subjectSum.getPrincipal());
httpSession.setAttribute(SurenessConstant.PRINCIPALS, subjectSum.getPrincipalMap()); httpSession.setAttribute(SurenessConstant.PRINCIPALS, subjectSum.getPrincipalMap());
httpSession.setAttribute(SurenessConstant.ROLES, subjectSum.getRoles()); httpSession.setAttribute(SurenessConstant.ROLES, subjectSum.getRoles());
...@@ -26,4 +27,8 @@ public class AttachSessionServletHandler implements SuccessHandler{ ...@@ -26,4 +27,8 @@ public class AttachSessionServletHandler implements SuccessHandler{
} }
} }
private boolean isHttpSessionValid(HttpSession httpSession) {
return httpSession.isNew() || isNull(httpSession.getAttribute(SurenessConstant.PRINCIPAL));
}
} }
...@@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; ...@@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
/** /**
* the manager for successHandler * the manager for successHandler
...@@ -24,7 +26,7 @@ public class HandlerManager { ...@@ -24,7 +26,7 @@ public class HandlerManager {
* @param request http request * @param request http request
*/ */
public void hand(SubjectSum subjectSum, Object request) { public void hand(SubjectSum subjectSum, Object request) {
if (successHandlers != null) { if (nonNull(successHandlers)) {
for (SuccessHandler successHandler : successHandlers) { for (SuccessHandler successHandler : successHandlers) {
try { try {
successHandler.processHandler(subjectSum, request); successHandler.processHandler(subjectSum, request);
...@@ -36,7 +38,7 @@ public class HandlerManager { ...@@ -36,7 +38,7 @@ public class HandlerManager {
} }
public void registerHandler(List<SuccessHandler> handlers) { public void registerHandler(List<SuccessHandler> handlers) {
if (successHandlers == null) { if (isNull(successHandlers)) {
successHandlers = handlers; successHandlers = handlers;
} else { } else {
successHandlers.addAll(handlers); successHandlers.addAll(handlers);
...@@ -44,7 +46,7 @@ public class HandlerManager { ...@@ -44,7 +46,7 @@ public class HandlerManager {
} }
public void registerHandler(SuccessHandler handler) { public void registerHandler(SuccessHandler handler) {
if (successHandlers == null) { if (isNull(successHandlers)) {
successHandlers = new LinkedList<>(); successHandlers = new LinkedList<>();
} }
successHandlers.add(handler); successHandlers.add(handler);
......
...@@ -6,7 +6,15 @@ import com.usthe.sureness.subject.Subject; ...@@ -6,7 +6,15 @@ import com.usthe.sureness.subject.Subject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.*; import java.util.Set;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;
import java.util.HashSet;
import static java.util.Objects.nonNull;
import static java.util.Objects.isNull;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -47,7 +55,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -47,7 +55,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
String targetResource = (String) subject.getTargetResource(); String targetResource = (String) subject.getTargetResource();
//[role1,role2,role3], [role1], [], null //[role1,role2,role3], [role1], [], null
String matchRoleString = root.searchPathFilterRoles(targetResource); String matchRoleString = root.searchPathFilterRoles(targetResource);
if (matchRoleString != null && matchRoleString.startsWith(LEFT_CON) if (nonNull(matchRoleString) && matchRoleString.startsWith(LEFT_CON)
&& matchRoleString.endsWith(RIGHT_CON)) { && matchRoleString.endsWith(RIGHT_CON)) {
if (NULL_ROLE.equals(matchRoleString)) { if (NULL_ROLE.equals(matchRoleString)) {
subject.setSupportRoles(new ArrayList<>(0)); subject.setSupportRoles(new ArrayList<>(0));
...@@ -64,20 +72,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -64,20 +72,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
checkComponentInit(); checkComponentInit();
Set<String> resources = new HashSet<>(); Set<String> resources = new HashSet<>();
Set<String> excludeResources = new HashSet<>(); Set<String> excludeResources = new HashSet<>();
for (PathTreeProvider provider : pathTreeProviderList) { iterateOverPathTreeProviderList(resources, excludeResources);
Set<String> resourceTmp = provider.providePathData();
Set<String> excludeResourceTmp = provider.provideExcludedResource();
if (resourceTmp != null) {
resources.addAll(resourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} providePathData is null", provider);
}
if (excludeResourceTmp != null) {
excludeResources.addAll(excludeResourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} provideExcludedResource is null", provider);
}
}
root.buildTree(resources); root.buildTree(resources);
excludeResources = excludeResources.stream() excludeResources = excludeResources.stream()
...@@ -92,20 +87,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -92,20 +87,7 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
checkComponentInit(); checkComponentInit();
Set<String> resources = new HashSet<>(); Set<String> resources = new HashSet<>();
Set<String> excludeResources = new HashSet<>(); Set<String> excludeResources = new HashSet<>();
for (PathTreeProvider provider : pathTreeProviderList) { iterateOverPathTreeProviderList(resources, excludeResources);
Set<String> resourceTmp = provider.providePathData();
Set<String> excludeResourceTmp = provider.provideExcludedResource();
if (resourceTmp != null) {
resources.addAll(resourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} providePathData is null", provider);
}
if (excludeResourceTmp != null) {
excludeResources.addAll(excludeResourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} provideExcludedResource is null", provider);
}
}
root.rebuildTree(resources); root.rebuildTree(resources);
excludeResources = excludeResources.stream() excludeResources = excludeResources.stream()
...@@ -118,22 +100,22 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -118,22 +100,22 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
public boolean isExcludedResource(Subject request) { public boolean isExcludedResource(Subject request) {
checkComponentInit(); checkComponentInit();
String exclude = excludeRoot.searchPathFilterRoles((String) request.getTargetResource()); String exclude = excludeRoot.searchPathFilterRoles((String) request.getTargetResource());
return exclude != null && exclude.equals(EXCLUDE_ROLE); return nonNull(exclude) && exclude.equals(EXCLUDE_ROLE);
} }
private void checkComponentInit() { private void checkComponentInit() {
if (pathTreeProviderList == null) { if (isNull(pathTreeProviderList)) {
throw new SurenessNoInitException("DefaultPathRoleMatcher init error : component init not complete"); throw new SurenessNoInitException("DefaultPathRoleMatcher init error : component init not complete");
} }
} }
private void clearTree() { private void clearTree() {
root.clearTree(); root.clearTree();
excludeRoot.clearTree(); excludeRoot.clearTree();
} }
public void setPathTreeProvider(PathTreeProvider pathTreeProvider) { public void setPathTreeProvider(PathTreeProvider pathTreeProvider) {
if (pathTreeProviderList == null) { if (isNull(pathTreeProviderList)) {
pathTreeProviderList = new LinkedList<>(); pathTreeProviderList = new LinkedList<>();
} }
pathTreeProviderList.add(pathTreeProvider); pathTreeProviderList.add(pathTreeProvider);
...@@ -142,7 +124,6 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -142,7 +124,6 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
public void setPathTreeProviderList(List<PathTreeProvider> providerList) { public void setPathTreeProviderList(List<PathTreeProvider> providerList) {
pathTreeProviderList = providerList; pathTreeProviderList = providerList;
} }
public DefaultPathRoleMatcher addPathTreeProvider(PathTreeProvider pathTreeProvider) { public DefaultPathRoleMatcher addPathTreeProvider(PathTreeProvider pathTreeProvider) {
if (pathTreeProviderList == null) { if (pathTreeProviderList == null) {
pathTreeProviderList = new LinkedList<>(); pathTreeProviderList = new LinkedList<>();
...@@ -150,4 +131,22 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher { ...@@ -150,4 +131,22 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
pathTreeProviderList.add(pathTreeProvider); pathTreeProviderList.add(pathTreeProvider);
return this; return this;
} }
private void iterateOverPathTreeProviderList(Set<String> resources, Set<String> excludeResources) {
for (PathTreeProvider provider : pathTreeProviderList) {
Set<String> resourceTmp = provider.providePathData();
Set<String> excludeResourceTmp = provider.provideExcludedResource();
if (nonNull(resourceTmp)) {
resources.addAll(resourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} providePathData is null", provider);
}
if (nonNull(excludeResourceTmp)) {
excludeResources.addAll(excludeResourceTmp);
} else {
logger.warn("sureness - pathTreeProvider: {} provideExcludedResource is null", provider);
}
}
}
} }
...@@ -17,7 +17,6 @@ public interface PathTreeProvider { ...@@ -17,7 +17,6 @@ public interface PathTreeProvider {
* tomcat context path is: <context path="v2"> * tomcat context path is: <context path="v2">
*/ */
AtomicReference<String> CONTEXT_PATH_REF = new AtomicReference<>(); AtomicReference<String> CONTEXT_PATH_REF = new AtomicReference<>();
/** /**
* set context path * set context path
* Please sync with your server context path settings here * Please sync with your server context path settings here
......
...@@ -4,7 +4,12 @@ package com.usthe.sureness.matcher.util; ...@@ -4,7 +4,12 @@ package com.usthe.sureness.matcher.util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.*; 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; import java.util.regex.Pattern;
/** /**
...@@ -26,8 +31,9 @@ public class TirePathTree { ...@@ -26,8 +31,9 @@ public class TirePathTree {
private static final String NODE_TYPE_METHOD = "methodNode"; private static final String NODE_TYPE_METHOD = "methodNode";
private static final String NODE_TYPE_FILTER_ROLES = "rolesNode"; private static final String NODE_TYPE_FILTER_ROLES = "rolesNode";
private static final String URL_PATH_SPLIT = "/"; private static final String URL_PATH_SPLIT = "/";
private static final String MATCH_ONE = "*"; private static final String MATCH_ALL_METHOD = "*";
private static final String MATCH_ALL = "**"; 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_3 = 3;
private static final int PATH_NODE_NUM_2 = 2; private static final int PATH_NODE_NUM_2 = 2;
private static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/+"); private static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/+");
...@@ -103,8 +109,8 @@ public class TirePathTree { ...@@ -103,8 +109,8 @@ public class TirePathTree {
resourceList.add(root); resourceList.add(root);
while (!resourceList.isEmpty()) { while (!resourceList.isEmpty()) {
Node currentNode = resourceList.poll(); Node currentNode = resourceList.poll();
if (NODE_TYPE_METHOD.equals(currentNode.nodeType)) { if (currentNode.getMethodChildren() != null && !currentNode.getMethodChildren().isEmpty()) {
resourceNum ++; resourceNum += currentNode.getMethodChildren().size();
} }
if (currentNode.getChildren() != null && !currentNode.getChildren().isEmpty()) { if (currentNode.getChildren() != null && !currentNode.getChildren().isEmpty()) {
resourceList.addAll(currentNode.getChildren().values()); resourceList.addAll(currentNode.getChildren().values());
...@@ -166,22 +172,28 @@ public class TirePathTree { ...@@ -166,22 +172,28 @@ public class TirePathTree {
return null; return null;
} }
if (currentFlow == urlPac.length - 1 && (NODE_TYPE_MAY_PATH_END.equals(current.getNodeType()))) { if (currentFlow == urlPac.length - 1 && (NODE_TYPE_MAY_PATH_END.equals(current.getNodeType()))) {
Node methodNode = current.getChildren().get(method); Node methodNode = current.getMethodChild(method);
if (methodNode != null) { if (methodNode != null) {
if (NODE_TYPE_METHOD.equals(methodNode.getNodeType())) { if (NODE_TYPE_METHOD.equals(methodNode.getNodeType())) {
return methodNode.getChildren().keySet().iterator().next(); return methodNode.getChildren().keySet().iterator().next();
} }
} else { } else {
Node nextNode = current.getChildren().get(MATCH_ONE); Node nextNode = current.getMethodChild(MATCH_ALL_METHOD);
if (nextNode != null && NODE_TYPE_METHOD.equals(nextNode.getNodeType())) { if (nextNode != null && NODE_TYPE_METHOD.equals(nextNode.getNodeType())) {
return nextNode.getChildren().keySet().iterator().next(); return nextNode.getChildren().keySet().iterator().next();
} }
if (nextNode == null) { nextNode = current.getChildren().get(MATCH_ONE_PATH);
nextNode = current.getChildren().get(MATCH_ALL); 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())) { if (nextNode != null && NODE_TYPE_MAY_PATH_END.equals(nextNode.getNodeType())) {
methodNode = nextNode.getChildren().get(method); methodNode = nextNode.getMethodChild(method);
methodNode = methodNode == null ? nextNode.getChildren().get(MATCH_ONE) : methodNode; methodNode = methodNode == null ? nextNode.getMethodChild(MATCH_ALL_METHOD) : methodNode;
if (methodNode != null && NODE_TYPE_METHOD.equals(methodNode.getNodeType())) { if (methodNode != null && NODE_TYPE_METHOD.equals(methodNode.getNodeType())) {
return methodNode.getChildren().keySet().iterator().next(); return methodNode.getChildren().keySet().iterator().next();
} }
...@@ -196,7 +208,7 @@ public class TirePathTree { ...@@ -196,7 +208,7 @@ public class TirePathTree {
return matchRole; return matchRole;
} }
} }
if (currentNodeData.equals(MATCH_ONE)) { if (currentNodeData.equals(MATCH_ONE_PATH)) {
matchRole = searchPathRoleInChildren(current, urlPac, currentFlow - 1, method); matchRole = searchPathRoleInChildren(current, urlPac, currentFlow - 1, method);
if (matchRole != null) { if (matchRole != null) {
return matchRole; return matchRole;
...@@ -206,7 +218,7 @@ public class TirePathTree { ...@@ -206,7 +218,7 @@ public class TirePathTree {
return matchRole; return matchRole;
} }
} }
if (currentNodeData.equals(MATCH_ALL)) { if (currentNodeData.equals(MATCH_MULTI_PATH)) {
matchRole = searchPathRoleInChildren(current, urlPac, currentFlow - 1, method); matchRole = searchPathRoleInChildren(current, urlPac, currentFlow - 1, method);
if (matchRole != null) { if (matchRole != null) {
return matchRole; return matchRole;
...@@ -252,15 +264,15 @@ public class TirePathTree { ...@@ -252,15 +264,15 @@ public class TirePathTree {
} }
} }
} }
if (current.getChildren().containsKey(MATCH_ONE)) { if (current.getChildren().containsKey(MATCH_ONE_PATH)) {
Node matchOneNode = current.getChildren().get(MATCH_ONE); Node matchOneNode = current.getChildren().get(MATCH_ONE_PATH);
matchRole = searchPathRole(matchOneNode, urlPac, currentFlow + 1, method); matchRole = searchPathRole(matchOneNode, urlPac, currentFlow + 1, method);
if (matchRole != null) { if (matchRole != null) {
return matchRole; return matchRole;
} }
} }
if (current.getChildren().containsKey(MATCH_ALL)) { if (current.getChildren().containsKey(MATCH_MULTI_PATH)) {
Node matchAllNode = current.getChildren().get(MATCH_ALL); Node matchAllNode = current.getChildren().get(MATCH_MULTI_PATH);
matchRole = searchPathRole(matchAllNode, urlPac, currentFlow + 1, method); matchRole = searchPathRole(matchAllNode, urlPac, currentFlow + 1, method);
} }
return matchRole; return matchRole;
...@@ -279,8 +291,8 @@ public class TirePathTree { ...@@ -279,8 +291,8 @@ public class TirePathTree {
if (pattern == null || pathNode == null) { if (pattern == null || pathNode == null) {
return true; return true;
} }
if (pattern.equals(pathNode) || MATCH_ONE.equals(pattern) if (pattern.equals(pathNode) || MATCH_ONE_PATH.equals(pattern)
|| MATCH_ALL.equals(pattern)) { || MATCH_MULTI_PATH.equals(pattern)) {
return false; return false;
} }
if (!isPatternStr(pattern)) { if (!isPatternStr(pattern)) {
...@@ -302,9 +314,9 @@ public class TirePathTree { ...@@ -302,9 +314,9 @@ public class TirePathTree {
*/ */
private boolean isPatternStr(String str) { private boolean isPatternStr(String str) {
return str != null return str != null
&& str.contains(MATCH_ONE) && str.contains(MATCH_ONE_PATH)
&& !MATCH_ONE.equals(str) && !MATCH_ONE_PATH.equals(str)
&& !MATCH_ALL.equals(str); && !MATCH_MULTI_PATH.equals(str);
} }
/** /**
...@@ -367,7 +379,7 @@ public class TirePathTree { ...@@ -367,7 +379,7 @@ public class TirePathTree {
pre = current; pre = current;
current = current.getChildren().get(urlData); current = current.getChildren().get(urlData);
} }
if (MATCH_ONE.equals(current.getData()) || MATCH_ALL.equals(current.getData())) { if (MATCH_ONE_PATH.equals(current.getData()) || MATCH_MULTI_PATH.equals(current.getData())) {
// When the last one is * or **, it may match empty, // When the last one is * or **, it may match empty,
// and the previous one may also be NODE_TYPE_MAY_PATH_END type // and the previous one may also be NODE_TYPE_MAY_PATH_END type
pre.setNodeType(NODE_TYPE_MAY_PATH_END); pre.setNodeType(NODE_TYPE_MAY_PATH_END);
...@@ -375,13 +387,18 @@ public class TirePathTree { ...@@ -375,13 +387,18 @@ public class TirePathTree {
// set node type is NODE_TYPE_MAY_PATH_END // set node type is NODE_TYPE_MAY_PATH_END
current.setNodeType(NODE_TYPE_MAY_PATH_END); current.setNodeType(NODE_TYPE_MAY_PATH_END);
// start insert httpMethod method, if existed, not overwrite and modify the original configuration // start insert httpMethod method, if existed, not overwrite and modify the original configuration
if (!current.getChildren().containsKey(method) && !current.getChildren().containsKey(MATCH_ONE)) { if (current.getMethodChildren() != null) {
current.insertChild(method, NODE_TYPE_METHOD); if (current.getMethodChildren().containsKey(method)) {
} else { logger.warn("[sureness]-The path resource: {} has match same resource config, ignore this one.", path);
logger.warn("[sureness]-The path resource: {} has match same method or *, ignore it.", path); return;
return; }
if (current.getMethodChildren().containsKey(MATCH_ALL_METHOD)) {
logger.warn("[sureness]-The path resource: {} has match same resource config(* means all http method), ignore this one.", path);
return;
}
} }
current = current.getChildren().get(method);
current = current.insertMethodChildren(method);
// Start inserting leaf nodes - supportRoles // Start inserting leaf nodes - supportRoles
// each resource only mapping a left node, that is, at most one child node under supportRoles--httpMethod // each resource only mapping a left node, that is, at most one child node under supportRoles--httpMethod
// if existed, not overwrite and modify the original configuration // if existed, not overwrite and modify the original configuration
...@@ -409,6 +426,8 @@ public class TirePathTree { ...@@ -409,6 +426,8 @@ public class TirePathTree {
/** pattern children list **/ /** pattern children list **/
private List<String> patternChildren; private List<String> patternChildren;
private Map<String, Node> methodChildren;
private Node(String data, String nodeType) { private Node(String data, String nodeType) {
this.data = data; this.data = data;
this.nodeType = nodeType; this.nodeType = nodeType;
...@@ -435,6 +454,23 @@ public class TirePathTree { ...@@ -435,6 +454,23 @@ public class TirePathTree {
this.patternChildren.add(data); this.patternChildren.add(data);
} }
public Node getMethodChild(String method) {
return methodChildren == null ? null : methodChildren.get(method);
}
public Map<String, Node> getMethodChildren() {
return methodChildren;
}
public Node insertMethodChildren(String method) {
if (methodChildren == null) {
methodChildren = new HashMap<>(8);
}
Node node = new Node(method, NODE_TYPE_METHOD);
methodChildren.put(method, node);
return node;
}
private String getNodeType() { private String getNodeType() {
return nodeType; return nodeType;
} }
...@@ -447,17 +483,11 @@ public class TirePathTree { ...@@ -447,17 +483,11 @@ public class TirePathTree {
return data; return data;
} }
private void setData(String data) {
this.data = data;
}
private Map<String, Node> getChildren() { private Map<String, Node> getChildren() {
return children; return children;
} }
private void setChildren(Map<String, Node> children) {
this.children = children;
}
public List<String> getPatternChildren() { public List<String> getPatternChildren() {
return patternChildren; return patternChildren;
......
...@@ -12,8 +12,11 @@ import org.slf4j.Logger; ...@@ -12,8 +12,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import static java.util.Objects.nonNull;
import static java.util.Objects.isNull;
/** /**
* Authentication authorization entrance * Authentication authorization entrance
* @author tomsun28 * @author tomsun28
...@@ -55,8 +58,7 @@ public class SurenessSecurityManager implements SecurityManager { ...@@ -55,8 +58,7 @@ public class SurenessSecurityManager implements SecurityManager {
* @throws SurenessNoInitException check false not init * @throws SurenessNoInitException check false not init
*/ */
private void checkComponentInit() { private void checkComponentInit() {
if (subjectFactory == null || pathRoleMatcher == null || if (validateSomeOneIsNull(Stream.of(subjectFactory, pathRoleMatcher, processorManager))) {
processorManager == null) {
logger.error("SecurityManager init error : SurenessSecurityManager not init fill component"); logger.error("SecurityManager init error : SurenessSecurityManager not init fill component");
// The component's own related exceptions or configuration line exceptions are not thrown up // The component's own related exceptions or configuration line exceptions are not thrown up
throw new SurenessNoInitException("SurenessSecurityManager not init fill component"); throw new SurenessNoInitException("SurenessSecurityManager not init fill component");
...@@ -83,7 +85,7 @@ public class SurenessSecurityManager implements SecurityManager { ...@@ -83,7 +85,7 @@ public class SurenessSecurityManager implements SecurityManager {
return null; return null;
} }
noTryExcluded = false; noTryExcluded = false;
if (preSubject == null) { if (isNull(preSubject)) {
pathRoleMatcher.matchRole(thisSubject); pathRoleMatcher.matchRole(thisSubject);
preSubject = thisSubject; preSubject = thisSubject;
} else { } else {
...@@ -101,11 +103,15 @@ public class SurenessSecurityManager implements SecurityManager { ...@@ -101,11 +103,15 @@ public class SurenessSecurityManager implements SecurityManager {
} }
private void handSuccess(SubjectSum subjectSum, Object request) { private void handSuccess(SubjectSum subjectSum, Object request) {
if (handlerManager != null) { if (nonNull(handlerManager)) {
handlerManager.hand(subjectSum, request); handlerManager.hand(subjectSum, request);
} }
} }
private boolean validateSomeOneIsNull(final Stream stream) {
return stream.anyMatch(Objects::isNull);
}
@Override @Override
public List<Subject> createSubject(Object var1) { public List<Subject> createSubject(Object var1) {
return subjectFactory.createSubjects(var1); return subjectFactory.createSubjects(var1);
...@@ -139,9 +145,6 @@ public class SurenessSecurityManager implements SecurityManager { ...@@ -139,9 +145,6 @@ public class SurenessSecurityManager implements SecurityManager {
return processorManager; return processorManager;
} }
public HandlerManager getHandlerManager() {
return handlerManager;
}
/** /**
* singleton * singleton
......
...@@ -8,7 +8,7 @@ package com.usthe.sureness.processor.exception; ...@@ -8,7 +8,7 @@ package com.usthe.sureness.processor.exception;
*/ */
public class NeedDigestInfoException extends SurenessAuthenticationException { public class NeedDigestInfoException extends SurenessAuthenticationException {
private String authenticate; private final String authenticate;
public NeedDigestInfoException(String message, String authenticate) { public NeedDigestInfoException(String message, String authenticate) {
super(message); super(message);
......
package com.usthe.sureness.processor.support; package com.usthe.sureness.processor.support;
import com.usthe.sureness.processor.BaseProcessor; import com.usthe.sureness.processor.BaseProcessor;
import com.usthe.sureness.processor.exception.*; import com.usthe.sureness.processor.exception.DisabledAccountException;
import com.usthe.sureness.processor.exception.ExcessiveAttemptsException;
import com.usthe.sureness.processor.exception.IncorrectCredentialsException;
import com.usthe.sureness.processor.exception.UnknownAccountException;
import com.usthe.sureness.processor.exception.SurenessAuthenticationException;
import com.usthe.sureness.processor.exception.NeedDigestInfoException;
import com.usthe.sureness.provider.SurenessAccount; import com.usthe.sureness.provider.SurenessAccount;
import com.usthe.sureness.provider.SurenessAccountProvider; import com.usthe.sureness.provider.SurenessAccountProvider;
import com.usthe.sureness.subject.Subject; import com.usthe.sureness.subject.Subject;
...@@ -12,6 +17,7 @@ import org.slf4j.LoggerFactory; ...@@ -12,6 +17,7 @@ import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import static java.util.Objects.nonNull;
/** /**
* process digest auth - DigestSubject * process digest auth - DigestSubject
...@@ -87,14 +93,22 @@ public class DigestProcessor extends BaseProcessor { ...@@ -87,14 +93,22 @@ public class DigestProcessor extends BaseProcessor {
return var; return var;
} }
private String getAuthenticate(){ private String getAuthenticate() {
String nonce = calcDigest(String.valueOf(System.currentTimeMillis())); String nonce = calcDigest(String.valueOf(System.currentTimeMillis()));
return "Digest " + "realm=" + realm + ",nonce=" + nonce + ",qop=" + qop; return new StringBuilder()
.append("Digest ")
.append("realm=")
.append(realm)
.append(",nonce=")
.append(nonce)
.append(",qop=")
.append(qop)
.toString();
} }
private String calcDigest(String first, String ... args){ private String calcDigest(String first, String ... args){
StringBuilder stringBuilder = new StringBuilder(first); StringBuilder stringBuilder = new StringBuilder(first);
if (args != null) { if (nonNull(args)) {
for (String str : args){ for (String str : args){
stringBuilder.append(':').append(str); stringBuilder.append(':').append(str);
} }
...@@ -116,7 +130,6 @@ public class DigestProcessor extends BaseProcessor { ...@@ -116,7 +130,6 @@ public class DigestProcessor extends BaseProcessor {
public void setAccountProvider(SurenessAccountProvider provider) { public void setAccountProvider(SurenessAccountProvider provider) {
this.accountProvider = provider; this.accountProvider = provider;
} }
public static void setRealm(String realm) { public static void setRealm(String realm) {
DigestProcessor.realm = realm; DigestProcessor.realm = realm;
} }
...@@ -124,4 +137,5 @@ public class DigestProcessor extends BaseProcessor { ...@@ -124,4 +137,5 @@ public class DigestProcessor extends BaseProcessor {
public static void setQop(String qop) { public static void setQop(String qop) {
DigestProcessor.qop = qop; DigestProcessor.qop = qop;
} }
} }
...@@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory; ...@@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.util.Objects.nonNull;
/** /**
* the processor support jwt - JwtSubject * the processor support jwt - JwtSubject
...@@ -67,7 +68,7 @@ public class JwtProcessor extends BaseProcessor { ...@@ -67,7 +68,7 @@ public class JwtProcessor extends BaseProcessor {
// attention: need to set subject own roles from account // attention: need to set subject own roles from account
var.setPrincipal(claims.getSubject()); var.setPrincipal(claims.getSubject());
List<String> ownRoles = claims.get("roles", List.class); List<String> ownRoles = claims.get("roles", List.class);
if (ownRoles != null) { if (nonNull(ownRoles)) {
var.setOwnRoles(ownRoles); var.setOwnRoles(ownRoles);
} }
PrincipalMap principalMap = new SinglePrincipalMap(); PrincipalMap principalMap = new SinglePrincipalMap();
......
...@@ -23,6 +23,6 @@ public class SurenessConstant { ...@@ -23,6 +23,6 @@ public class SurenessConstant {
public static final String BEARER = "Bearer"; public static final String BEARER = "Bearer";
/** Token auth key **/ /** Token auth key **/
public static final String TOKEN = "token"; public static final String TOKEN = "token";
/** JWT auth **/
public static final String JWT = "jwt"; public static final String JWT = "Jwt";
} }
...@@ -78,9 +78,12 @@ public class TirePathTreeTest { ...@@ -78,9 +78,12 @@ public class TirePathTreeTest {
// support ignore http method // support ignore http method
paths.add("/api/school/book===*===[role8]"); paths.add("/api/school/book===*===[role8]");
paths.add("/api2/school/*===*===[role18]"); paths.add("/api2/school/*===*===[role18]");
// fix issue bug https://github.com/dromara/sureness/issues/132
paths.add("/api/v6/book/*===get===[role1]");
paths.add("/api/v6/book===post===[role2]");
root.buildTree(paths); root.buildTree(paths);
assertEquals(33, root.getResourceNum()); assertEquals(35, root.getResourceNum());
} }
@Test @Test
...@@ -137,6 +140,9 @@ public class TirePathTreeTest { ...@@ -137,6 +140,9 @@ public class TirePathTreeTest {
assertEquals("[role18]", root.searchPathFilterRoles("/api2/school/book===post")); assertEquals("[role18]", root.searchPathFilterRoles("/api2/school/book===post"));
assertEquals("[role18]", root.searchPathFilterRoles("/api2/school/student===get")); assertEquals("[role18]", root.searchPathFilterRoles("/api2/school/student===get"));
assertEquals("[role18]", root.searchPathFilterRoles("/api2/school===delete")); assertEquals("[role18]", root.searchPathFilterRoles("/api2/school===delete"));
// fix issue bug https://github.com/dromara/sureness/issues/132
assertEquals("[role1]", root.searchPathFilterRoles("/api/v6/book/3===get"));
assertEquals("[role2]", root.searchPathFilterRoles("/api/v6/book===post"));
} }
} }
\ No newline at end of file
...@@ -10,7 +10,7 @@ slug: / ...@@ -10,7 +10,7 @@ slug: /
> A simple and efficient jvm security framework that focus on the protection of REST API. > A simple and efficient jvm security framework that focus on the protection of REST API.
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Maven](https://img.shields.io/badge/Maven%20Central-1.0.4-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core) [![Maven](https://img.shields.io/badge/Maven%20Central-1.0.5-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core)
![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks) ![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks)
[![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness) [![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness)
![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red) ![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red)
......
...@@ -21,11 +21,11 @@ When use maven or gradle build project, add coordinate ...@@ -21,11 +21,11 @@ When use maven or gradle build project, add coordinate
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</dependency> </dependency>
``` ```
``` ```
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.4' compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.5'
``` ```
### 🐵 Use the Default Configuration to Configure Sureness ### 🐵 Use the Default Configuration to Configure Sureness
......
...@@ -4,6 +4,7 @@ const organizationName = 'usthe' // Usually your GitHub org/user name. ...@@ -4,6 +4,7 @@ const organizationName = 'usthe' // Usually your GitHub org/user name.
const projectName = 'sureness' // Usually your repo name. const projectName = 'sureness' // Usually your repo name.
const branch = 'master' const branch = 'master'
const repoUrl = `https://github.com/dromara/${projectName}` const repoUrl = `https://github.com/dromara/${projectName}`
const cdnUrl = 'https://cdn.jsdelivr.net/gh/usthe/sureness@gh-pages/'
module.exports = { module.exports = {
title: 'Sureness', title: 'Sureness',
...@@ -12,18 +13,19 @@ module.exports = { ...@@ -12,18 +13,19 @@ module.exports = {
baseUrl: '/sureness/', baseUrl: '/sureness/',
onBrokenLinks: 'throw', onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'throw', onBrokenMarkdownLinks: 'throw',
favicon: 'img/icon64.png', favicon: cdnUrl + 'img/icon64.png',
organizationName, organizationName,
projectName, projectName,
customFields: { customFields: {
repoUrl repoUrl,
cdnUrl
}, },
i18n: { i18n: {
defaultLocale: 'en', defaultLocale: 'en',
locales: ['en', 'zh-cn'], locales: ['en', 'zh-cn'],
}, },
themeConfig: { themeConfig: {
image: 'img/icon64128.png', image: cdnUrl + 'img/icon128.png',
liveCodeBlock: { liveCodeBlock: {
playgroundPosition: 'bottom', playgroundPosition: 'bottom',
}, },
...@@ -58,7 +60,7 @@ module.exports = { ...@@ -58,7 +60,7 @@ module.exports = {
announcementBar: { announcementBar: {
id: "github-star", id: "github-star",
content: content:
'<font style="font-size: medium; font-weight: bolder">If you like Sureness,</font> <a target="_blank" style="font-size: medium; font-weight: bolder" rel="noopener noreferrer" href="https://github.com/dromara/sureness">give us a star on GitHub! </a>⭐️', '<font style="font-size: medium; font-weight: bolder">If you like Sureness,</font> <a target="_blank" style="font-size: medium; font-weight: bolder" rel="noopener noreferrer" href="https://github.com/dromara/sureness">give us a star on GitHub </a> <font style="font-size: medium; font-weight: bolder"> or </font><a target="_blank" style="font-size: medium; font-weight: bolder" rel="noopener noreferrer" href="https://gitee.com/dromara/sureness">Gitee! </a>⭐️',
backgroundColor: '#7228B5', backgroundColor: '#7228B5',
textColor: '#fafbfc', textColor: '#fafbfc',
isCloseable: true, isCloseable: true,
...@@ -67,7 +69,7 @@ module.exports = { ...@@ -67,7 +69,7 @@ module.exports = {
title: ' ', title: ' ',
logo: { logo: {
alt: 'Focus on Protection of API', alt: 'Focus on Protection of API',
src: 'img/icon128.svg', src: cdnUrl + 'img/icon128.svg',
}, },
items: [ items: [
{ {
...@@ -203,7 +205,7 @@ module.exports = { ...@@ -203,7 +205,7 @@ module.exports = {
], ],
logo: { logo: {
alt: 'Open Source Logo', alt: 'Open Source Logo',
src: 'img/dromara.jpg', src: cdnUrl + 'img/dromara.jpg',
href: 'https://github.com/dromara', href: 'https://github.com/dromara',
}, },
copyright: `Apache License 2.0 | Copyright © ${new Date().getFullYear()}`, copyright: `Apache License 2.0 | Copyright © ${new Date().getFullYear()}`,
...@@ -258,12 +260,12 @@ module.exports = { ...@@ -258,12 +260,12 @@ module.exports = {
{ {
tagName: 'link', tagName: 'link',
rel: 'icon', rel: 'icon',
href: 'img/icon64.png', href: cdnUrl + 'img/icon64.png',
}, },
{ {
tagName: 'link', tagName: 'link',
rel: 'manifest', rel: 'manifest',
href: '/manifest.json', href: cdnUrl + 'manifest.json',
}, },
{ {
tagName: 'meta', tagName: 'meta',
...@@ -283,18 +285,18 @@ module.exports = { ...@@ -283,18 +285,18 @@ module.exports = {
{ {
tagName: 'link', tagName: 'link',
rel: 'apple-touch-icon', rel: 'apple-touch-icon',
href: 'img/icon64.png', href: cdnUrl + 'img/icon64.png',
}, },
{ {
tagName: 'link', tagName: 'link',
rel: 'mask-icon', rel: 'mask-icon',
href: 'img/icon64.svg', href: cdnUrl + 'img/icon64.svg',
color: 'rgb(234, 90, 7)', color: 'rgb(234, 90, 7)',
}, },
{ {
tagName: 'meta', tagName: 'meta',
name: 'msapplication-TileImage', name: 'msapplication-TileImage',
content: 'img/icon64.png', content: cdnUrl + 'img/icon64.png',
}, },
{ {
tagName: 'meta', tagName: 'meta',
...@@ -311,6 +313,6 @@ module.exports = { ...@@ -311,6 +313,6 @@ module.exports = {
'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=block' 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=block'
], ],
scripts: [ scripts: [
'https://buttons.github.io/buttons.js' 'https://cdn.jsdelivr.net/gh/buttons/buttons.github.io/buttons.js'
] ]
} }
...@@ -267,5 +267,8 @@ ...@@ -267,5 +267,8 @@
}, },
"Friend Links": { "Friend Links": {
"message": "友情链接" "message": "友情链接"
},
"Media Partners": {
"message": "合作媒体"
} }
} }
\ No newline at end of file
...@@ -8,7 +8,7 @@ slug: / ...@@ -8,7 +8,7 @@ slug: /
> 面向`REST API`的高性能认证鉴权框架 > 面向`REST API`的高性能认证鉴权框架
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Maven](https://img.shields.io/badge/Maven%20Central-1.0.4-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core) [![Maven](https://img.shields.io/badge/Maven%20Central-1.0.5-blue.svg)](https://search.maven.org/artifact/com.usthe.sureness/sureness-core)
![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks) ![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks)
[![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness) [![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness)
![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red) ![GitHub Release Date](https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red)
......
...@@ -20,11 +20,11 @@ sidebar_label: 快速开始 ...@@ -20,11 +20,11 @@ sidebar_label: 快速开始
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</dependency> </dependency>
``` ```
``` ```
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.4' compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.5'
``` ```
#### 🐵 使用默认配置来配置Sureness #### 🐵 使用默认配置来配置Sureness
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
}, },
"link.item.label.QQ Group - 390083213": { "link.item.label.QQ Group - 390083213": {
"message": "QQ 群 - 390083213", "message": "QQ 群 - 390083213",
"description": "The label of footer link with label=QQ Group - 282870345 linking to https://qm.qq.com/cgi-bin/qm/qr?k=3IpzQjFOztJe464_eMBmDHfT0YTWK5Qa&jump_from=webapi" "description": "The label of footer link with label=QQ Group - 390083213 linking to https://qm.qq.com/cgi-bin/qm/qr?k=3IpzQjFOztJe464_eMBmDHfT0YTWK5Qa&jump_from=webapi"
}, },
"link.item.label.Tom Blog": { "link.item.label.Tom Blog": {
"message": "Tom 博客", "message": "Tom 博客",
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
}, },
"item.label.QQ Group - 390083213": { "item.label.QQ Group - 390083213": {
"message": "QQ 群 - 390083213", "message": "QQ 群 - 390083213",
"description": "Navbar item with label QQ Group - 282870345" "description": "Navbar item with label QQ Group - 390083213"
}, },
"item.label.Blog": { "item.label.Blog": {
"message": "博客", "message": "博客",
......
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
export default function transfer(imageUrl) {
const {siteConfig} = useDocusaurusContext();
const {cdnUrl} = siteConfig.customFields;
if (cdnUrl !== null && imageUrl !== undefined && imageUrl !== null) {
return cdnUrl + imageUrl;
} else {
return imageUrl;
}
}
\ No newline at end of file
import React from 'react' import React from 'react'
import Translate, {translate} from '@docusaurus/Translate'; import Translate, {translate} from '@docusaurus/Translate'
export const features = [{ export const features = [{
title: translate({ title: translate({
...@@ -121,6 +122,19 @@ export const friendLinks = [ ...@@ -121,6 +122,19 @@ export const friendLinks = [
} }
] ]
export const mediaPartners = [
{
img: 'dromara_qr.png',
alt: 'Dromara',
url: 'https://mp.weixin.qq.com/s/Q3b7ZE802IMF6MwIPJIGQA'
},
{
img: 'JavaHouDuan_logo.png',
alt: 'JavaHouDuan',
url: 'https://mp.weixin.qq.com/s/Ylq51a7Av8ZRuH811xZnDA'
}
]
export const logos = [{ export const logos = [{
/** /**
* Page 1 * Page 1
...@@ -213,7 +227,7 @@ export const SetupExample = ` ...@@ -213,7 +227,7 @@ export const SetupExample = `
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId> <artifactId>sureness-core</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</dependency> </dependency>
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.3' compile group: 'com.usthe.sureness', name: 'sureness-core', version: '1.0.3'
......
import React from 'react' import React from 'react'
import clsx from 'clsx' import clsx from 'clsx'
import useBaseUrl from '@docusaurus/useBaseUrl'
import styles from './Feature.module.css' import styles from './Feature.module.css'
import cdnTransfer from '../../CdnTransfer'
export default function Feature({ imageUrl, title, description }) { export default function Feature({ imageUrl, title, description }) {
const imgUrl = useBaseUrl(imageUrl) const imgUrl = cdnTransfer(imageUrl)
return ( return (
<div className={clsx('col col--4', styles.feature)}> <div className={clsx('col col--4', styles.feature)}>
{imgUrl && ( {imgUrl && (
......
...@@ -4,6 +4,7 @@ import styles from './LogoCarousel.module.css' ...@@ -4,6 +4,7 @@ import styles from './LogoCarousel.module.css'
const INTERVAL_LENGTH = 5000 const INTERVAL_LENGTH = 5000
const LOGO_WIDTH = 150 const LOGO_WIDTH = 150
const cdnUrl = 'https://cdn.jsdelivr.net/gh/usthe/sureness@gh-pages/img/icons/'
let ticks = 0 let ticks = 0
...@@ -18,6 +19,8 @@ export default class LogoCarousel extends React.Component { ...@@ -18,6 +19,8 @@ export default class LogoCarousel extends React.Component {
margin: 70 margin: 70
} }
this.imgUrl =
this.containerRef = React.createRef() this.containerRef = React.createRef()
} }
...@@ -73,7 +76,7 @@ export default class LogoCarousel extends React.Component { ...@@ -73,7 +76,7 @@ export default class LogoCarousel extends React.Component {
this.list = () => ( this.list = () => (
<ul style={{ transform: `translate(${this.state.position}px, 0px)` }}> <ul style={{ transform: `translate(${this.state.position}px, 0px)` }}>
{this.props.logos.map((value, index) => ( {this.props.logos.map((value, index) => (
<li key={index}><a href={value.url} target="_blank" rel="noopener noreferrer"><img src={'img/icons/' + value.img} alt={value.alt} /></a></li> <li key={index}><a href={value.url} target="_blank" rel="noopener noreferrer"><img src={cdnUrl + value.img} alt={value.alt} /></a></li>
))} ))}
</ul> </ul>
) )
......
...@@ -11,9 +11,10 @@ import Feature from './components/Feature' ...@@ -11,9 +11,10 @@ import Feature from './components/Feature'
import Section from './components/Section' import Section from './components/Section'
import Highlight from './components/Highlight' import Highlight from './components/Highlight'
import LogoCarousel from './components/LogoCarousel' import LogoCarousel from './components/LogoCarousel'
import cdnTransfer from '../CdnTransfer'
import styles from './styles.module.css' import styles from './styles.module.css'
import { features, SetupExample, SurenessIntegration, friendLinks } from '../constants' import { features, SetupExample, SurenessIntegration, friendLinks, mediaPartners } from '../constants'
function Home() { function Home() {
const context = useDocusaurusContext() const context = useDocusaurusContext()
...@@ -25,14 +26,14 @@ function Home() { ...@@ -25,14 +26,14 @@ function Home() {
<header className={clsx('hero hero--primary', styles.heroBanner)}> <header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container"> <div className="container">
<h1 className="hero__title"> <h1 className="hero__title">
<img src="img/brand128.svg"/> <img src={cdnTransfer('img/brand128.svg')}/>
</h1> </h1>
<p className="hero__subtitle"><Translate>Focus on Protection of API</Translate></p> <p className="hero__subtitle"><Translate>Focus on Protection of API</Translate></p>
<div className={styles.social}> <div className={styles.social}>
<a href="https://www.apache.org/licenses/LICENSE-2.0.html"><img <a href="https://www.apache.org/licenses/LICENSE-2.0.html"><img
src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg"/></a> src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg"/></a>
<a href="https://search.maven.org/artifact/com.usthe.sureness/sureness-core"><img <a href="https://search.maven.org/artifact/com.usthe.sureness/sureness-core"><img
src="https://img.shields.io/badge/Maven%20Central-1.0.4-blue.svg"/></a> src="https://img.shields.io/badge/Maven%20Central-1.0.5-blue.svg"/></a>
<a href="https://www.apache.org/licenses/LICENSE-2.0.html"><img <a href="https://www.apache.org/licenses/LICENSE-2.0.html"><img
src="https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red"/></a> src="https://img.shields.io/github/release-date/dromara/sureness?color=blue&logo=figshare&logoColor=red"/></a>
<a href="https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks"><img <a href="https://img.shields.io/github/status/contexts/pulls/dromara/sureness/8?label=pull%20checks"><img
...@@ -123,15 +124,15 @@ function Home() { ...@@ -123,15 +124,15 @@ function Home() {
<div> <div>
<h4>Native Support for:</h4> <h4>Native Support for:</h4>
<a href="https://spring.io/" className={styles.frameworkLogos}><img <a href="https://spring.io/" className={styles.frameworkLogos}><img
src="img/icons/spring-logo.svg" alt="spring"/></a> src={cdnTransfer('img/icons/spring-logo.svg')} alt="spring"/></a>
<a href="https://javalin.io/" className={styles.frameworkLogos}><img <a href="https://javalin.io/" className={styles.frameworkLogos}><img
src="img/icons/javalin_logo.svg" alt="Javalin"/></a> src={cdnTransfer('img/icons/javalin_logo.svg')} alt="Javalin"/></a>
<a href="https://micronaut.io/" className={styles.frameworkLogos}><img <a href="https://micronaut.io/" className={styles.frameworkLogos}><img
src="img/icons/micronaut_logo.png" alt="Micronaut"/></a> src={cdnTransfer('img/icons/micronaut_logo.png')} alt="Micronaut"/></a>
<a href="https://quarkus.io/" className={styles.frameworkLogos}><img <a href="https://quarkus.io/" className={styles.frameworkLogos}><img
src="img/icons/quarkus_logo.svg" alt="Quarkus"/></a> src={cdnTransfer('img/icons/quarkus_logo.svg')} alt="Quarkus"/></a>
<a href="https://ktor.io/" className={styles.frameworkLogos}><img <a href="https://ktor.io/" className={styles.frameworkLogos}><img
src="img/icons/ktor_logo.svg" alt="Ktor"/></a> src={cdnTransfer('img/icons/ktor_logo.svg')} alt="Ktor"/></a>
</div> </div>
</> </>
} }
...@@ -141,7 +142,7 @@ function Home() { ...@@ -141,7 +142,7 @@ function Home() {
<img <img
width="760" width="760"
height="445" height="445"
src="img/compare.png" src={cdnTransfer('img/compare.png')}
/> />
} }
isDark isDark
...@@ -200,7 +201,7 @@ function Home() { ...@@ -200,7 +201,7 @@ function Home() {
<img <img
width="560" width="560"
height="415" height="415"
src="img/benchmark_en.png" src={cdnTransfer('img/benchmark_en.png')}
/> />
} }
reversed reversed
...@@ -243,7 +244,7 @@ function Home() { ...@@ -243,7 +244,7 @@ function Home() {
<img <img
width="760" width="760"
height="405" height="405"
src="img/PathRoleMatcher.svg" src={cdnTransfer('img/PathRoleMatcher.svg')}
/> />
} }
isDark isDark
...@@ -303,6 +304,10 @@ function Home() { ...@@ -303,6 +304,10 @@ function Home() {
<Section> <Section>
<LogoCarousel logos={friendLinks} headerTitle={translate({message: 'Friend Links'})}></LogoCarousel> <LogoCarousel logos={friendLinks} headerTitle={translate({message: 'Friend Links'})}></LogoCarousel>
</Section> </Section>
{/*Media Partners*/}
<Section>
<LogoCarousel logos={mediaPartners} headerTitle={translate({message: 'Media Partners'})}></LogoCarousel>
</Section>
</main> </main>
</Layout> </Layout>
) )
......
...@@ -7226,9 +7226,9 @@ path-key@^3.0.0, path-key@^3.1.0: ...@@ -7226,9 +7226,9 @@ path-key@^3.0.0, path-key@^3.1.0:
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.6: path-parse@^1.0.6:
version "1.0.6" version "1.0.7"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-to-regexp@0.1.7: path-to-regexp@0.1.7:
version "0.1.7" version "0.1.7"
...@@ -7820,7 +7820,7 @@ querystring@0.2.0: ...@@ -7820,7 +7820,7 @@ querystring@0.2.0:
querystringify@^2.1.1: querystringify@^2.1.1:
version "2.2.0" version "2.2.0"
resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
queue-microtask@^1.2.2: queue-microtask@^1.2.2:
...@@ -8311,7 +8311,7 @@ require-main-filename@^2.0.0: ...@@ -8311,7 +8311,7 @@ require-main-filename@^2.0.0:
requires-port@^1.0.0: requires-port@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
resolve-cwd@^2.0.0: resolve-cwd@^2.0.0:
...@@ -9640,9 +9640,9 @@ url-parse-lax@^3.0.0: ...@@ -9640,9 +9640,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0" prepend-http "^2.0.0"
url-parse@^1.4.3, url-parse@^1.5.1: url-parse@^1.4.3, url-parse@^1.5.1:
version "1.5.1" version "1.5.3"
resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sureness-core.version>1.0.4</sureness-core.version> <sureness-core.version>1.0.5</sureness-core.version>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<dependency> <dependency>
<groupId>com.jfinal</groupId> <groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId> <artifactId>jfinal</artifactId>
<version>4.9.10</version> <version>4.9.11</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
......
# MicroProfile generated Application
## Introduction
MicroProfile Starter has generated this MicroProfile application for you.
The generation of the executable jar file can be performed by issuing the following command
mvn clean package
mvn clean install -Pwildfly
This will create an executable jar file **demo-wildfly.jar** within the _target_ maven folder. This can be started by executing the following command
java -jar target/demo-wildfly.jar
To launch the test page, open your browser at the following URL
http://localhost:8080/index.html
## Specification examples
By default, there is always the creation of a JAX-RS application class to define the path on which the JAX-RS endpoints are available.
Also, a simple Hello world endpoint is created, have a look at the class **HelloController**.
More information on MicroProfile can be found [here](https://microprofile.io/)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>samples</artifactId>
<groupId>com.usthe.sureness</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<artifactId>micro-profile-sureness</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<version.wildfly>23.0.0.Final</version.wildfly>
<failOnMissingWebXml>false</failOnMissingWebXml>
<final.name>demo</final.name>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.install.skip>true</maven.install.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>4.0.1</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId>
</dependency>
</dependencies>
<build>
<finalName>demo</finalName>
</build>
<profiles>
<profile>
<id>wildfly</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-jar-maven-plugin</artifactId>
<version>1.0.0.Alpha4</version>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
<configuration>
<feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#${version.wildfly}</feature-pack-location>
<layers>
<layer>jaxrs</layer>
</layers>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<version>1.0.1.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>jboss-public-repository</id>
<name>JBoss Public Maven Repository Group</name>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>Red Hat GA</id>
<name>Red Hat GA</name>
<url>https://maven.repository.redhat.com/ga/</url>
</repository>
</repositories>
</profile>
</profiles>
</project>
package com.usthe.sureness.microprofile;
import com.usthe.sureness.DefaultSurenessConfig;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* @author Lenovo
*/
@ApplicationPath("/")
public class DemoRestApplication extends Application {
public DemoRestApplication(){
super();
new DefaultSurenessConfig(DefaultSurenessConfig.SUPPORT_JAX_RS);
}
}
package com.usthe.sureness.microprofile;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
/**
* @author Lenovo
*/
@Path("/hello")
@Singleton
public class HelloController {
@GET
public String sayHello() {
return "Hello World";
}
}
package com.usthe.sureness.microprofile;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
/**
* @author Lenovo
*/
@Path("api")
public class ResourceController {
/** access success message **/
public static final String SUCCESS_ACCESS_RESOURCE = "access this resource: %s success";
@GET
@Path("v1/bar/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock1(@Context Request servletRequest, @PathParam("id") String id) {
return String.format(SUCCESS_ACCESS_RESOURCE, "get /api/v1/bar/" + id);
}
@POST
@Path("v1/bar")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock2(@Context Request servletRequest) {
return String.format(SUCCESS_ACCESS_RESOURCE, "post /api/v1/bar");
}
@PUT
@Path("v2/bar")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock3(@Context Request servletRequest) {
return String.format(SUCCESS_ACCESS_RESOURCE, "put /api/v2/bar");
}
@GET
@Path("v2/foo")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock4(@Context Request servletRequest) {
return String.format(SUCCESS_ACCESS_RESOURCE, "get /api/v2/foo");
}
@DELETE
@Path("v2/foo")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock5(@Context Request servletRequest) {
return String.format(SUCCESS_ACCESS_RESOURCE, "delete /api/v2/foo");
}
@GET
@Path("v3/foo")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock6(@Context Request servletRequest) {
return String.format(SUCCESS_ACCESS_RESOURCE, "get /api/v3/foo");
}
}
package com.usthe.sureness.microprofile;
import com.usthe.sureness.mgt.SurenessSecurityManager;
import com.usthe.sureness.processor.exception.*;
import com.usthe.sureness.subject.SubjectSum;
import com.usthe.sureness.util.SurenessContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.container.*;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
/**
* @author Lenovo
*/
@Provider
@PreMatching
public class SurenessFilter implements ContainerRequestFilter, ContainerResponseFilter {
/** logger **/
private static final Logger logger = LoggerFactory.getLogger(SurenessFilter.class);
@Override
public void filter(ContainerRequestContext requestContext) {
try {
SubjectSum subject = SurenessSecurityManager.getInstance().checkIn(requestContext);
// You can consider using SurenessContextHolder to bind subject in threadLocal
// if bind, please remove it when end
if (subject != null) {
SurenessContextHolder.bindSubject(subject);
}
} catch (IncorrectCredentialsException | UnknownAccountException | ExpiredCredentialsException e1) {
logger.debug("this request account info is illegal");
requestContext.abortWith(Response.status(401).entity(e1.getMessage()).build());
} catch (NeedDigestInfoException e4) {
logger.debug("you should try once again with digest auth information");
requestContext.abortWith(Response.status(401).header("WWW-Authenticate", e4.getAuthenticate()).build());
} catch (UnauthorizedException e5) {
logger.debug("this account can not access this resource");
requestContext.abortWith(Response.status(403).entity(e5.getMessage()).build());
} catch (RuntimeException e) {
logger.error("other exception happen: ", e);
requestContext.abortWith(Response.status(500).entity(e.getMessage()).build());
}
}
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
SurenessContextHolder.clear();
}
}
## -- sureness.yml document dataSource-- ##
# load api resource which need be protected, config role who can access these resource.
# resources that are not configured are also authenticated and protected by default, but not authorized
# eg: /api/v1/bar===post===[role1] means /api/v1/bar===post can be access by role1
# eg: /api/v3/foo===get===[] means /api/v3/foo===* can not be access by any role
resourceRole:
- /api/v1/bar/*===get===[role1,role2,role3]
- /api/v1/bar===post===[role1]
- /api/v2/bar===put===[role2]
- /api/v2/foo===get===[role3]
- /api/v3/foo===get===[]
# load api resource which do not need be protected, means them need be excluded.
# these api resource can be access by everyone
# eg: /**/*.png===* means get/post/put/delete/patch any url suffixed with `.png` can be access by everyone
excludedResource:
- /api/v2/foo===delete
- /**/*.html===get
- /**/*.js===get
- /**/*.css===get
- /**/*.ico===*
- /**/*.png===*
- /hello
# account info
# there are three account: sam, tom, lisa
# eg: sam has [role1,role2,role3], password is sam123, has salt -> 123
# eg: tom has role2, password is tom123
# eg: lisa has role3, password is lisa123
account:
- appId: sam
# if add salt, the credential is encrypted by md5 - result is: MD5(password+salt)
# digest auth not support encrypted credential
credential: 1B9E9136628CB1B161AE47132DD7AF19
salt: 123
role: [role1,role2,role3]
- appId: tom
credential: tom123
role: [role2]
- appId: lisa
credential: lisa123
role: [role3]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
## -- sureness.yml document dataSource-- ##
# load api resource which need be protected, config role who can access these resource.
# resources that are not configured are also authenticated and protected by default, but not authorized
# eg: /api/v1/bar===post===[role1] means /api/v1/bar===post can be access by role1
# eg: /api/v3/foo===get===[] means /api/v3/foo===* can not be access by any role
resourceRole:
- /api/v1/bar/*===get===[role1,role2,role3]
- /api/v1/bar===post===[role1]
- /api/v2/bar===put===[role2]
- /api/v2/foo===get===[role3]
- /api/v3/foo===get===[]
# load api resource which do not need be protected, means them need be excluded.
# these api resource can be access by everyone
# eg: /**/*.png===* means get/post/put/delete/patch any url suffixed with `.png` can be access by everyone
excludedResource:
- /api/v2/foo===delete
- /**/*.html===get
- /**/*.js===get
- /**/*.css===get
- /**/*.ico===*
- /**/*.png===*
- /hello
# account info
# there are three account: sam, tom, lisa
# eg: sam has [role1,role2,role3], password is sam123, has salt -> 123
# eg: tom has role2, password is tom123
# eg: lisa has role3, password is lisa123
account:
- appId: sam
# if add salt, the credential is encrypted by md5 - result is: MD5(password+salt)
# digest auth not support encrypted credential
credential: 1B9E9136628CB1B161AE47132DD7AF19
salt: 123
role: [role1,role2,role3]
- appId: tom
credential: tom123
role: [role2]
- appId: lisa
credential: lisa123
role: [role3]
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Eclipse MicroProfile demo</title>
</head>
<body>
<h2>MicroProfile</h2>
<a href="#" target="_blank" >Hello JAX-RS endpoint</a> <br/>
</body>
</html>
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
<module>spring-gateway-sureness</module> <module>spring-gateway-sureness</module>
<module>zuul-sureness</module> <module>zuul-sureness</module>
<module>sureness-spring-boot-starter-example</module> <module>sureness-spring-boot-starter-example</module>
<module>micro-profile-sureness</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-boot-starter-sureness.version>1.0.0-beta.1</spring-boot-starter-sureness.version>
</properties> </properties>
<dependencies> <dependencies>
...@@ -30,8 +31,8 @@ ...@@ -30,8 +31,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.usthe.sureness</groupId> <groupId>com.usthe.sureness</groupId>
<artifactId>sureness-spring-boot-starter</artifactId> <artifactId>spring-boot-starter-sureness</artifactId>
<version>${project.version}</version> <version>${spring-boot-starter-sureness.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
......
...@@ -10,10 +10,17 @@ logging: ...@@ -10,10 +10,17 @@ logging:
root: info root: info
sureness: sureness:
enable: true enabled: true
supportType: servlet
authTypes: authTypes:
- jwt - Jwt
token: ?::4s9ssf2sf4sed45pf):RnLN7XNn4wARoQXizIv6MHUsIV+EFfiMw/x7R0ntu4aWr/CWuApcFajCyaFv0bwq2Eik0jdrKUtsA6bx3sDJeFV643R+YYzGMRIqcBIp6AKA98GM2RIqcBIp6-?::4390fsf4sdl6opf)4ZI:tdQMtcQQ14pkOAQdQ546 - Basic
scanPackages: - Digest
- com.usthe.sureness.bootstrap support-types:
\ No newline at end of file - Servlet
- Websocket
jwt:
secret-key: ?::4s9ssf2sf4sed45pf):RnLN7XNn4wARoQXizIv6MHUsIV+EFfiMw/x7R0ntu4aWr/CWuApcFajCyaFv0bwq2Eik0jdrKUtsA6bx3sDJeFV643R+YYzGMRIqcBIp6AKA98GM2RIqcBIp6-?::4390fsf4sdl6opf)4ZI:tdQMtcQQ14pkOAQdQ546
annotation:
enable: true
scan-packages:
- com.usthe.sureness.bootstrap.controller
...@@ -8,13 +8,11 @@ ...@@ -8,13 +8,11 @@
<version>1.0.0-SNAPSHOT</version> <version>1.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<modules>
<module>sureness-spring-boot-starter</module>
</modules>
<artifactId>support</artifactId> <artifactId>support</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules>
<module>spring-boot-starter-sureness</module>
</modules>
</project> </project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.usthe.sureness</groupId>
<artifactId>spring-boot-starter-sureness</artifactId>
<version>1.0.0-beta.2</version>
<packaging>jar</packaging>
<name>spring-boot-starter-sureness</name>
<inceptionYear>2019</inceptionYear>
<url>https://github.com/dromara/sureness</url>
<description>
Sureness is a simple and efficient open-source security framework that focus on protection for restful api.
</description>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<name>ChineseTony</name>
<email>13206573871@163.com</email>
<organization>cugb</organization>
<organizationUrl>https://www.cugb.edu.cn/</organizationUrl>
</developer>
<developer>
<name>tomsun28</name>
<email>tomsun28@outlook.com</email>
<organization>usthe</organization>
<organizationUrl>usthe.com</organizationUrl>
</developer>
</developers>
<scm>
<connection>
scm:git:https://github.com/dromara/sureness.git
</connection>
<developerConnection>
scm:git:https://github.com/dromara/sureness.git
</developerConnection>
<url>https://github.com/dromara/sureness</url>
<tag>1.0.2</tag>
</scm>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sureness-core.version>1.0.4-beta.2</sureness-core.version>
<spring-boot.version>2.4.5</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId>
<version>${sureness-core.version}</version>
</dependency>
</dependencies>
<distributionManagement>
<snapshotRepository>
<id>tom</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>tom</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<profiles>
<profile>
<id>deploy</id>
<activation>
<property>
<name>gpg.passphrase</name>
</property>
</activation>
<build>
<plugins>
<!-- Source -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<configuration>
<encoding>UTF-8</encoding>
<aggregate>true</aggregate>
<charset>UTF-8</charset>
<docencoding>UTF-8</docencoding>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- gpg -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<!-- Prevent `gpg` from using pinentry programs -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<!-- nexus -->
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>tom</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.usthe.sureness.configuration;
import com.usthe.sureness.matcher.DefaultPathRoleMatcher;
import com.usthe.sureness.matcher.PathTreeProvider;
import com.usthe.sureness.matcher.TreePathRoleMatcher;
import com.usthe.sureness.mgt.SecurityManager;
import com.usthe.sureness.mgt.SurenessSecurityManager;
import com.usthe.sureness.processor.DefaultProcessorManager;
import com.usthe.sureness.processor.Processor;
import com.usthe.sureness.processor.ProcessorManager;
import com.usthe.sureness.processor.support.DigestProcessor;
import com.usthe.sureness.processor.support.JwtProcessor;
import com.usthe.sureness.processor.support.NoneProcessor;
import com.usthe.sureness.processor.support.PasswordProcessor;
import com.usthe.sureness.processor.support.SessionProcessor;
import com.usthe.sureness.provider.SurenessAccountProvider;
import com.usthe.sureness.provider.annotation.AnnotationPathTreeProvider;
import com.usthe.sureness.provider.ducument.DocumentAccountProvider;
import com.usthe.sureness.provider.ducument.DocumentPathTreeProvider;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.SubjectFactory;
import com.usthe.sureness.subject.SurenessSubjectFactory;
import com.usthe.sureness.subject.creater.BasicSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.BasicSubjectServletCreator;
import com.usthe.sureness.subject.creater.BasicSubjectSpringReactiveCreator;
import com.usthe.sureness.subject.creater.DigestSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.DigestSubjectServletCreator;
import com.usthe.sureness.subject.creater.DigestSubjectSpringReactiveCreator;
import com.usthe.sureness.subject.creater.JwtSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.JwtSubjectServletCreator;
import com.usthe.sureness.subject.creater.JwtSubjectSpringReactiveCreator;
import com.usthe.sureness.subject.creater.JwtSubjectWsJaxRsCreator;
import com.usthe.sureness.subject.creater.JwtSubjectWsServletCreator;
import com.usthe.sureness.subject.creater.JwtSubjectWsSpringReactiveCreator;
import com.usthe.sureness.subject.creater.NoneSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.NoneSubjectServletCreator;
import com.usthe.sureness.subject.creater.NoneSubjectSpringReactiveCreator;
import com.usthe.sureness.subject.creater.SessionSubjectServletCreator;
import com.usthe.sureness.util.JsonWebTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static com.usthe.sureness.configuration.SurenessProperties.*;
/**
* @author wangtao
* @date 2021/7/3
*/
@Configuration
@ConditionalOnProperty(prefix = "sureness", name = "enabled", havingValue = "true",
matchIfMissing = true)
@ConditionalOnResource(resources = "META-INF/spring.factories")
@AutoConfigureAfter(value = {SurenessProperties.class})
public class SurenessAutoConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(SurenessAutoConfiguration.class);
private static final int NUM_2 = 2;
private ApplicationContext applicationContext;
private SurenessProperties surenessProperties;
public SurenessAutoConfiguration(ApplicationContext applicationContext, SurenessProperties properties) {
this.applicationContext = applicationContext;
this.surenessProperties = properties;
}
@Bean
@ConditionalOnMissingBean(SurenessAccountProvider.class)
SurenessAccountProvider accountProvider(){
return new DocumentAccountProvider();
}
@Bean
@ConditionalOnMissingBean(PathTreeProvider.class)
PathTreeProvider pathTreeProvider(DefaultPathRoleMatcher pathRoleMatcher){
PathTreeProvider pathTreeProvider = new DocumentPathTreeProvider();
pathRoleMatcher.setPathTreeProvider(pathTreeProvider);
pathRoleMatcher.buildTree();
return pathTreeProvider;
}
@Bean
@ConditionalOnMissingBean(SubjectFactory.class)
@ConditionalOnBean(SurenessProperties.class)
SubjectFactory subjectFactory() {
SubjectFactory subjectFactory = new SurenessSubjectFactory();
List<SubjectCreate> subjectCreates = new ArrayList<>();
Set<AuthType> authTypes = surenessProperties.getAuthTypes();
if (authTypes == null || authTypes.isEmpty()) {
// if is null, default config is basic auth, jwt auth
LOGGER.info("[sureness-starter] - use default authTypes: Basic, Jwt");
authTypes = new HashSet<>(2);
authTypes.add(AuthType.BASIC);
authTypes.add(AuthType.JWT);
surenessProperties.setAuthTypes(authTypes);
}
Set<SupportType> supportTypes = surenessProperties.getSupportTypes();
if (supportTypes == null || supportTypes.isEmpty()) {
// if is null, default config is servlet, websocket
LOGGER.info("[sureness-starter] - use default supportTypes: Servlet, Websocket");
supportTypes = new HashSet<>(2);
supportTypes.add(SupportType.Servlet);
supportTypes.add(SupportType.WebSocket);
surenessProperties.setSupportTypes(supportTypes);
}
if (supportTypes.size() >= NUM_2 && !supportTypes.contains(SupportType.WebSocket)) {
LOGGER.error("[sureness-starter] - supportTypes: Servlet, JAX-RS or Spring-Reactor neither can exist at the same time");
throw new SurenessInitException("[sureness-starter] - supportTypes: Servlet, JAX-RS or Spring-Reactor neither can exist at the same time");
}
if (supportTypes.contains(SupportType.Servlet)) {
subjectCreates.add(new NoneSubjectServletCreator());
if (supportTypes.contains(SupportType.WebSocket)) {
subjectCreates.add(new JwtSubjectWsServletCreator());
}
if (authTypes.contains(AuthType.BASIC)){
subjectCreates.add(new BasicSubjectServletCreator());
}
if (authTypes.contains(AuthType.JWT)){
subjectCreates.add(new JwtSubjectServletCreator());
subjectCreates.add(new JwtSubjectWsServletCreator());
}
if (authTypes.contains(AuthType.DIGEST)){
subjectCreates.add(new DigestSubjectServletCreator());
}
if (surenessProperties.isSessionEnabled()) {
subjectCreates.add(new SessionSubjectServletCreator());
}
} else if (supportTypes.contains(SupportType.JAX_RS)){
// other is JAX-RS
subjectCreates.add(new NoneSubjectJaxRsCreator());
if (supportTypes.contains(SupportType.WebSocket)) {
subjectCreates.add(new JwtSubjectWsJaxRsCreator());
}
if (authTypes.contains(AuthType.BASIC)){
subjectCreates.add(new BasicSubjectJaxRsCreator());
}
if (authTypes.contains(AuthType.JWT)){
subjectCreates.add(new JwtSubjectJaxRsCreator());
subjectCreates.add(new JwtSubjectWsJaxRsCreator());
}
if (authTypes.contains(AuthType.DIGEST)){
subjectCreates.add(new DigestSubjectJaxRsCreator());
}
} else if (supportTypes.contains(SupportType.Spring_Reactor)) {
subjectCreates.add(new NoneSubjectSpringReactiveCreator());
if (supportTypes.contains(SupportType.WebSocket)) {
subjectCreates.add(new JwtSubjectWsSpringReactiveCreator());
}
if (authTypes.contains(AuthType.BASIC)) {
subjectCreates.add(new BasicSubjectSpringReactiveCreator());
}
if (authTypes.contains(AuthType.JWT)) {
subjectCreates.add(new JwtSubjectSpringReactiveCreator());
}
if (authTypes.contains(AuthType.DIGEST)) {
subjectCreates.add(new DigestSubjectSpringReactiveCreator());
}
}
subjectFactory.registerSubjectCreator(subjectCreates);
LOGGER.info("[sureness-starter] - SurenessSubjectFactory init success");
return subjectFactory;
}
@Bean
@ConditionalOnMissingBean(SecurityManager.class)
SecurityManager securityManager(
ProcessorManager processorManager,
TreePathRoleMatcher pathRoleMatcher,
SubjectFactory subjectFactory) {
if (surenessProperties.getJwt() != null) {
String jwtSecret = surenessProperties.getJwt().getSecretKey();
if (jwtSecret != null && !"".equals(jwtSecret)) {
JsonWebTokenUtil.setDefaultSecretKey(jwtSecret);
}
}
SurenessSecurityManager securityManager = SurenessSecurityManager.getInstance();
securityManager.setPathRoleMatcher(pathRoleMatcher);
securityManager.setSubjectFactory(subjectFactory);
securityManager.setProcessorManager(processorManager);
return securityManager;
}
@Bean
@ConditionalOnMissingBean(ProcessorManager.class)
ProcessorManager processorManager(SurenessAccountProvider accountProvider) {
List<Processor> processorList = new LinkedList<>();
NoneProcessor noneProcessor = new NoneProcessor();
processorList.add(noneProcessor);
Set<AuthType> authTypes = surenessProperties.getAuthTypes();
if (authTypes == null || authTypes.isEmpty()) {
// if is null, default config is basic auth, jwt auth
LOGGER.info("[sureness-starter] - use default authTypes: Basic, Jwt");
authTypes = new HashSet<>(2);
authTypes.add(AuthType.BASIC);
authTypes.add(AuthType.JWT);
surenessProperties.setAuthTypes(authTypes);
}
if (authTypes.contains(AuthType.JWT)) {
JwtProcessor jwtProcessor = new JwtProcessor();
processorList.add(jwtProcessor);
}
if (authTypes.contains(AuthType.BASIC)) {
PasswordProcessor passwordProcessor = new PasswordProcessor();
passwordProcessor.setAccountProvider(accountProvider);
processorList.add(passwordProcessor);
}
if (authTypes.contains(AuthType.DIGEST)) {
DigestProcessor digestProcessor = new DigestProcessor();
digestProcessor.setAccountProvider(accountProvider);
processorList.add(digestProcessor);
}
if (surenessProperties.isSessionEnabled()) {
SessionProcessor sessionProcessor = new SessionProcessor();
processorList.add(sessionProcessor);
}
return new DefaultProcessorManager(processorList);
}
@Bean
@ConditionalOnMissingBean(TreePathRoleMatcher.class)
TreePathRoleMatcher pathRoleMatcher(PathTreeProvider pathTreeProvider,
DefaultPathRoleMatcher pathRoleMatcher) {
List<PathTreeProvider> providers = new ArrayList<>();
providers.add(pathTreeProvider);
// add documentProvider default
providers.add(new DocumentPathTreeProvider());
AnnotationProperties annotationProperties = surenessProperties.getAnnotation();
if (annotationProperties != null && annotationProperties.isEnable()) {
List<String> scanPackages = annotationProperties.getScanPackages();
if (scanPackages == null || scanPackages.isEmpty()) {
LOGGER.error("[sureness-starter] - annotation is enable but annotation.scanPackages is null, need config!");
} else {
AnnotationPathTreeProvider annotationPathTreeProvider = new AnnotationPathTreeProvider();
annotationPathTreeProvider.setScanPackages(scanPackages);
providers.add(annotationPathTreeProvider);
}
}
pathRoleMatcher.setPathTreeProviderList(providers);
pathRoleMatcher.buildTree();
return pathRoleMatcher;
}
@Bean
@ConditionalOnMissingBean(DefaultPathRoleMatcher.class)
public DefaultPathRoleMatcher defaultPathRoleMatcher(){
return new DefaultPathRoleMatcher();
}
@Bean
@ConditionalOnWebApplication
@ConditionalOnMissingBean(value = FilterRegistrationBean.class)
@ConditionalOnExpression("'${sureness.support-types}'.contains('com.usthe.sureness.configuration.SupportType.Servlet')")
public FilterRegistrationBean filterRegistration(
SecurityManager securityManager
) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SurenessFilter(securityManager));
registration.addUrlPatterns("/*");
registration.setFilter((Filter)
applicationContext.getBean("surenessFilter"));
registration.setName("surenessFilter");
registration.setOrder(1);
return registration;
}
@Bean
@ConditionalOnMissingBean(name = "surenessFilter")
public Filter surenessFilter(SecurityManager securityManager){
return new SurenessFilter(securityManager);
}
}
package com.usthe.sureness.configuration; package com.usthe.sureness.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.usthe.sureness.mgt.SecurityManager; import com.usthe.sureness.mgt.SecurityManager;
import com.usthe.sureness.processor.exception.DisabledAccountException; import com.usthe.sureness.processor.exception.DisabledAccountException;
import com.usthe.sureness.processor.exception.ExcessiveAttemptsException; import com.usthe.sureness.processor.exception.ExcessiveAttemptsException;
...@@ -27,6 +26,7 @@ import java.io.IOException; ...@@ -27,6 +26,7 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
/** /**
* @author wangtao * @author wangtao
* @date 2021/7/8 * @date 2021/7/8
...@@ -122,12 +122,7 @@ public class SurenessFilter implements Filter { ...@@ -122,12 +122,7 @@ public class SurenessFilter implements Filter {
((HttpServletResponse) response).addHeader(key, value.get(0))); ((HttpServletResponse) response).addHeader(key, value.get(0)));
try (PrintWriter printWriter = response.getWriter()) { try (PrintWriter printWriter = response.getWriter()) {
if (content.getBody() != null) { if (content.getBody() != null) {
if (content.getBody() instanceof String) { printWriter.write(content.getBody().toString());
printWriter.write(content.getBody().toString());
} else {
ObjectMapper objectMapper = new ObjectMapper();
printWriter.write(objectMapper.writeValueAsString(content.getBody()));
}
} else { } else {
printWriter.flush(); printWriter.flush();
} }
......
package com.usthe.sureness.configuration;
import com.usthe.sureness.processor.exception.ExtSurenessException;
/**
* sureness init exception
* @author tomsun28
* @date 2021/7/24 14:36
*/
public class SurenessInitException extends ExtSurenessException {
public SurenessInitException(String message) {
super(message);
}
}
package com.usthe.sureness.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
/**
* @author wangtao
* @date 2021/7/3
*/
@Component
@ConfigurationProperties(prefix = "sureness")
public class SurenessProperties {
/**
* sureness enabled, default true
*/
private boolean enabled = true;
/**
* 可配置 支持 websocket, servlet, jax-rs或者其它容器协议
*/
private Set<SupportType> supportTypes;
/**
* 支持的认证方式 Jwt, basic auth, digest auth等其它认证方式
*/
private Set<AuthType> authTypes;
/**
* 当 authType 为 jwt 时设置的属性
*/
private JwtProperties jwt;
/**
* 是否开启 session
*/
private boolean sessionEnabled = false;
/**
* config for Annotation provider
*/
private AnnotationProperties annotation;
public Set<SupportType> getSupportTypes() {
return supportTypes;
}
public void setSupportTypes(Set<SupportType> supportTypes) {
this.supportTypes = supportTypes;
}
public Set<AuthType> getAuthTypes() {
return authTypes;
}
public void setAuthTypes(Set<AuthType> authTypes) {
this.authTypes = authTypes;
}
public JwtProperties getJwt() {
return jwt;
}
public void setJwt(JwtProperties jwt) {
this.jwt = jwt;
}
public boolean isSessionEnabled() {
return sessionEnabled;
}
public void setSessionEnabled(boolean sessionEnabled) {
this.sessionEnabled = sessionEnabled;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public AnnotationProperties getAnnotation() {
return annotation;
}
public void setAnnotation(AnnotationProperties annotation) {
this.annotation = annotation;
}
public static enum AuthType {
/** json web token auth **/
JWT,
/** basic auth **/
BASIC,
/** digest auth **/
DIGEST
}
public static enum SupportType {
/** http servlet **/
Servlet,
/** jax-rs **/
JAX_RS,
/** spring reactor stream **/
Spring_Reactor,
/** websocket **/
WebSocket
}
public static class AnnotationProperties {
private boolean enable = false;
private List<String> scanPackages;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List<String> getScanPackages() {
return scanPackages;
}
public void setScanPackages(List<String> scanPackages) {
this.scanPackages = scanPackages;
}
}
public static class JwtProperties {
private String secretKey;
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>support</artifactId>
<groupId>com.usthe.sureness</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sureness-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.usthe.sureness.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* @author wangtao
* @date 2021/7/3
*/
@Component
@ConfigurationProperties(prefix = "sureness")
public class SurenessProperties {
/**
* 可配置 支持 websocket, servlet, jax-rs或者其它容器协议
*/
private String supportType;
/**
* 支持的认证方式 Jwt, basic auth, digest auth等其它认证方式
*/
private Set<String> authTypes;
/**
* jwt的解析加密密钥
*/
private String token;
private List<String> scanPackages;
public List<String> getScanPackages() {
return scanPackages;
}
public void setScanPackages(List<String> scanPackages) {
this.scanPackages = scanPackages;
}
public String getSupportType() {
return supportType;
}
public void setSupportType(String supportType) {
this.supportType = supportType;
}
public Set<String> getAuthTypes() {
return authTypes;
}
public void setAuthTypes(Set<String> authTypes) {
this.authTypes = authTypes;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "SurenessProperties{" +
"supportType='" + supportType + '\'' +
", authType='" + Arrays.toString(authTypes.toArray(new String[]{})) + '\'' +
", token='" + token + '\'' +
", scanPackages=" + Arrays.toString(scanPackages.toArray(new String[]{})) +
'}';
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册