提交 01e7d7b2 编写于 作者: sinat_25235033's avatar sinat_25235033

support protect quarkus feature

上级 b77a50e1
......@@ -48,9 +48,10 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<javax.servlet.version>3.1.0</javax.servlet.version>
<javax.ws.rs.version>2.1.1</javax.ws.rs.version>
<jjwt.version>0.9.0</jjwt.version>
<yaml.version>1.17</yaml.version>
<servlet.api.version>3.1.0</servlet.api.version>
<xml.bind.version>2.3.0</xml.bind.version>
<slf4j.version>1.7.21</slf4j.version>
<junit.version>4.12</junit.version>
......@@ -60,7 +61,13 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.api.version}</version>
<version>${javax.servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${javax.ws.rs.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
......
......@@ -8,10 +8,15 @@ 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.provider.ducument.DocumentResourceDefaultProvider;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.SubjectFactory;
import com.usthe.sureness.subject.SurenessSubjectFactory;
import com.usthe.sureness.subject.creater.JwtSubjectCreator;
import com.usthe.sureness.subject.creater.BasicAuthPasswordSubjectCreator;
import com.usthe.sureness.subject.creater.BasicSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.JwtSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.JwtSubjectServletCreator;
import com.usthe.sureness.subject.creater.BasicSubjectServletCreator;
import com.usthe.sureness.subject.creater.NoneSubjectJaxRsCreator;
import com.usthe.sureness.subject.creater.NoneSubjectServletCreator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -20,6 +25,7 @@ import java.util.LinkedList;
import java.util.List;
/** 对用文件做持久层权限资源方式的默认配置
* support servlet or jax-rs, default servlet
* @author tomsun28
* @date 11:26 2019-05-26
*/
......@@ -27,11 +33,18 @@ public class DefaultSurenessConfig {
private static final Logger logger = LoggerFactory.getLogger(DefaultSurenessConfig.class);
public static final String SUPPORT_SERVLET = "servlet";
public static final String SUPPORT_JAX_RS = "jax-rs";
public DefaultSurenessConfig() {
this.init();
this.init(SUPPORT_SERVLET);
}
public DefaultSurenessConfig(String supportContainer) {
this.init(supportContainer);
}
private void init() {
private void init(String supportContainer) {
// resource init
DocumentResourceDefaultProvider resourceProvider = new DocumentResourceDefaultProvider();
if (logger.isDebugEnabled()) {
......@@ -62,9 +75,19 @@ public class DefaultSurenessConfig {
// SubjectFactory init
SubjectFactory subjectFactory = new SurenessSubjectFactory();
subjectFactory.registerSubjectCreator(Arrays.asList(
new BasicAuthPasswordSubjectCreator(),
new JwtSubjectCreator()));
List<SubjectCreate> subjectCreates;
if (SUPPORT_JAX_RS.equals(supportContainer)) {
subjectCreates = Arrays.asList(
new NoneSubjectJaxRsCreator(),
new BasicSubjectJaxRsCreator(),
new JwtSubjectJaxRsCreator());
} else {
subjectCreates = Arrays.asList(
new NoneSubjectServletCreator(),
new BasicSubjectServletCreator(),
new JwtSubjectServletCreator());
}
subjectFactory.registerSubjectCreator(subjectCreates);
if (logger.isDebugEnabled()) {
logger.debug("SurenessSubjectFactory init");
}
......
......@@ -6,7 +6,6 @@ import com.usthe.sureness.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
......@@ -110,12 +109,9 @@ public class DefaultPathRoleMatcher implements TreePathRoleMatcher {
}
@Override
public boolean isExcludedResource(Object request) {
public boolean isExcludedResource(Subject request) {
checkComponentInit();
String requestUri = ((HttpServletRequest) request).getRequestURI();
String requestType = ((HttpServletRequest) request).getMethod();
String targetUri = requestUri.concat("===").concat(requestType).toLowerCase();
String exclude = excludeRoot.searchPathFilterRoles(targetUri);
String exclude = excludeRoot.searchPathFilterRoles((String) request.getTargetResource());
return exclude != null && exclude.equals(EXCLUDE_ROLE);
}
......
......@@ -37,5 +37,5 @@ public interface TreePathRoleMatcher {
* @param request 请求内容
* @return 是排除资源true 否则false
*/
boolean isExcludedResource(Object request);
boolean isExcludedResource(Subject request);
}
......@@ -57,6 +57,11 @@ public class SurenessSecurityManager implements SecurityManager {
@Override
public SubjectSum checkIn(Subject token) throws BaseSurenessException {
// 判断请求资源是否是配置的排除过滤资源
// 若是直接通行,返回NULL不抛异常
if (pathRoleMatcher.isExcludedResource(token)) {
return null;
}
pathRoleMatcher.matchRole(token);
return processorManager.process(token);
}
......@@ -64,11 +69,6 @@ public class SurenessSecurityManager implements SecurityManager {
@Override
public SubjectSum checkIn(Object var1) throws BaseSurenessException {
checkComponentInit();
// 判断请求资源是否是配置的排除过滤资源
// 若是直接通行,返回NULL不抛异常
if (pathRoleMatcher.isExcludedResource(var1)) {
return null;
}
// 创建subject list去一次一次认证鉴权尝试
List<Subject> subjectList = createSubject(var1);
......
......@@ -4,6 +4,7 @@ import com.usthe.sureness.processor.BaseProcessor;
import com.usthe.sureness.processor.exception.SurenessAuthenticationException;
import com.usthe.sureness.processor.exception.SurenessAuthorizationException;
import com.usthe.sureness.processor.exception.UnauthorizedException;
import com.usthe.sureness.processor.exception.UnknownAccountException;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.support.NoneSubject;
import org.slf4j.Logger;
......@@ -32,7 +33,7 @@ public class NoneProcessor extends BaseProcessor {
@Override
public Subject authenticated(Subject var) throws SurenessAuthenticationException {
return var;
throw new UnknownAccountException("the request do not have the auth detail, please input your auth");
}
@SuppressWarnings("unchecked")
......@@ -43,7 +44,7 @@ public class NoneProcessor extends BaseProcessor {
if (logger.isDebugEnabled()) {
logger.debug("NoneProcessor authorized fail, due {} need role access", var.getTargetResource());
}
throw new UnauthorizedException("do not have the role access");
throw new UnauthorizedException("authorized forbidden, the request do not have the role access");
}
}
}
package com.usthe.sureness.subject.creater;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.support.PasswordSubject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.container.ContainerRequestContext;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* 支持通过basic auth 创建PasswordSubject 的创建者
* only support JAX-RS
* @author tomsun28
* @date 23:53 2020-09-20
*/
public class BasicSubjectJaxRsCreator implements SubjectCreate {
private static final Logger logger = LoggerFactory.getLogger(BasicSubjectJaxRsCreator.class);
private static final String AUTHORIZATION = "Authorization";
private static final String BASIC = "Basic";
private static final int COUNT_2 = 2;
@Override
public boolean canSupportSubject(Object context) {
// basic auth判断
// ("Authorization", "Basic YWRtaW46YWRtaW4=") --- basic auth
if (context instanceof ContainerRequestContext) {
String authorization = ((ContainerRequestContext)context).getHeaderString(AUTHORIZATION);
return authorization != null && authorization.startsWith(BASIC);
} else {
return false;
}
}
@Override
public Subject createSubject(Object context) {
String authorization = ((ContainerRequestContext)context).getHeaderString(AUTHORIZATION);
//basic auth
String basicAuth = authorization.replace(BASIC, "").trim();
basicAuth = new String(Base64.getDecoder().decode(basicAuth), StandardCharsets.UTF_8);
String[] auth = basicAuth.split(":");
if (auth.length != COUNT_2) {
if (logger.isInfoEnabled()) {
logger.info("can not create basic auth PasswordSubject by this request message");
}
return null;
}
String username = auth[0];
if (username == null || "".equals(username)) {
if (logger.isInfoEnabled()) {
logger.info("can not create basic auth PasswordSubject by this request message, appId can not null");
}
return null;
}
String password = auth[1];
String requestUri = ((ContainerRequestContext) context).getUriInfo().getPath();
String requestType = ((ContainerRequestContext) context).getMethod();
String targetUri = requestUri.concat("===").concat(requestType).toLowerCase();
return PasswordSubject.builder(username, password)
.setTargetResource(targetUri)
.build();
}
}
......@@ -12,12 +12,13 @@ import java.util.Base64;
/**
* 支持通过basic auth 创建PasswordSubject 的创建者
* only support HttpServletRequest
* @author tomsun28
* @date 23:53 2020-02-27
*/
public class BasicAuthPasswordSubjectCreator implements SubjectCreate {
public class BasicSubjectServletCreator implements SubjectCreate {
private static final Logger logger = LoggerFactory.getLogger(BasicAuthPasswordSubjectCreator.class);
private static final Logger logger = LoggerFactory.getLogger(BasicSubjectServletCreator.class);
private static final String AUTHORIZATION = "Authorization";
private static final String BASIC = "Basic";
......
package com.usthe.sureness.subject.creater;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.support.JwtSubject;
import com.usthe.sureness.util.JsonWebTokenUtil;
import com.usthe.sureness.util.SurenessCommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.container.ContainerRequestContext;
/**
* JwtSubject creator
* only support JAX-RS
* @author tomsun28
* @date 23:58 2020-02-27
*/
public class JwtSubjectJaxRsCreator implements SubjectCreate {
private static final Logger logger = LoggerFactory.getLogger(JwtSubjectJaxRsCreator.class);
private static final String BEARER = "Bearer";
private static final String AUTHORIZATION = "Authorization";
@Override
public boolean canSupportSubject(Object context) {
// support bearer jwt
// ("Authorization", "Bearer eyJhbGciOiJIUzUxMi...") --- jwt auth
if (context instanceof ContainerRequestContext) {
String authorization = ((ContainerRequestContext)context).getHeaderString(AUTHORIZATION);
if (authorization != null && authorization.startsWith(BEARER)) {
String jwtValue = authorization.replace(BEARER, "").trim();
return !JsonWebTokenUtil.isNotJsonWebToken(jwtValue);
}
}
return false;
}
@Override
public Subject createSubject(Object context) {
String authorization = ((ContainerRequestContext)context).getHeaderString(AUTHORIZATION);
if (authorization != null && authorization.startsWith(BEARER)) {
// jwt token
String jwtValue = authorization.replace(BEARER, "").trim();
if (JsonWebTokenUtil.isNotJsonWebToken(jwtValue)) {
if (logger.isInfoEnabled()) {
logger.info("can not create JwtSubject by this request message, is not jwt");
}
return null;
}
String requestUri = ((ContainerRequestContext) context).getUriInfo().getPath();
String requestType = ((ContainerRequestContext) context).getMethod();
String targetUri = requestUri.concat("===").concat(requestType.toLowerCase());
String userAgent = SurenessCommonUtil.findUserAgent((ContainerRequestContext) context);
return JwtSubject.builder(jwtValue)
.setTargetResource(targetUri)
.setUserAgent(userAgent)
.build();
}
return null;
}
}
......@@ -12,12 +12,13 @@ import javax.servlet.http.HttpServletRequest;
/**
* JwtSubject creator
* only support HttpServletRequest
* @author tomsun28
* @date 23:58 2020-02-27
*/
public class JwtSubjectCreator implements SubjectCreate {
public class JwtSubjectServletCreator implements SubjectCreate {
private static final Logger logger = LoggerFactory.getLogger(JwtSubjectCreator.class);
private static final Logger logger = LoggerFactory.getLogger(JwtSubjectServletCreator.class);
private static final String BEARER = "Bearer";
private static final String AUTHORIZATION = "Authorization";
......
package com.usthe.sureness.subject.creater;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.support.NoneSubject;
import com.usthe.sureness.util.SurenessCommonUtil;
import javax.ws.rs.container.ContainerRequestContext;
/**
* 无认证信息的subject creator
* 所有请求都能创建出一个NoneSubject
* only support JAX-RS
* @author tomsun28
* @date 15:55 2020-02-28
*/
public class NoneSubjectJaxRsCreator implements SubjectCreate {
@Override
public boolean canSupportSubject(Object context) {
return context instanceof ContainerRequestContext;
}
@Override
public Subject createSubject(Object context) {
String requestUri = ((ContainerRequestContext) context).getUriInfo().getPath();
String requestType = ((ContainerRequestContext) context).getMethod();
String targetUri = requestUri.concat("===").concat(requestType).toLowerCase();
String userAgent = SurenessCommonUtil.findUserAgent((ContainerRequestContext) context);
return NoneSubject.builder()
.setTargetUri(targetUri)
.setUserAgent(userAgent).build();
}
}
......@@ -10,13 +10,14 @@ import javax.servlet.http.HttpServletRequest;
/**
* 无认证信息的subject creator
* 所有请求都能创建出一个NoneSubject
* only support HttpServletRequest
* @author tomsun28
* @date 15:55 2020-02-28
*/
public class NoneSubjectCreator implements SubjectCreate {
public class NoneSubjectServletCreator implements SubjectCreate {
@Override
public boolean canSupportSubject(Object context) {
return true;
return context instanceof HttpServletRequest;
}
@Override
......
......@@ -2,6 +2,7 @@ package com.usthe.sureness.util;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import java.util.Random;
/**
......@@ -23,6 +24,15 @@ public class SurenessCommonUtil {
public static String findUserAgent(HttpServletRequest request) {
String userAgent = request.getHeader(USER_AGENT);
return findUserAgent(userAgent);
}
public static String findUserAgent(ContainerRequestContext request) {
String userAgent = request.getHeaderString(USER_AGENT);
return findUserAgent(userAgent);
}
public static String findUserAgent(String userAgent) {
if (userAgent == null || "".equals(userAgent)) {
userAgent = UNKNOWN;
} else if (userAgent.contains(ANDROID)) {
......
......@@ -2,6 +2,9 @@ package com.usthe.sureness.matcher;
import com.usthe.sureness.matcher.util.TirePathTree;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.SubjectFactory;
import com.usthe.sureness.subject.support.NoneSubject;
import com.usthe.sureness.subject.support.PasswordSubject;
import org.junit.AfterClass;
import org.junit.BeforeClass;
......@@ -85,14 +88,18 @@ public class DefaultPathRoleMatcherTest {
expect(request.getRequestURI()).andReturn("/api/v2/detail");
expect(request.getMethod()).andReturn("put");
replay(request);
assertTrue(pathRoleMatcher.isExcludedResource(request));
Subject subject = NoneSubject.builder().setTargetUri(request.getRequestURI().concat("===")
.concat(request.getMethod()).toLowerCase()).build();
assertTrue(pathRoleMatcher.isExcludedResource(subject));
verify(request);
request = createNiceMock(HttpServletRequest.class);
expect(request.getRequestURI()).andReturn("/book/v2/detail");
expect(request.getMethod()).andReturn("put");
replay(request);
assertFalse(pathRoleMatcher.isExcludedResource(request));
subject = NoneSubject.builder().setTargetUri(request.getRequestURI().concat("===")
.concat(request.getMethod()).toLowerCase()).build();
assertFalse(pathRoleMatcher.isExcludedResource(subject));
verify(request);
}
......
......@@ -16,7 +16,7 @@ import static org.easymock.EasyMock.*;
* @author tomsun28
* @date 21:04 2020-03-08
*/
public class BasicAuthPasswordSubjectCreatorTest {
public class BasicSubjectServletCreatorTest {
private static final String AUTHORIZATION = "Authorization";
private static final String BASIC = "Basic";
......@@ -25,7 +25,7 @@ public class BasicAuthPasswordSubjectCreatorTest {
@Before
public void setUp() {
creator = new BasicAuthPasswordSubjectCreator();
creator = new BasicSubjectServletCreator();
}
@Test
......
......@@ -18,7 +18,7 @@ import static org.easymock.EasyMock.*;
* @author tomsun28
* @date 21:04 2020-03-08
*/
public class JwtSubjectCreatorTest {
public class JwtSubjectServletCreatorTest {
private static final String AUTHORIZATION = "Authorization";
private static final String BEARER = "Bearer";
......@@ -27,7 +27,7 @@ public class JwtSubjectCreatorTest {
@Before
public void setUp() {
creator = new JwtSubjectCreator();
creator = new JwtSubjectServletCreator();
}
......
......@@ -14,13 +14,13 @@ import static org.easymock.EasyMock.*;
* @author tomsun28
* @date 21:05 2020-03-08
*/
public class NoneSubjectCreatorTest {
public class NoneSubjectServletCreatorTest {
private SubjectCreate creator;
@Before
public void setUp() {
creator = new NoneSubjectCreator();
creator = new NoneSubjectServletCreator();
}
......
......@@ -13,8 +13,8 @@ import com.usthe.sureness.provider.SurenessAccountProvider;
import com.usthe.sureness.sample.tom.sureness.creator.CustomSubjectCreator;
import com.usthe.sureness.subject.SubjectFactory;
import com.usthe.sureness.subject.SurenessSubjectFactory;
import com.usthe.sureness.subject.creater.BasicAuthPasswordSubjectCreator;
import com.usthe.sureness.subject.creater.JwtSubjectCreator;
import com.usthe.sureness.subject.creater.BasicSubjectServletCreator;
import com.usthe.sureness.subject.creater.JwtSubjectServletCreator;
import com.usthe.sureness.util.JsonWebTokenUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -65,9 +65,9 @@ public class SurenessConfiguration {
SubjectFactory subjectFactory = new SurenessSubjectFactory();
subjectFactory.registerSubjectCreator(Arrays.asList(
// use default basic auth subject creator
new BasicAuthPasswordSubjectCreator(),
new BasicSubjectServletCreator(),
// use default jwt subject creator
new JwtSubjectCreator(),
new JwtSubjectServletCreator(),
// use custom creator
new CustomSubjectCreator()));
return subjectFactory;
......
......@@ -2,7 +2,7 @@
这里实现了我们除了spring外常用的其他jvm框架集成sureness的样例,方便参考
> only support servlet like tomcat jetty and more
> support servlet(javax.servlet) and jax-rs(javax.ws.rs)
1. javalin - https://javalin.io/
......@@ -11,8 +11,11 @@
2. Ktor - https://ktor.kotlincn.net/quickstart/index.html
> DEMO详见 [ktor-sureness](ktor-sureness)
3. quarkus - https://quarkus.io/get-started/
> DEMO详见 [quarkus-sureness](quarkus-sureness)
**TODO**
3. [quarkus](https://quarkus.io/get-started/)
4. [microprofile](https://start.microprofile.io/)
4. [microprofile](https://start.microprofile.io/)
......@@ -14,5 +14,6 @@
<modules>
<module>ktor-sureness</module>
<module>javalin-sureness</module>
<module>quarkus-sureness</module>
</modules>
</project>
\ No newline at end of file
*
!target/*-runner
!target/*-runner.jar
!target/lib/*
!target/quarkus-app/*
\ No newline at end of file
# Eclipse
.project
.classpath
.settings/
bin/
# IntelliJ
.idea
*.ipr
*.iml
*.iws
# NetBeans
nb-configuration.xml
# Visual Studio Code
.vscode
.factorypath
# OSX
.DS_Store
# Vim
*.swp
*.swo
# patch
*.orig
*.rej
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
release.properties
\ No newline at end of file
# quarkus-sureness project
This project uses Quarkus, the Supersonic Subatomic Java Framework.
If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
## Running the application in dev mode
You can run your application in dev mode that enables live coding using:
```
./mvnw quarkus:dev
```
## Packaging and running the application
The application can be packaged using `./mvnw package`.
It produces the `quarkus-sureness-1.0-SNAPSHOT-runner.jar` file in the `/target` directory.
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/lib` directory.
The application is now runnable using `java -jar target/quarkus-sureness-1.0-SNAPSHOT-runner.jar`.
## Creating a native executable
You can create a native executable using: `./mvnw package -Pnative`.
Or, if you don't have GraalVM installed, you can run the native executable build in a container using: `./mvnw package -Pnative -Dquarkus.native.container-build=true`.
You can then execute your native executable with: `./target/quarkus-sureness-1.0-SNAPSHOT-runner`
If you want to learn more about building native executables, please consult https://quarkus.io/guides/building-native-image.
\ No newline at end of file
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>samples</artifactId>
<groupId>com.usthe.sureness</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>quarkus-sureness</artifactId>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>1.8.0.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>1.8.0.Final</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.usthe.sureness</groupId>
<artifactId>sureness-core</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<!-- <plugin>-->
<!-- <artifactId>maven-surefire-plugin</artifactId>-->
<!-- <version>${surefire-plugin.version}</version>-->
<!-- <configuration>-->
<!-- <systemPropertyVariables>-->
<!-- <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>-->
<!-- <maven.home>${maven.home}</maven.home>-->
<!-- </systemPropertyVariables>-->
<!-- </configuration>-->
<!-- </plugin>-->
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<!-- <plugin>-->
<!-- <artifactId>maven-failsafe-plugin</artifactId>-->
<!-- <version>${surefire-plugin.version}</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>integration-test</goal>-->
<!-- <goal>verify</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <systemPropertyVariables>-->
<!-- <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>-->
<!-- <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>-->
<!-- <maven.home>${maven.home}</maven.home>-->
<!-- </systemPropertyVariables>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# mvn package -Dquarkus.package.type=fast-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/quarkus-sureness-fast-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/quarkus-sureness-fast-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-sureness-fast-jar
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 target/quarkus-app/*.jar /deployments/
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# mvn package
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-sureness-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/quarkus-sureness-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-sureness-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# mvn package -Pnative -Dquarkus.native.container-build=true
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-sureness .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/quarkus-sureness
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
package com.usthe.sureness;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
/**
* @author tomsun28
*/
@Path("/")
public class ExampleResource {
@GET
@Path("hello")
@Produces(MediaType.TEXT_PLAIN)
public String hello(@Context Request servletRequest) {
return "hello";
}
@GET
@Path("api/v3/host")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock1(@Context Request servletRequest) {
return "get api/v3/host";
}
@GET
@Path("api/v2/host")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock2(@Context Request servletRequest) {
return "get api/v2/host";
}
@POST
@Path("api/v2/host")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock3(@Context Request servletRequest) {
return "post api/v2/host";
}
@PUT
@Path("api/v2/host")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock4(@Context Request servletRequest) {
return "put api/v2/host";
}
@DELETE
@Path("api/v2/host")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock5(@Context Request servletRequest) {
return "delete api/v2/host";
}
@DELETE
@Path("api/v2/getSource2/book")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock6(@Context Request servletRequest) {
return "get /api/v2/getSource2/book";
}
@GET
@Path("api/v1/source1")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock7(@Context Request servletRequest) {
return "get api/v1/source1";
}
@DELETE
@Path("api/v1/source1")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock8(@Context Request servletRequest) {
return "delete api/v1/source1";
}
@POST
@Path("api/v1/source1")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock9(@Context Request servletRequest) {
return "post api/v1/source1";
}
@PUT
@Path("api/v1/source1")
@Produces(MediaType.TEXT_PLAIN)
public String api1Mock0(@Context Request servletRequest) {
return "put api/v1/source1";
}
}
\ No newline at end of file
package com.usthe.sureness;
import io.quarkus.runtime.Startup;
import javax.enterprise.context.ApplicationScoped;
/**
* sureness 配置,使用默认的DefaultSurenessConfig
* @author tomsun28
* @date 23:38 2019-05-12
*/
@Startup
@ApplicationScoped
public class SurenessConfiguration {
/**
* 初始化sureness默认配置
*/
public SurenessConfiguration() {
new DefaultSurenessConfig(DefaultSurenessConfig.SUPPORT_JAX_RS);
}
}
package com.usthe.sureness;
import com.usthe.sureness.mgt.SurenessSecurityManager;
import com.usthe.sureness.processor.exception.DisabledAccountException;
import com.usthe.sureness.processor.exception.ExcessiveAttemptsException;
import com.usthe.sureness.processor.exception.ExpiredCredentialsException;
import com.usthe.sureness.processor.exception.IncorrectCredentialsException;
import com.usthe.sureness.processor.exception.ProcessorNotFoundException;
import com.usthe.sureness.processor.exception.UnauthorizedException;
import com.usthe.sureness.processor.exception.UnknownAccountException;
import com.usthe.sureness.processor.exception.UnsupportedSubjectException;
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.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
/**
* 程序的http request请求入口过滤类示例 所有request请求都需经过此类
* @author tomsun28
* @date 17:22 2019-05-12
*/
@Provider
@PreMatching
public class SurenessFilterExample implements ContainerRequestFilter, ContainerResponseFilter {
/** 日志操作 **/
private static final Logger logger = LoggerFactory.getLogger(SurenessFilterExample.class);
@Override
public void filter(ContainerRequestContext requestContext) {
try {
SubjectSum subject = SurenessSecurityManager.getInstance().checkIn(requestContext);
// 可以考虑使用SurenessContextHolder放入threadLocal中绑定
if (subject != null) {
SurenessContextHolder.bindSubject(subject);
}
} catch (ProcessorNotFoundException | UnknownAccountException | UnsupportedSubjectException e4) {
logger.debug("this request is illegal");
requestContext.abortWith(Response.status(401).entity(e4.getMessage()).build());
} catch (DisabledAccountException | ExcessiveAttemptsException e2 ) {
logger.debug("the account is disabled");
requestContext.abortWith(Response.status(401).entity(e2.getMessage()).build());
} catch (IncorrectCredentialsException | ExpiredCredentialsException e3) {
logger.debug("this account credential is incorrect or expired");
requestContext.abortWith(Response.status(401).entity(e3.getMessage()).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();
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>quarkus-sureness - 1.0-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn compile quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>Do you like Quarkus?</h2>
<p>Go give it a star on <a href="https://github.com/quarkusio/quarkus">GitHub</a>.</p>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: com.usthe.sureness</li>
<li>ArtifactId: quarkus-sureness</li>
<li>Version: 1.0-SNAPSHOT</li>
<li>Quarkus Version: 1.8.0.Final</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html" target="_blank">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started.html" target="_blank">Getting started</a></li>
<li><a href="https://quarkus.io" target="_blank">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
# Configuration file
# key = value
\ No newline at end of file
## -- sureness文本数据源 -- ##
# 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源
# 没有配置的资源也默认被认证保护,但不鉴权
# eg: /api/v2/host===post===[role2,role3,role4] 表示 /api/v2/host===post 这条资源支持 role2,role3,role4这三种角色访问
# eg: /api/v1/getSource3===get===[] 表示 /api/v1/getSource3===get 这条资源支持所有角色或无角色访问
resourceRole:
- /api/v2/host===post===[role2,role3,role4]
- /api/v2/host===get===[role2,role3,role4]
- /api/v2/host===delete===[role2,role3,role4]
- /api/v2/host===put===[role2,role3,role4]
- /api/mi/**===put===[role2,role3,role4]
- /api/v1/getSource1===get===[role1,role2]
- /api/v2/getSource2/*/*===get===[role2]
- /api/v1/source1===get===[role2]
- /api/v1/source1===post===[role1]
- /api/v1/source1===delete===[role3]
- /api/v1/source1===put===[role1,role2]
- /api/v1/source2===get===[]
# 需要被过滤保护的资源,不认证鉴权直接访问
excludedResource:
- /api/v3/host===get
- /api/v3/book===get
- /api/v1/account/auth===post
- /hello===get
# 用户账户信息
# 下面有 admin root tom三个账户
# eg: admin/admin 拥有[role1,role2]角色,加盐密码为0192023A7BBD73250516F069DF18B500
# eg: root 没有角色,密码为明文23456
account:
- appId: admin
# 如果填写了加密盐--salt,则credential为MD5(password+salt)的32位结果
# 没有盐认为不加密,credential为明文
credential: 0192023A7BBD73250516F069DF18B500
salt: 123
role: [role1,role2]
- appId: root
credential: 23456
role: [role1]
- appId: tom
credential: 32113
role: [role2]
\ No newline at end of file
package com.usthe.sureness;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class ExampleResourceTest {
@Test
public void testHelloEndpoint() {
// given()
// .when().get("/hello")
// .then()
// .statusCode(200)
// .body(is("hello"));
}
}
\ No newline at end of file
package com.usthe.sureness;
import io.quarkus.test.junit.NativeImageTest;
@NativeImageTest
public class NativeExampleResourceIT extends ExampleResourceTest {
// Execute the same tests but in native mode.
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册