You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/06/18 12:39:46 UTC
[servicecomb-fence] 01/09: Initial commit
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-fence.git
commit 7e4d7e4298078a7fc0eae88d7842483f8cdf10f9
Author: liubao <ba...@huawei.com>
AuthorDate: Fri May 24 14:43:59 2019 +0800
Initial commit
---
.gitignore | 82 +++++++++
README.md | 110 ++++++++++++
api/authentication-server/endpoint/pom.xml | 43 +++++
.../server/PasswordTokenGranter.java | 100 +++++++++++
.../server/RefreshTokenTokenGranter.java | 95 ++++++++++
.../authentication/server/TokenEndpoint.java | 54 ++++++
.../authentication/server/TokenGranter.java | 40 +++++
api/authentication-server/pom.xml | 36 ++++
api/authentication-server/service/pom.xml | 31 ++++
.../servicecomb/authentication/server/Token.java | 96 ++++++++++
.../authentication/server/TokenConst.java | 34 ++++
.../authentication/server/TokenService.java | 24 +++
api/common/endpoint/pom.xml | 38 ++++
api/common/pom.xml | 36 ++++
api/common/service/pom.xml | 56 ++++++
.../servicecomb/authentication/jwt/JWTClaims.java | 80 +++++++++
.../authentication/jwt/JWTClaimsCommon.java | 100 +++++++++++
.../servicecomb/authentication/jwt/JWTHeader.java | 42 +++++
.../servicecomb/authentication/jwt/JsonParser.java | 40 +++++
.../servicecomb/authentication/util/Constants.java | 26 +++
api/edge-service/endpoint/pom.xml | 38 ++++
api/edge-service/pom.xml | 36 ++++
api/edge-service/service/pom.xml | 42 +++++
.../authentication/edge/AuthHandler.java | 48 +++++
.../authentication/edge/AuthenticationFilter.java | 47 +++++
.../edge/CustomVertxRestDispatcher.java | 197 +++++++++++++++++++++
.../authentication/edge/InternalAccessHandler.java | 37 ++++
...servicecomb.common.rest.filter.HttpServerFilter | 18 ++
...cecomb.transport.rest.vertx.VertxHttpDispatcher | 18 ++
.../src/main/resources/config/cse.handler.xml | 23 +++
api/pom.xml | 92 ++++++++++
api/resource-server/endpoint/pom.xml | 38 ++++
api/resource-server/pom.xml | 36 ++++
api/resource-server/service/pom.xml | 42 +++++
.../resource/AccessConfiguration.java | 37 ++++
.../resource/AccessConfigurationManager.java | 36 ++++
...eptionExceptionToProducerResponseConverter.java | 39 ++++
.../resource/ResourceAuthHandler.java | 101 +++++++++++
.../resource/SimpleAuthentication.java | 77 ++++++++
....exception.ExceptionToProducerResponseConverter | 18 ++
.../src/main/resources/config/cse.handler.xml | 21 +++
samples/AuthenticationServer/pom.xml | 168 ++++++++++++++++++
.../AuthenticationConfiguration.java | 69 ++++++++
.../authentication/AuthenticationServerMain.java | 30 ++++
.../src/main/resources/log4j2.xml | 43 +++++
.../src/main/resources/microservice.yaml | 36 ++++
samples/Client/pom.xml | 151 ++++++++++++++++
.../authentication/AuthenticationClientMain.java | 30 ++++
.../authentication/AuthenticationTestCase.java | 186 +++++++++++++++++++
.../authentication/BootEventListener.java | 45 +++++
.../authentication/GateRestTemplate.java | 111 ++++++++++++
.../authentication/ITUriTemplateHandler.java | 44 +++++
.../servicecomb/authentication/TestCase.java | 22 +++
.../servicecomb/authentication/TestEndpoint.java | 52 ++++++
.../apache/servicecomb/authentication/TestMgr.java | 118 ++++++++++++
samples/Client/src/main/resources/log4j2.xml | 43 +++++
.../Client/src/main/resources/microservice.yaml | 36 ++++
samples/EdgeService/pom.xml | 111 ++++++++++++
.../authentication/gateway/ApiDispatcher.java | 69 ++++++++
.../gateway/AuthenticationConfiguration.java | 31 ++++
.../gateway/AuthenticationEdgeMain.java | 26 +++
.../authentication/gateway/EdgeSSLCustom.java | 38 ++++
.../gateway/StaticWebpageDispatcher.java | 52 ++++++
...cecomb.transport.rest.vertx.VertxHttpDispatcher | 19 ++
samples/EdgeService/src/main/resources/log4j2.xml | 43 +++++
.../src/main/resources/microservice.yaml | 71 ++++++++
.../src/main/resources/ui/css/style.css | 49 +++++
.../src/main/resources/ui/js/jquery-1.11.1.min.js | 4 +
.../EdgeService/src/main/resources/ui/js/login.js | 52 ++++++
.../EdgeService/src/main/resources/ui/js/upload.js | 63 +++++++
.../EdgeService/src/main/resources/ui/login.html | 45 +++++
.../EdgeService/src/main/resources/ui/upload.html | 61 +++++++
.../authentication/test/PatternTest.java | 36 ++++
samples/ResourceServer/pom.xml | 142 +++++++++++++++
.../resource/AuthenticationConfiguration.java | 31 ++++
.../authentication/resource/FileEndpoint.java | 45 +++++
.../authentication/resource/FileStoreService.java | 31 ++++
.../resource/HandlerAuthEndpoint.java | 46 +++++
.../resource/LocalFileStoreService.java | 64 +++++++
.../resource/MethodSecurityConfiguration.java | 36 ++++
.../resource/PreMethodAuthEndpoint.java | 50 ++++++
.../resource/ResourceServerMain.java | 30 ++++
.../ResourceServer/src/main/resources/log4j2.xml | 43 +++++
.../src/main/resources/microservice.yaml | 51 ++++++
samples/pom.xml | 92 ++++++++++
85 files changed, 4819 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..044d558
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,82 @@
+# Output Directory
+target/
+
+# C pre-compile
+*.gch
+*.pch
+
+# C compile
+*.a
+*.o
+*.ko
+*.la
+*.lo
+*.obj
+*.elf
+*.so
+*.so.*
+*.dylib
+*.exe
+*.lib
+*.dll
+*.out
+*.app
+*.hex
+
+# Debug files
+*.dSYM/
+
+# Java
+*.class
+
+# Java Package Files
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Zip Files
+*.rar
+*.zip
+*.7z
+*.tar
+*.gz
+
+# Ant
+build/
+
+# Compiled Python
+__pycache__/
+*.py[cod]
+*py.class
+
+# Eclipse
+.settings/
+.classpath
+.project
+
+# IntelliJ, based on http://devnet.jetbrains.net/docs/DOC-1186
+.idea/
+*.iml
+*.ipr
+*.iws
+
+# logs and trace
+*.log
+*.trace
+*.dat
+
+# vi swap
+*.swp
+
+# Backup Files
+*.bak
+*.old
+
+# SVN metadata
+.svn/
+
+# Mac
+.DS_Store
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c91d67e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+This project demonstrates authentications and authorizations based on JWT/OAuth2. Projct names follow OAuth2 architecture.
+
+## Implementations
+
+This project uses spring security API and mainly designed for ServiceComb architecture.
+
+* User Management
+
+ 1. UserDetailsService: load users information
+ 2. UserDetails: User information
+ 3. GrantedAuthority: authorities
+ 4. PasswordEncoder: encode or verify user password
+
+## Project
+
+* AuthenticationServer
+
+Authentication server implementation. Provides APIs to login, and query roles, etc.
+
+
+* Gateway
+
+Check if users are authenticated and dispatch HTTP request.
+
+* Client
+
+Demonstrates how client uses this project. Integration tests are provided.
+
+
+* Api
+Reusable part.
+
+* For testing
+
+Run AuthenticationServer、Gateway、Client、ResourceServer and call
+
+```
+http://localhost:9093/v1/test/start
+```
+
+see AuthenticationTestCase for details.
+
+
+本项目提供认证鉴权服务的实现,主要提供了基于角色的权限管理,和基于JWT的微服务授权模式。微服务的命名参考了OAuth2协议里面的命名方式。可以参考[OAuth2.0原理和验证流程分析](https://www.jianshu.com/p/d74ce6ca0c33)对于OAuth2认证过程的介绍,本项目的认证过程非常类似OAuth2的密码模式。
+
+项目的目标是提供一个商业可用的鉴权实现,对于项目代码实现的问题可以提交issue,本项目也接纳PR,共同完善。
+
+
+
+## 实现说明
+
+* 用户管理
+用户管理采用了org.springframework.security.core.userdetails的模型,包括:
+ 1. UserDetailsService:加载用户信息。
+ 2. UserDetails:用户信息。
+ 3. GrantedAuthority:角色信息。
+ 4. PasswordEncoder:用户密码加密和匹配。
+
+
+## 项目结构介绍
+
+* AuthenticationServer
+
+认证鉴权服务。提供用户管理、角色管理。并提供登录认证、权限查询等接口。鉴权服务及相关API是核心交付件,也是能够被重用的部分。开发者可以基于这个项目开发认证鉴权服务。
+
+* Gateway
+提供请求拦截,校验用户是否已经经过认证。一方面演示网关如何和配套鉴权服务完成开发,本项目也是自动化测试的组成部分。
+
+* Client
+Client模拟的是使用使用者。一方面演示客户端如何获取Token,本项目也是自动化测试的组成部分。
+
+* ResourceServer
+ResourceServer模拟的是业务服务。一方面演示业务服务如何进行权限配置,本项目也是自动化测试的组成部分。
+
+* Api
+认证鉴权提取的公共功能,作为复用单元。目前项目处于初始阶段,很多复用代码分散在其他项目中。
+
+
+* 测试介绍
+
+本项目实现了微服务架构的自动化测试。启动AuthenticationServer、Gateway、Client、ResourceServer后,可以提供
+
+```
+http://localhost:9093/v1/test/start
+```
+触发测试用例的执行。 所有的测试用例放到Client微服务里面, 这个微服务实现了简单的测试框架帮助书写测试用例,对测试结果进行检查等功能。
+
+测试项目同时展示了这个项目的功能,比如: AuthenticationTestCase 的测试逻辑展示了基本的认证功能,从登陆,到接口的权限检查。
+
+# TODO LIST
+1. provide TLS for authentication server & edge service
+2. grant scope for INTERNAL access & EXTERNAL access
+3. access token support: a. use access token to get optional scope or roles token. 这个可以解决角色过多的时候, token过大的一些问题
+4. 实现注销逻辑(会话管理)
+5. 支持分层的角色机制
+
+ ROLE_LEVEL1
+ / \
+ ROLE_LEVEL2 ROLE_LEVEL2
+
+ TOKEN里面只返回ROLE_LEVEL1,设置为ROLE_LEVEL2访问的操作,也可以访问。
+
+6. REFRESH_TOKEN可以用来实现申请不同SCOPE的TOKEN。
+7. 设计目标:无状态。认证服务器和资源服务器均可以多实例部署,每个实例之间不共享状态。在实现很多功能的时候,都遵循这个约束。包括通过refresh token获取新的access token的时候。遵循这个约束,意味着请求需要同时传递refresh token和access token。
+8, 重新设计TOKEN(代码重构、支持会话管理),支持OpenID Connect。
+
+OAUTH的不好的地方:TOKEN在有效期内,容易被利用,无法注销;TOKEN过期后,必须重新认证,和用户是否在一直操作无关,体验不好,虽然可以通过refresh_token获取新的token提升体验,但是refresh_token有效期如果设置的太长,会降低安全性。Token在有效期内,如果修改了权限等信息,无法及时感知,需要重新登录。
+OAUTH的好的地方:TOKEN签发、认证都可以由微服务实例独自完成,不需要共用的数据存储,比如数据库、Redis等,效率更高,弹性扩容。
+
+
diff --git a/api/authentication-server/endpoint/pom.xml b/api/authentication-server/endpoint/pom.xml
new file mode 100644
index 0000000..a653462
--- /dev/null
+++ b/api/authentication-server/endpoint/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-server-api-endpoint</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java
new file mode 100644
index 0000000..7d16268
--- /dev/null
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.servicecomb.authentication.jwt.JWTClaims;
+import org.apache.servicecomb.authentication.jwt.JsonParser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.Signer;
+import org.springframework.stereotype.Component;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+@Component(value = "passwordTokenGranter")
+public class PasswordTokenGranter implements TokenGranter {
+ @Autowired
+ @Qualifier("authUserDetailsService")
+ private UserDetailsService userDetailsService;
+
+ @Autowired
+ @Qualifier("authPasswordEncoder")
+ private PasswordEncoder passwordEncoder;
+
+ @Autowired
+ @Qualifier("authSigner")
+ private Signer signer;
+
+ @Override
+ public Token grant(Map<String, String> parameters) {
+ String username = parameters.get(TokenConst.PARAM_USERNAME);
+ String password = parameters.get(TokenConst.PARAM_PASSWORD);
+
+ UserDetails userDetails = userDetailsService.loadUserByUsername(username);
+ if (passwordEncoder.matches(password, userDetails.getPassword())) {
+ JWTClaims claims = new JWTClaims();
+ if (userDetails.getAuthorities() != null) {
+ userDetails.getAuthorities().forEach(authority -> claims.addAuthority(authority.getAuthority()));
+ }
+ claims.setJti(UUID.randomUUID().toString());
+ claims.setIat(System.currentTimeMillis());
+ claims.setExp(5 * 60);
+
+ String content = JsonParser.unparse(claims);
+ Jwt accessToken = JwtHelper.encode(content, signer);
+
+ Token token = new Token();
+ token.setScope(claims.getScope());
+ token.setExpires_in(10 * 60);
+ token.setToken_type("bearer");
+ token.setAccess_token(accessToken.getEncoded());
+
+ JWTClaims accessTokenClaims = new JWTClaims();
+ accessTokenClaims.setJti(UUID.randomUUID().toString());
+ accessTokenClaims.setIat(System.currentTimeMillis());
+ accessTokenClaims.setExp(60 * 60);
+ Jwt refreshToken = JwtHelper.encode(JsonParser.unparse(claims), signer);
+ token.setRefresh_token(refreshToken.getEncoded());
+
+ return token;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String grantType() {
+ return TokenConst.GRANT_TYPE_PASSWORD;
+ }
+
+ @Override
+ public boolean enabled() {
+ return DynamicPropertyFactory.getInstance()
+ .getBooleanProperty("servicecomb.authentication.granter.password.enabled", true)
+ .get();
+ }
+
+}
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java
new file mode 100644
index 0000000..ffbf9c5
--- /dev/null
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.Map;
+
+import org.apache.servicecomb.authentication.jwt.JWTClaims;
+import org.apache.servicecomb.authentication.jwt.JsonParser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.Signer;
+import org.springframework.security.jwt.crypto.sign.SignerVerifier;
+import org.springframework.stereotype.Component;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+@Component(value = "fefreshTokenTokenGranter")
+public class RefreshTokenTokenGranter implements TokenGranter {
+ @Autowired
+ @Qualifier("authSignerVerifier")
+ private SignerVerifier signerVerifier;
+
+ @Autowired
+ @Qualifier("authSigner")
+ private Signer signer;
+
+ @Override
+ public boolean enabled() {
+ return DynamicPropertyFactory.getInstance()
+ .getBooleanProperty("servicecomb.authentication.granter.refreshToken.enabled", true)
+ .get();
+ }
+
+ @Override
+ public String grantType() {
+ return TokenConst.GRANT_TYPE_REFRESH_TOKEN;
+ }
+
+ @Override
+ public Token grant(Map<String, String> parameters) {
+ String refreshToken = parameters.get(TokenConst.PARAM_REFRESH_TOKEN);
+ String accessToken = parameters.get(TokenConst.PARAM_ACCESS_TOKEN);
+
+ // verify refresh tokens
+ Jwt jwt = JwtHelper.decode(refreshToken);
+ JWTClaims claims;
+ try {
+ jwt.verifySignature(signerVerifier);
+ claims = JsonParser.parse(jwt.getClaims(), JWTClaims.class);
+ // TODO: verify claims.
+ } catch (Exception e) {
+ return null;
+ }
+
+ // verify access tokens
+ jwt = JwtHelper.decode(accessToken);
+ claims = null;
+ try {
+ jwt.verifySignature(signerVerifier);
+ claims = JsonParser.parse(jwt.getClaims(), JWTClaims.class);
+ // TODO: verify claims.
+ } catch (Exception e) {
+ return null;
+ }
+
+ claims.setIat(System.currentTimeMillis());
+ String content = JsonParser.unparse(claims);
+ Jwt newAccessToken = JwtHelper.encode(content, signer);
+
+ Token token = new Token();
+ token.setScope(claims.getScope());
+ token.setExpires_in(10 * 60);
+ token.setToken_type("bearer");
+ token.setAccess_token(newAccessToken.getEncoded());
+ return token;
+ }
+
+}
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java
new file mode 100644
index 0000000..775d332
--- /dev/null
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RestSchema(schemaId = "TokenEndpoint")
+@RequestMapping(path = "/v1/oauth/token")
+public class TokenEndpoint implements TokenService {
+ @Autowired
+ private List<TokenGranter> granters;
+
+ @Override
+ @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED)
+ public Token getAccessToken(@RequestBody Map<String, String> parameters) {
+ String grantType = parameters.get(TokenConst.PARAM_GRANT_TYPE);
+
+ for (TokenGranter granter : granters) {
+ if (granter.enabled()) {
+ Token token = granter.grant(grantType, parameters);
+ if (token != null) {
+ return token;
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenGranter.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenGranter.java
new file mode 100644
index 0000000..9ba0861
--- /dev/null
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenGranter.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.Map;
+
+/**
+ * Token granter is used to grant access tokens.
+ * @author Administrator
+ *
+ */
+public interface TokenGranter {
+ boolean enabled();
+
+ String grantType();
+
+ default Token grant(String grantType, Map<String, String> parameters) {
+ if (grantType().equals(grantType)) {
+ return grant(parameters);
+ }
+ return null;
+ }
+
+ Token grant(Map<String, String> parameters);
+}
diff --git a/api/authentication-server/pom.xml b/api/authentication-server/pom.xml
new file mode 100644
index 0000000..946a2fb
--- /dev/null
+++ b/api/authentication-server/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-server-api</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>service</module>
+ <module>endpoint</module>
+ </modules>
+</project>
\ No newline at end of file
diff --git a/api/authentication-server/service/pom.xml b/api/authentication-server/service/pom.xml
new file mode 100644
index 0000000..4433ff6
--- /dev/null
+++ b/api/authentication-server/service/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-server-api-service</artifactId>
+ <packaging>jar</packaging>
+
+</project>
diff --git a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/Token.java b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/Token.java
new file mode 100644
index 0000000..8758bd1
--- /dev/null
+++ b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/Token.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.Map;
+import java.util.Set;
+
+public class Token {
+ // Naming conventions https://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-00#section-3.1
+ private String token_type;
+
+ private String access_token;
+
+ private String refresh_token;
+
+ private int expires_in;
+
+ private Set<String> scope;
+
+ // JWT id
+ private String jti;
+
+ private Map<String, Object> additionalInformation;
+
+ public String getToken_type() {
+ return token_type;
+ }
+
+ public void setToken_type(String token_type) {
+ this.token_type = token_type;
+ }
+
+ public String getAccess_token() {
+ return access_token;
+ }
+
+ public void setAccess_token(String access_token) {
+ this.access_token = access_token;
+ }
+
+ public String getRefresh_token() {
+ return refresh_token;
+ }
+
+ public void setRefresh_token(String refresh_token) {
+ this.refresh_token = refresh_token;
+ }
+
+ public int getExpires_in() {
+ return expires_in;
+ }
+
+ public void setExpires_in(int expires_in) {
+ this.expires_in = expires_in;
+ }
+
+ public Set<String> getScope() {
+ return scope;
+ }
+
+ public void setScope(Set<String> scope) {
+ this.scope = scope;
+ }
+
+ public String getJti() {
+ return jti;
+ }
+
+ public void setJti(String jti) {
+ this.jti = jti;
+ }
+
+ public Map<String, Object> getAdditionalInformation() {
+ return additionalInformation;
+ }
+
+ public void setAdditionalInformation(Map<String, Object> additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+}
diff --git a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenConst.java b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenConst.java
new file mode 100644
index 0000000..915a515
--- /dev/null
+++ b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenConst.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+public class TokenConst {
+ public static final String PARAM_GRANT_TYPE = "grant_type";
+
+ public static final String PARAM_USERNAME = "username";
+
+ public static final String PARAM_PASSWORD = "password";
+
+ public static final String PARAM_REFRESH_TOKEN = "refresh_token";
+
+ public static final String PARAM_ACCESS_TOKEN = "access_token";
+
+ public static final String GRANT_TYPE_PASSWORD = "password";
+
+ public static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
+}
diff --git a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java
new file mode 100644
index 0000000..b0cea22
--- /dev/null
+++ b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.server;
+
+import java.util.Map;
+
+public interface TokenService {
+ Token getAccessToken(Map<String, String> parameters);
+}
diff --git a/api/common/endpoint/pom.xml b/api/common/endpoint/pom.xml
new file mode 100644
index 0000000..de2736a
--- /dev/null
+++ b/api/common/endpoint/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/common/pom.xml b/api/common/pom.xml
new file mode 100644
index 0000000..b4a9fbc
--- /dev/null
+++ b/api/common/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-common-api</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>service</module>
+ <module>endpoint</module>
+ </modules>
+</project>
\ No newline at end of file
diff --git a/api/common/service/pom.xml b/api/common/service/pom.xml
new file mode 100644
index 0000000..66c5f90
--- /dev/null
+++ b/api/common/service/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-common-api-service</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.security.oauth</groupId>
+ <artifactId>spring-security-oauth2</artifactId>
+ <version>2.3.2.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-jwt</artifactId>
+ <version>1.0.7.RELEASE</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.security.oauth</groupId>
+ <artifactId>spring-security-oauth2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-jwt</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaims.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaims.java
new file mode 100644
index 0000000..c62affc
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaims.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.jwt;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class JWTClaims extends JWTClaimsCommon {
+ protected Set<String> authorities;
+
+ protected Map<String, Object> additionalInformation;
+
+ /**
+ * The scope of the access token as described by <a
+ * href="http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.3">Section 3.3</a>
+ */
+ protected Set<String> scope;
+
+ public Set<String> getAuthorities() {
+ return authorities;
+ }
+
+ public void setAuthorities(Set<String> authorities) {
+ this.authorities = authorities;
+ }
+
+ public Map<String, Object> getAdditionalInformation() {
+ return additionalInformation;
+ }
+
+ public void setAdditionalInformation(Map<String, Object> additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+ public Set<String> getScope() {
+ return scope;
+ }
+
+ public void setScope(Set<String> scope) {
+ this.scope = scope;
+ }
+
+ public void addAdditionalInformation(String key, Object value) {
+ if (this.additionalInformation == null) {
+ this.additionalInformation = new HashMap<>();
+ }
+ this.additionalInformation.put(key, value);
+ }
+
+ public void addScope(String operation) {
+ if (this.scope == null) {
+ this.scope = new HashSet<>();
+ }
+ this.scope.add(operation);
+ }
+
+ public void addAuthority(String authority) {
+ if (this.authorities == null) {
+ this.authorities = new HashSet<>();
+ }
+ this.authorities.add(authority);
+ }
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaimsCommon.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaimsCommon.java
new file mode 100644
index 0000000..54e26a5
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTClaimsCommon.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.jwt;
+
+public class JWTClaimsCommon {
+ // see: https://tools.ietf.org/html/rfc7519
+ // (Issuer) Claim
+ protected String iss;
+
+ // (Subject) Claim
+ protected String sub;
+
+ // (Audience) Claim
+ protected String aud;
+
+ // (Expiration Time) Claim
+ protected long exp;
+
+ // (Not Before) Claim
+ protected long nbf;
+
+ // (Issued At) Claim
+ protected long iat;
+
+ // (JWT ID) Claim
+ protected String jti;
+
+ public String getIss() {
+ return iss;
+ }
+
+ public void setIss(String iss) {
+ this.iss = iss;
+ }
+
+ public String getSub() {
+ return sub;
+ }
+
+ public void setSub(String sub) {
+ this.sub = sub;
+ }
+
+ public String getAud() {
+ return aud;
+ }
+
+ public void setAud(String aud) {
+ this.aud = aud;
+ }
+
+ public long getExp() {
+ return exp;
+ }
+
+ public void setExp(long exp) {
+ this.exp = exp;
+ }
+
+ public long getNbf() {
+ return nbf;
+ }
+
+ public void setNbf(long nbf) {
+ this.nbf = nbf;
+ }
+
+ public long getIat() {
+ return iat;
+ }
+
+ public void setIat(long iat) {
+ this.iat = iat;
+ }
+
+ public String getJti() {
+ return jti;
+ }
+
+ public void setJti(String jti) {
+ this.jti = jti;
+ }
+
+
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTHeader.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTHeader.java
new file mode 100644
index 0000000..2cc797c
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JWTHeader.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.jwt;
+
+public class JWTHeader {
+ private String typ;
+
+ private String alg;
+
+ public String getTyp() {
+ return typ;
+ }
+
+ public void setTyp(String typ) {
+ this.typ = typ;
+ }
+
+ public String getAlg() {
+ return alg;
+ }
+
+ public void setAlg(String alg) {
+ this.alg = alg;
+ }
+
+
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JsonParser.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JsonParser.java
new file mode 100644
index 0000000..2a4bcd1
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/jwt/JsonParser.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.jwt;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JsonParser {
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ public static <T> T parse(String json, Class<T> clazz) {
+ try {
+ return MAPPER.readValue(json, clazz);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Cannot parse json", e);
+ }
+ }
+
+ public static <T> String unparse(T obj) {
+ try {
+ return MAPPER.writeValueAsString(obj);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Cannot unparse json", e);
+ }
+ }
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java
new file mode 100644
index 0000000..96333aa
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.util;
+
+public final class Constants {
+ public static final String HTTP_HEADER_AUTHORIZATION = "Authorization";
+
+ public static final String CONTEXT_HEADER_AUTHORIZATION = "Authorization";
+
+ public static final String CONTEXT_HEADER_CLAIMS = "Claims";
+}
diff --git a/api/edge-service/endpoint/pom.xml b/api/edge-service/endpoint/pom.xml
new file mode 100644
index 0000000..66c4a87
--- /dev/null
+++ b/api/edge-service/endpoint/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-edge-api-endpoint</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-edge-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/edge-service/pom.xml b/api/edge-service/pom.xml
new file mode 100644
index 0000000..24d393b
--- /dev/null
+++ b/api/edge-service/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-edge-api</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>service</module>
+ <module>endpoint</module>
+ </modules>
+</project>
\ No newline at end of file
diff --git a/api/edge-service/service/pom.xml b/api/edge-service/service/pom.xml
new file mode 100644
index 0000000..8d86c00
--- /dev/null
+++ b/api/edge-service/service/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-edge-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-edge-api-service</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java
new file mode 100644
index 0000000..40ef32d
--- /dev/null
+++ b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.edge;
+
+import org.apache.servicecomb.authentication.util.Constants;
+import org.apache.servicecomb.core.Handler;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.InvalidSignatureException;
+
+
+public class AuthHandler implements Handler {
+ @Override
+ public void handle(Invocation invocation, AsyncResponse asyncResponse) throws Exception {
+ String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION);
+ if (token == null) {
+ asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+ return;
+ }
+ Jwt jwt = JwtHelper.decode(token);
+ try {
+ jwt.verifySignature(BeanUtils.getBean("authSignerVerifier"));
+ } catch (InvalidSignatureException e) {
+ asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+ return;
+ }
+ invocation.next(asyncResponse);
+ }
+}
diff --git a/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java
new file mode 100644
index 0000000..46ba288
--- /dev/null
+++ b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.edge;
+
+import org.apache.servicecomb.authentication.util.Constants;
+import org.apache.servicecomb.common.rest.filter.HttpServerFilter;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+public class AuthenticationFilter implements HttpServerFilter {
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+
+ @Override
+ public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
+ String authentication = requestEx.getHeader(Constants.HTTP_HEADER_AUTHORIZATION);
+ if (authentication != null) {
+ String[] tokens = authentication.split(" ");
+ if (tokens.length == 2) {
+ if (tokens[0].equals("Bearer")) {
+ invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION, tokens[1]);
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/CustomVertxRestDispatcher.java b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/CustomVertxRestDispatcher.java
new file mode 100644
index 0000000..521b71c
--- /dev/null
+++ b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/CustomVertxRestDispatcher.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.edge;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.Response.Status.Family;
+
+import org.apache.servicecomb.common.rest.AbstractRestInvocation;
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.VertxRestInvocation;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.core.Transport;
+import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
+import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
+import org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;
+import org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.apache.servicecomb.transport.rest.vertx.AbstractVertxHttpDispatcher;
+import org.apache.servicecomb.transport.rest.vertx.VertxRestDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException;
+import io.vertx.core.json.JsonObject;
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.handler.CookieHandler;
+
+// copied from org.apache.servicecomb.transport.rest.vertx.VertxRestDispatcher 1.2.0
+// TODO: using 1.2.2+ to make it simpler
+public class CustomVertxRestDispatcher extends AbstractVertxHttpDispatcher {
+ private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestDispatcher.class);
+
+ private Transport transport;
+
+ @Override
+ public int getOrder() {
+ return 10001;
+ }
+
+ @Override
+ public boolean enabled() {
+ return true;
+ }
+
+ @Override
+ public void init(Router router) {
+ String regex = "(/v1/log|/inspector|/v1/auth)/(.*)";
+ router.routeWithRegex(regex).handler(CookieHandler.create());
+ router.routeWithRegex(regex).handler(createBodyHandler());
+ router.routeWithRegex(regex).failureHandler(this::failureHandler).handler(this::onRequest);
+ }
+
+ private void failureHandler(RoutingContext context) {
+ LOGGER.error("http server failed.", context.failure());
+
+ AbstractRestInvocation restProducerInvocation = context.get(RestConst.REST_PRODUCER_INVOCATION);
+ Throwable e = context.failure();
+ if (ErrorDataDecoderException.class.isInstance(e)) {
+ Throwable cause = e.getCause();
+ if (InvocationException.class.isInstance(cause)) {
+ e = cause;
+ }
+ }
+
+ // only when unexpected exception happens, it will run into here.
+ // the connection should be closed.
+ handleFailureAndClose(context, restProducerInvocation, e);
+ }
+
+ /**
+ * Try to find out the failure information and send it in response.
+ */
+ private void handleFailureAndClose(RoutingContext context, AbstractRestInvocation restProducerInvocation,
+ Throwable e) {
+ if (null != restProducerInvocation) {
+ // if there is restProducerInvocation, let it send exception in response. The exception is allowed to be null.
+ sendFailResponseByInvocation(context, restProducerInvocation, e);
+ return;
+ }
+
+ if (null != e) {
+ // if there exists exception, try to send this exception by RoutingContext
+ sendExceptionByRoutingContext(context, e);
+ return;
+ }
+
+ // if there is no exception, the response is determined by status code.
+ sendFailureRespDeterminedByStatus(context);
+ }
+
+ /**
+ * Try to determine response by status code, and send response.
+ */
+ private void sendFailureRespDeterminedByStatus(RoutingContext context) {
+ Family statusFamily = Family.familyOf(context.statusCode());
+ if (Family.CLIENT_ERROR.equals(statusFamily) || Family.SERVER_ERROR.equals(statusFamily) || Family.OTHER
+ .equals(statusFamily)) {
+ context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)
+ .setStatusCode(context.statusCode()).end();
+ } else {
+ // it seems the status code is not set properly
+ context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)
+ .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode())
+ .setStatusMessage(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())
+ .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()));
+ }
+ context.response().close();
+ }
+
+ /**
+ * Use routingContext to send failure information in throwable.
+ */
+ private void sendExceptionByRoutingContext(RoutingContext context, Throwable e) {
+ if (InvocationException.class.isInstance(e)) {
+ InvocationException invocationException = (InvocationException) e;
+ context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)
+ .setStatusCode(invocationException.getStatusCode()).setStatusMessage(invocationException.getReasonPhrase())
+ .end(wrapResponseBody(invocationException.getReasonPhrase()));
+ } else {
+ context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)
+ .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode()).end(wrapResponseBody(e.getMessage()));
+ }
+ context.response().close();
+ }
+
+ /**
+ * Consumer will treat the response body as json by default, so it's necessary to wrap response body as Json string
+ * to avoid deserialization error.
+ *
+ * @param message response body
+ * @return response body wrapped as Json string
+ */
+ String wrapResponseBody(String message) {
+ if (isValidJson(message)) {
+ return message;
+ }
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.put("message", message);
+
+ return jsonObject.toString();
+ }
+
+ /**
+ * Check if the message is a valid Json string.
+ * @param message the message to be checked.
+ * @return true if message is a valid Json string, otherwise false.
+ */
+ private boolean isValidJson(String message) {
+ try {
+ new JsonObject(message);
+ } catch (Exception ignored) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Use restProducerInvocation to send failure message. The throwable is allowed to be null.
+ */
+ private void sendFailResponseByInvocation(RoutingContext context, AbstractRestInvocation restProducerInvocation,
+ Throwable e) {
+ restProducerInvocation.sendFailResponse(e);
+ context.response().close();
+ }
+
+ private void onRequest(RoutingContext context) {
+ if (transport == null) {
+ transport = CseContext.getInstance().getTransportManager().findTransport(Const.RESTFUL);
+ }
+ HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);
+ HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());
+
+ VertxRestInvocation vertxRestInvocation = new VertxRestInvocation();
+ context.put(RestConst.REST_PRODUCER_INVOCATION, vertxRestInvocation);
+ vertxRestInvocation.invoke(transport, requestEx, responseEx, httpServerFilters);
+ }
+}
diff --git a/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/InternalAccessHandler.java b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/InternalAccessHandler.java
new file mode 100644
index 0000000..d01620f
--- /dev/null
+++ b/api/edge-service/service/src/main/java/org/apache/servicecomb/authentication/edge/InternalAccessHandler.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.edge;
+
+import org.apache.servicecomb.core.Handler;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+
+public class InternalAccessHandler implements Handler {
+
+ @Override
+ public void handle(Invocation invocation, AsyncResponse asyncReponse) throws Exception {
+ if (invocation.getOperationMeta().getSwaggerOperation().getTags() != null
+ && invocation.getOperationMeta().getSwaggerOperation().getTags().contains("INTERNAL")) {
+ asyncReponse.consumerFail(new InvocationException(403, "", "not allowed"));
+ return;
+ }
+ invocation.next(asyncReponse);
+ }
+
+}
diff --git a/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.filter.HttpServerFilter b/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.filter.HttpServerFilter
new file mode 100644
index 0000000..75e40b9
--- /dev/null
+++ b/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.filter.HttpServerFilter
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.authentication.edge.AuthenticationFilter
\ No newline at end of file
diff --git a/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher b/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
new file mode 100644
index 0000000..32c1583
--- /dev/null
+++ b/api/edge-service/service/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# org.apache.servicecomb.authentication.edge.CustomVertxRestDispatcher
\ No newline at end of file
diff --git a/api/edge-service/service/src/main/resources/config/cse.handler.xml b/api/edge-service/service/src/main/resources/config/cse.handler.xml
new file mode 100644
index 0000000..43a5258
--- /dev/null
+++ b/api/edge-service/service/src/main/resources/config/cse.handler.xml
@@ -0,0 +1,23 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<config>
+ <handler id="auth"
+ class="org.apache.servicecomb.authentication.edge.AuthHandler" />
+ <handler id="internalAccess"
+ class="org.apache.servicecomb.authentication.edge.InternalAccessHandler" />
+</config>
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..92c7f27
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <modules>
+ <module>common</module>
+ <module>authentication-server</module>
+ <module>resource-server</module>
+ <module>edge-service</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file
diff --git a/api/resource-server/endpoint/pom.xml b/api/resource-server/endpoint/pom.xml
new file mode 100644
index 0000000..dc5d549
--- /dev/null
+++ b/api/resource-server/endpoint/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-resource-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-resource-api-endpoint</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-resource-api-service</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/resource-server/pom.xml b/api/resource-server/pom.xml
new file mode 100644
index 0000000..7c3f228
--- /dev/null
+++ b/api/resource-server/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-resource-api</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>service</module>
+ <module>endpoint</module>
+ </modules>
+</project>
\ No newline at end of file
diff --git a/api/resource-server/service/pom.xml b/api/resource-server/service/pom.xml
new file mode 100644
index 0000000..cf045ce
--- /dev/null
+++ b/api/resource-server/service/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-resource-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-resource-api-service</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfiguration.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfiguration.java
new file mode 100644
index 0000000..8167612
--- /dev/null
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfiguration.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.config.inject.InjectProperties;
+import org.apache.servicecomb.config.inject.InjectProperty;
+
+@InjectProperties(prefix = "servicecomb.authencation.access")
+public class AccessConfiguration {
+ @InjectProperty(keys = {
+ "needAuth.${schemaId}.${operationId}",
+ "needAuth.${schemaId}",
+ "needAuth"},
+ defaultValue = "true")
+ public boolean needAuth;
+
+ @InjectProperty(keys = {
+ "roles.${schemaId}.${operationId}",
+ "roles.${schemaId}",
+ "roles"})
+ public String roles;
+}
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfigurationManager.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfigurationManager.java
new file mode 100644
index 0000000..c6ea891
--- /dev/null
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessConfigurationManager.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import java.util.Map;
+
+import org.apache.servicecomb.config.inject.ConfigObjectFactory;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+
+public class AccessConfigurationManager {
+ private static final Map<String, AccessConfiguration> CONFIGURATIONS = new ConcurrentHashMapEx<>();
+
+ private static final ConfigObjectFactory FACTORY = new ConfigObjectFactory();
+
+ public static AccessConfiguration getAccessConfiguration(Invocation invocation) {
+ return CONFIGURATIONS.computeIfAbsent(invocation.getOperationMeta().getSchemaQualifiedName(), key -> {
+ return FACTORY.create(AccessConfiguration.class, "schemaId", invocation.getSchemaId(), "operationId", invocation.getOperationName());
+ });
+ }
+}
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java
new file mode 100644
index 0000000..c2decce
--- /dev/null
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.security.access.AccessDeniedException;
+
+public class AccessDeniedExceptionExceptionToProducerResponseConverter
+ implements ExceptionToProducerResponseConverter<AccessDeniedException> {
+
+ @Override
+ public Class<AccessDeniedException> getExceptionClass() {
+ return AccessDeniedException.class;
+ }
+
+ @Override
+ public Response convert(SwaggerInvocation swaggerInvocation, AccessDeniedException e) {
+ return Response.failResp(new InvocationException(403, "forbidden", "not authenticated"));
+ }
+
+}
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
new file mode 100644
index 0000000..1d8e32b
--- /dev/null
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.authentication.jwt.JWTClaims;
+import org.apache.servicecomb.authentication.jwt.JsonParser;
+import org.apache.servicecomb.authentication.util.Constants;
+import org.apache.servicecomb.core.Handler;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextImpl;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+
+public class ResourceAuthHandler implements Handler {
+
+ @Override
+ public void handle(Invocation invocation, AsyncResponse asyncResponse) throws Exception {
+ AccessConfiguration config = AccessConfigurationManager.getAccessConfiguration(invocation);
+
+ // by pass authentication
+ if (!config.needAuth) {
+ invocation.next(asyncResponse);
+ return;
+ }
+
+ String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION);
+ if (token == null) {
+ asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+ return;
+ }
+ // verify tokens
+ Jwt jwt = JwtHelper.decode(token);
+ JWTClaims claims;
+ try {
+ jwt.verifySignature(BeanUtils.getBean("authSignerVerifier"));
+ claims = JsonParser.parse(jwt.getClaims(), JWTClaims.class);
+ // TODO: verify claims.
+ } catch (Exception e) {
+ asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+ return;
+ }
+
+ // check roles
+ if (!StringUtils.isEmpty(config.roles)) {
+ String[] roles = config.roles.split(",");
+ if (roles.length > 0) {
+ boolean valid = false;
+ Set<String> authorities = claims.getAuthorities();
+ for (String role : roles) {
+ if (authorities.contains(role)) {
+ valid = true;
+ break;
+ }
+ }
+ if (!valid) {
+ asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+ return;
+ }
+ }
+ }
+
+ // pre method authentiation
+ Set<GrantedAuthority> grantedAuthorities = new HashSet<>(claims.getAuthorities().size());
+ claims.getAuthorities().forEach(v -> grantedAuthorities.add(new SimpleGrantedAuthority(v)));
+ SecurityContext sc = new SecurityContextImpl();
+ Authentication authentication = new SimpleAuthentication(true, grantedAuthorities);
+ sc.setAuthentication(authentication);
+ SecurityContextHolder.setContext(sc);
+
+ // next
+ invocation.next(asyncResponse);
+ }
+
+}
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java
new file mode 100644
index 0000000..a23404c
--- /dev/null
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import java.util.Collection;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+
+public class SimpleAuthentication implements Authentication {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6077733273349249822L;
+
+ private boolean authenticated;
+
+ private Collection<? extends GrantedAuthority> authorities;
+
+ public SimpleAuthentication(boolean authenticated, Collection<? extends GrantedAuthority> authorities) {
+ this.authenticated = authenticated;
+ this.authorities = authorities;
+ }
+
+
+ @Override
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<? extends GrantedAuthority> getAuthorities() {
+ return this.authorities;
+ }
+
+ @Override
+ public Object getCredentials() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getDetails() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAuthenticated() {
+ return this.authenticated;
+ }
+
+ @Override
+ public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/api/resource-server/service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter b/api/resource-server/service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter
new file mode 100644
index 0000000..e6ad477
--- /dev/null
+++ b/api/resource-server/service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.authentication.resource.AccessDeniedExceptionExceptionToProducerResponseConverter
\ No newline at end of file
diff --git a/api/resource-server/service/src/main/resources/config/cse.handler.xml b/api/resource-server/service/src/main/resources/config/cse.handler.xml
new file mode 100644
index 0000000..0efe6d1
--- /dev/null
+++ b/api/resource-server/service/src/main/resources/config/cse.handler.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<config>
+ <handler id="resource-auth-provider"
+ class="org.apache.servicecomb.authentication.resource.ResourceAuthHandler" />
+</config>
diff --git a/samples/AuthenticationServer/pom.xml b/samples/AuthenticationServer/pom.xml
new file mode 100644
index 0000000..488d06d
--- /dev/null
+++ b/samples/AuthenticationServer/pom.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+
+<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>
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-samples</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>authentication-server</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ <version>3.4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.46</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security.oauth</groupId>
+ <artifactId>spring-security-oauth2</artifactId>
+ <version>2.3.2.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-jwt</artifactId>
+ <version>1.0.7.RELEASE</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.security.oauth</groupId>
+ <artifactId>spring-security-oauth2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-jwt</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-endpoint</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file
diff --git a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java
new file mode 100644
index 0000000..2fdbd4c
--- /dev/null
+++ b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import java.util.Arrays;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
+import org.springframework.security.jwt.crypto.sign.MacSigner;
+import org.springframework.security.jwt.crypto.sign.Signer;
+import org.springframework.security.jwt.crypto.sign.SignerVerifier;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+
+@Configuration
+public class AuthenticationConfiguration {
+ @Autowired
+ @Qualifier("authPasswordEncoder")
+ private PasswordEncoder passwordEncoder;
+
+ @Bean(name = "authPasswordEncoder")
+ public PasswordEncoder authPasswordEncoder() {
+ return new Pbkdf2PasswordEncoder();
+ }
+
+ @Bean(name = "authSigner")
+ public Signer authSigner() {
+ return authSignerVerifier();
+ }
+
+ @Bean(name = "authSignerVerifier")
+ public SignerVerifier authSignerVerifier() {
+ return new MacSigner("Please change this key.");
+ }
+
+ @Bean(name = "authUserDetailsService")
+ public UserDetailsService authUserDetailsService() {
+ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
+ UserDetails uAdmin = new User("admin", passwordEncoder.encode("changeMyPassword"),
+ Arrays.asList(new SimpleGrantedAuthority("ADMIN")));
+ UserDetails uGuest = new User("guest", passwordEncoder.encode("changeMyPassword"),
+ Arrays.asList(new SimpleGrantedAuthority("GUEST")));
+ manager.createUser(uAdmin);
+ manager.createUser(uGuest);
+ return manager;
+ }
+}
diff --git a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java
new file mode 100644
index 0000000..35b239d
--- /dev/null
+++ b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+
+public class AuthenticationServerMain {
+ public static void main(String[] args) {
+ try {
+ BeanUtils.init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/samples/AuthenticationServer/src/main/resources/log4j2.xml b/samples/AuthenticationServer/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..3c70391
--- /dev/null
+++ b/samples/AuthenticationServer/src/main/resources/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--this is sample configuration, please modify as your wish-->
+
+<configuration>
+ <Properties>
+ <Property name="log_path">./user/log/</Property>
+ </Properties>
+
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ </Console>
+ <RollingFile name="DailyRollingFile" fileName="${log_path}/output.log"
+ filePattern="${log_path}/zcrTest%d{yyyy-MM-dd}.log">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ <TimeBasedTriggeringPolicy interval="1"/>
+ <SizeBasedTriggeringPolicy size="10 MB"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ <AppenderRef ref="DailyRollingFile"/>
+ </Root>
+ </Loggers>
+</configuration>
\ No newline at end of file
diff --git a/samples/AuthenticationServer/src/main/resources/microservice.yaml b/samples/AuthenticationServer/src/main/resources/microservice.yaml
new file mode 100644
index 0000000..dfedc0f
--- /dev/null
+++ b/samples/AuthenticationServer/src/main/resources/microservice.yaml
@@ -0,0 +1,36 @@
+#
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# override common configurations in common module
+servicecomb-config-order: 100
+
+APPLICATION_ID: authentication-application
+service_description:
+ version: 0.0.1
+ name: authentication-server
+ environment: development
+
+servicecomb:
+ service:
+ registry:
+ address: http://localhost:30100
+ instance:
+ watch: false
+
+ rest:
+ address: 0.0.0.0:9091
diff --git a/samples/Client/pom.xml b/samples/Client/pom.xml
new file mode 100644
index 0000000..d879756
--- /dev/null
+++ b/samples/Client/pom.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+
+<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>
+
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-samples</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>client</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ <version>3.4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.46</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-common-api-endpoint</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java
new file mode 100644
index 0000000..ce9c356
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+
+public class AuthenticationClientMain {
+ public static void main(String[] args) {
+ try {
+ BeanUtils.init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
new file mode 100644
index 0000000..13bfaba
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import org.apache.servicecomb.authentication.jwt.JWTClaims;
+import org.apache.servicecomb.authentication.jwt.JsonParser;
+import org.apache.servicecomb.authentication.server.Token;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.HttpClientErrorException;
+
+@Component
+public class AuthenticationTestCase implements TestCase {
+ @Override
+ public void run() {
+ testHanlderAuth();
+ testMethodAuth();
+ }
+
+
+ private void testHanlderAuth() {
+ // get token
+ MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
+ map.add("grant_type", "password");
+ map.add("username", "admin");
+ map.add("password", "changeMyPassword");
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+ Token token =
+ BootEventListener.authenticationServerTokenEndpoint.postForObject("/",
+ new HttpEntity<>(map, headers),
+ Token.class);
+ TestMgr.check("bearer", token.getToken_type());
+ TestMgr.check(true, token.getAccess_token().length() > 10);
+
+ // get resources
+ headers = new HttpHeaders();
+ headers.add("Authorization", "Bearer " + token.getAccess_token());
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ String name;
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/everyoneSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/adminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/guestOrAdminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = null;
+ try {
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/guestSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ } catch (HttpClientErrorException e) {
+ TestMgr.check(403, e.getStatusCode().value());
+ }
+ TestMgr.check(null, name);
+
+ // refresh token
+ // get token
+ map = new LinkedMultiValueMap<>();
+ map.add("grant_type", "refresh_token");
+ map.add("refresh_token", token.getRefresh_token());
+ map.add("access_token", token.getAccess_token());
+ headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+ Token tokenNew =
+ BootEventListener.authenticationServerTokenEndpoint.postForObject("/",
+ new HttpEntity<>(map, headers),
+ Token.class);
+ TestMgr.check(token.getToken_type(), tokenNew.getToken_type());
+
+ JWTClaims claims = JsonParser.parse(JwtHelper.decode(token.getAccess_token()).getClaims(), JWTClaims.class);
+ JWTClaims newClaims = JsonParser.parse(JwtHelper.decode(tokenNew.getAccess_token()).getClaims(), JWTClaims.class);
+ TestMgr.check(claims.getJti(), newClaims.getJti());
+ TestMgr.check(claims.getIat() < newClaims.getIat(), true);
+
+ // get resources
+ headers = new HttpHeaders();
+ headers.add("Authorization", "Bearer " + tokenNew.getAccess_token());
+ headers.setContentType(MediaType.APPLICATION_JSON);
+
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/everyoneSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/adminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/guestOrAdminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = null;
+ try {
+ name = BootEventListener.resouceServerHandlerAuthEndpoint.postForObject("/guestSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ } catch (HttpClientErrorException e) {
+ TestMgr.check(403, e.getStatusCode().value());
+ }
+ TestMgr.check(null, name);
+ }
+
+
+ private void testMethodAuth() {
+ // get token
+ MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
+ map.add("grant_type", "password");
+ map.add("username", "admin");
+ map.add("password", "changeMyPassword");
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+ Token token =
+ BootEventListener.authenticationServerTokenEndpoint.postForObject("/",
+ new HttpEntity<>(map, headers),
+ Token.class);
+ TestMgr.check("bearer", token.getToken_type());
+ TestMgr.check(true, token.getAccess_token().length() > 10);
+ TestMgr.check(true, token.getRefresh_token().length() > 10);
+
+ // get resources
+ headers = new HttpHeaders();
+ headers.add("Authorization", "Bearer " + token.getAccess_token());
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ String name;
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/everyoneSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/adminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/guestOrAdminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = null;
+ try {
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/guestSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ } catch (HttpClientErrorException e) {
+ TestMgr.check(403, e.getStatusCode().value());
+ }
+ TestMgr.check(null, name);
+ }
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java
new file mode 100644
index 0000000..08d1bb3
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import org.apache.servicecomb.core.BootListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class BootEventListener implements BootListener {
+ public static GateRestTemplate authenticationServerTokenEndpoint;
+ public static GateRestTemplate gateEndpoint;
+ public static GateRestTemplate resouceServerHandlerAuthEndpoint;
+ public static GateRestTemplate resouceServerMethodAuthEndpoint;
+
+ @Override
+ public void onBootEvent(BootEvent event) {
+ if (EventType.AFTER_REGISTRY.equals(event.getEventType())) {
+ authenticationServerTokenEndpoint =
+ GateRestTemplate.createEdgeRestTemplate("edge-service", "authentication-server", "TokenEndpoint").init();
+ gateEndpoint =
+ GateRestTemplate.createEdgeRestTemplate("edge-service", null, null).init();
+ resouceServerHandlerAuthEndpoint =
+ GateRestTemplate.createEdgeRestTemplate("edge-service", "resource-server", "HandlerAuthEndpoint").init();
+ resouceServerMethodAuthEndpoint =
+ GateRestTemplate.createEdgeRestTemplate("edge-service", "resource-server", "PreMethodAuthEndpoint").init();
+ }
+
+ }
+
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/GateRestTemplate.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/GateRestTemplate.java
new file mode 100644
index 0000000..7a6709f
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/GateRestTemplate.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.authentication;
+
+import java.util.Arrays;
+
+import org.apache.servicecomb.core.definition.MicroserviceVersionMeta;
+import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.apache.servicecomb.serviceregistry.RegistryUtils;
+import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import org.apache.servicecomb.serviceregistry.consumer.MicroserviceVersionRule;
+import org.apache.servicecomb.serviceregistry.definition.DefinitionConst;
+import org.springframework.http.converter.FormHttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+public class GateRestTemplate extends RestTemplate {
+ private final String gateName;
+
+ private final String schemaId;
+
+ private final String producerName;
+
+ private String urlPrefix;
+
+ public static GateRestTemplate createEdgeRestTemplate(String gateName, String producerName, String schemaId) {
+ return new GateRestTemplate(gateName, producerName, schemaId);
+ }
+
+
+ public GateRestTemplate(String gateName, String producerName, String schemaId) {
+ this.gateName = gateName;
+ this.producerName = producerName;
+ this.schemaId = schemaId;
+ }
+
+ public GateRestTemplate init() {
+ urlPrefix = getUrlPrefix(gateName, producerName, schemaId);
+
+ setUriTemplateHandler(new ITUriTemplateHandler(urlPrefix));
+
+ setMessageConverters(Arrays.asList(
+ new MappingJackson2HttpMessageConverter(),
+ new StringHttpMessageConverter(),
+ new FormHttpMessageConverter()));
+
+ return this;
+ }
+
+ public String getUrlPrefix() {
+ return urlPrefix;
+ }
+
+ private String getUrlPrefix(String gateName, String producerName, String schemaId) {
+ MicroserviceVersionRule microserviceVersionRule = RegistryUtils.getServiceRegistry()
+ .getAppManager()
+ .getOrCreateMicroserviceVersionRule(RegistryUtils.getAppId(),
+ gateName,
+ DefinitionConst.VERSION_RULE_ALL);
+ MicroserviceInstance microserviceInstance = microserviceVersionRule.getInstances()
+ .values()
+ .stream()
+ .findFirst()
+ .get();
+ URIEndpointObject edgeAddress = new URIEndpointObject(microserviceInstance.getEndpoints().get(0));
+
+ String urlSchema = "http";
+ if (edgeAddress.isSslEnabled()) {
+ urlSchema = "https";
+ }
+
+ if(producerName == null) {
+ return String
+ .format("%s://%s:%d",
+ urlSchema,
+ edgeAddress.getHostOrIp(),
+ edgeAddress.getPort());
+ }
+
+ microserviceVersionRule = RegistryUtils.getServiceRegistry()
+ .getAppManager()
+ .getOrCreateMicroserviceVersionRule(RegistryUtils.getAppId(),
+ producerName,
+ DefinitionConst.VERSION_RULE_ALL);
+ MicroserviceVersionMeta microserviceVersionMeta = microserviceVersionRule.getLatestMicroserviceVersion();
+ SchemaMeta schemaMeta = microserviceVersionMeta.getMicroserviceMeta().ensureFindSchemaMeta(schemaId);
+ return String
+ .format("%s://%s:%d/api/%s%s",
+ urlSchema,
+ edgeAddress.getHostOrIp(),
+ edgeAddress.getPort(),
+ producerName,
+ schemaMeta.getSwagger().getBasePath());
+ }
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/ITUriTemplateHandler.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/ITUriTemplateHandler.java
new file mode 100644
index 0000000..8308599
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/ITUriTemplateHandler.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.authentication;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.springframework.web.util.DefaultUriTemplateHandler;
+
+public class ITUriTemplateHandler extends DefaultUriTemplateHandler {
+ private String urlPrefix;
+
+ public ITUriTemplateHandler(String urlPrefix) {
+ this.urlPrefix = urlPrefix;
+ }
+
+ @Override
+ protected URI expandInternal(String uriTemplate, Object... uriVariables) {
+ return super.expandInternal(changeUrl(uriTemplate), uriVariables);
+ }
+
+ @Override
+ protected URI expandInternal(String uriTemplate, Map<String, ?> uriVariables) {
+ return super.expandInternal(changeUrl(uriTemplate), uriVariables);
+ }
+
+ private String changeUrl(String uriTemplate) {
+ return urlPrefix + uriTemplate;
+ }
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestCase.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestCase.java
new file mode 100644
index 0000000..1c511d2
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestCase.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+public interface TestCase {
+ void run();
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
new file mode 100644
index 0000000..19b0af1
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import java.util.List;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RestSchema(schemaId = "TestEndpoint")
+@RequestMapping(path = "/v1/test")
+public class TestEndpoint {
+ @Autowired
+ private List<TestCase> tests;
+
+ @GetMapping(path = "/start")
+ public String start() {
+ tests.forEach(test -> test.run());
+
+ List<Throwable> errors = TestMgr.errors();
+ if (TestMgr.isSuccess()) {
+ return TestMgr.successMessage();
+ } else {
+ TestMgr.summary();
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("Failed count : " + errors.size());
+ sb.append("\n");
+ errors.forEach(t -> sb.append(t.getMessage() + "\n"));
+
+ TestMgr.reset();
+ return sb.toString();
+ }
+ }
+}
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
new file mode 100644
index 0000000..030bb4c
--- /dev/null
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+public class TestMgr {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TestMgr.class);
+
+ private static final List<Throwable> errorList = new ArrayList<>();
+
+ private static String msg = "";
+
+ private static AtomicLong checksCount = new AtomicLong();
+
+ public static void setMsg(String msg) {
+ TestMgr.msg = msg;
+ }
+
+ public static void setMsg(String microserviceName, String transport) {
+ TestMgr.msg = String.format("microservice=%s, transport=%s", microserviceName, transport);
+ }
+
+ public static void check(Object expect, Object real) {
+ check(expect, real, null);
+ }
+
+ public static void check(Object expect, Object real, Throwable error) {
+ checksCount.incrementAndGet();
+ if (expect == real) {
+ return;
+ }
+
+ String strExpect = String.valueOf(expect);
+ String strReal = String.valueOf(real);
+
+ if (!strExpect.equals(strReal)) {
+ Error newError = new Error(msg + " | Expect " + strExpect + ", but " + strReal);
+ if (error != null) {
+ newError.setStackTrace(error.getStackTrace());
+ }
+ errorList.add(newError);
+ }
+ }
+
+ public static void checkNotEmpty(String real) {
+ if (StringUtils.isEmpty(real)) {
+ errorList.add(new Error(msg + " | unexpected null result, method is " + getCaller()));
+ }
+ }
+
+ public static void failed(String desc, Throwable e) {
+ Error error = new Error(msg + " | " + desc + ", method is " + getCaller());
+ if (e != null) {
+ error.setStackTrace(error.getStackTrace());
+ }
+ errorList.add(error);
+ }
+
+ public static boolean isSuccess() {
+ return errorList.isEmpty();
+ }
+
+ public static void summary() {
+ if (errorList.isEmpty()) {
+ LOGGER.info("............. test finished ............");
+ return;
+ }
+
+ LOGGER.info("............. test not finished ............");
+ for (Throwable e : errorList) {
+ LOGGER.info("", e);
+ }
+ }
+
+ public static void reset() {
+ errorList.clear();
+ checksCount.set(0);
+ }
+
+ public static String successMessage() {
+ return "Success. Checkes = " + checksCount.get();
+ }
+
+ public static List<Throwable> errors() {
+ return errorList;
+ }
+
+ private static String getCaller() {
+ StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+ if (stackTrace.length < 3) {
+ return null;
+ }
+ StackTraceElement stackTraceElement = stackTrace[3];
+ return stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
+ }
+}
diff --git a/samples/Client/src/main/resources/log4j2.xml b/samples/Client/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..3c70391
--- /dev/null
+++ b/samples/Client/src/main/resources/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--this is sample configuration, please modify as your wish-->
+
+<configuration>
+ <Properties>
+ <Property name="log_path">./user/log/</Property>
+ </Properties>
+
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ </Console>
+ <RollingFile name="DailyRollingFile" fileName="${log_path}/output.log"
+ filePattern="${log_path}/zcrTest%d{yyyy-MM-dd}.log">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ <TimeBasedTriggeringPolicy interval="1"/>
+ <SizeBasedTriggeringPolicy size="10 MB"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ <AppenderRef ref="DailyRollingFile"/>
+ </Root>
+ </Loggers>
+</configuration>
\ No newline at end of file
diff --git a/samples/Client/src/main/resources/microservice.yaml b/samples/Client/src/main/resources/microservice.yaml
new file mode 100644
index 0000000..f19ca7b
--- /dev/null
+++ b/samples/Client/src/main/resources/microservice.yaml
@@ -0,0 +1,36 @@
+#
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# override common configurations in common module
+servicecomb-config-order: 100
+
+APPLICATION_ID: authentication-application
+service_description:
+ version: 0.0.1
+ name: authentication-client
+ environment: development
+
+servicecomb:
+ service:
+ registry:
+ address: http://localhost:30100
+ instance:
+ watch: false
+
+ rest:
+ address: 0.0.0.0:9093
diff --git a/samples/EdgeService/pom.xml b/samples/EdgeService/pom.xml
new file mode 100644
index 0000000..cb50f95
--- /dev/null
+++ b/samples/EdgeService/pom.xml
@@ -0,0 +1,111 @@
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+
+<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>
+
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-samples</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>edge-service</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-edge-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-edge-api-endpoint</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-server-api-service</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>edge-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/ApiDispatcher.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/ApiDispatcher.java
new file mode 100644
index 0000000..7642268
--- /dev/null
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/ApiDispatcher.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.gateway;
+
+import java.util.Map;
+
+import org.apache.servicecomb.edge.core.AbstractEdgeDispatcher;
+import org.apache.servicecomb.edge.core.EdgeInvocation;
+
+import io.vertx.ext.web.Cookie;
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.handler.CookieHandler;
+
+//TODO: using 1.2.2+ to make it simpler
+public class ApiDispatcher extends AbstractEdgeDispatcher {
+ @Override
+ public int getOrder() {
+ return 10002;
+ }
+
+ @Override
+ public void init(Router router) {
+ String regex = "/api/([^\\/]+)/(.*)";
+ router.routeWithRegex(regex).handler(CookieHandler.create());
+ router.routeWithRegex(regex).handler(createBodyHandler());
+ router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest);
+ }
+
+ protected void onRequest(RoutingContext context) {
+ Map<String, String> pathParams = context.pathParams();
+ String microserviceName = pathParams.get("param0");
+ String path = "/" + pathParams.get("param1");
+
+ EdgeInvocation invoker = new EdgeInvocation() {
+ // Authentication. Notice: adding context must after setContext or will override by network
+ protected void setContext() throws Exception {
+ super.setContext();
+ // get session id from header and cookie for debug reasons
+ String sessionId = context.request().getHeader("session-id");
+ if (sessionId != null) {
+ this.invocation.addContext("session-id", sessionId);
+ } else {
+ Cookie sessionCookie = context.getCookie("session-id");
+ if (sessionCookie != null) {
+ this.invocation.addContext("session-id", sessionCookie.getValue());
+ }
+ }
+ }
+ };
+ invoker.init(microserviceName, context, path, httpServerFilters);
+ invoker.edgeInvoke();
+ }
+}
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java
new file mode 100644
index 0000000..1e913fb
--- /dev/null
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.gateway;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.jwt.crypto.sign.MacSigner;
+import org.springframework.security.jwt.crypto.sign.SignerVerifier;
+
+@Configuration
+public class AuthenticationConfiguration {
+ @Bean(name = "authSignerVerifier")
+ public SignerVerifier authSignerVerifier() {
+ return new MacSigner("Please change this key.");
+ }
+}
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationEdgeMain.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationEdgeMain.java
new file mode 100644
index 0000000..b040342
--- /dev/null
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationEdgeMain.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.gateway;
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+
+public class AuthenticationEdgeMain {
+ public static void main(String[] args) throws Exception {
+ BeanUtils.init();
+ }
+}
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/EdgeSSLCustom.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/EdgeSSLCustom.java
new file mode 100644
index 0000000..0fb1268
--- /dev/null
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/EdgeSSLCustom.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.gateway;
+
+import java.io.File;
+
+import org.apache.servicecomb.foundation.ssl.SSLCustom;
+
+public class EdgeSSLCustom extends SSLCustom {
+
+ @Override
+ public char[] decode(char[] plain) {
+ return plain;
+ }
+
+ @Override
+ public String getFullPath(String name) {
+ String fullName = System.getProperty("user.dir") + File.separator + name;
+ System.out.println(fullName);
+ return (new File(fullName)).getAbsolutePath();
+ }
+
+}
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/StaticWebpageDispatcher.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/StaticWebpageDispatcher.java
new file mode 100644
index 0000000..555ddc4
--- /dev/null
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/StaticWebpageDispatcher.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.gateway;
+
+import org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.handler.StaticHandler;
+
+public class StaticWebpageDispatcher implements VertxHttpDispatcher {
+ private static final Logger LOGGER = LoggerFactory.getLogger(StaticWebpageDispatcher.class);
+
+ private static final String WEB_ROOT = DynamicPropertyFactory.getInstance()
+ .getStringProperty("gateway.webroot", "/var/static")
+ .get();
+
+ @Override
+ public int getOrder() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public void init(Router router) {
+ String regex = "/ui/(.*)";
+ StaticHandler webpageHandler = StaticHandler.create();
+ webpageHandler.setWebRoot(WEB_ROOT);
+ LOGGER.info("server static web page for WEB_ROOT={}", WEB_ROOT);
+ router.routeWithRegex(regex).failureHandler((context) -> {
+ LOGGER.error("", context.failure());
+ }).handler(webpageHandler);
+ }
+
+}
diff --git a/samples/EdgeService/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher b/samples/EdgeService/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
new file mode 100644
index 0000000..cf4f35b
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.authentication.gateway.ApiDispatcher
+org.apache.servicecomb.authentication.gateway.StaticWebpageDispatcher
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/log4j2.xml b/samples/EdgeService/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..b51f28e
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--this is sample configuration, please modify as your wish-->
+
+<configuration>
+ <Properties>
+ <Property name="log_path">./gateway/log/</Property>
+ </Properties>
+
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ </Console>
+ <RollingFile name="DailyRollingFile" fileName="${log_path}/output.log"
+ filePattern="${log_path}/zcrTest%d{yyyy-MM-dd}.log">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ <TimeBasedTriggeringPolicy interval="1"/>
+ <SizeBasedTriggeringPolicy size="10 MB"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ <AppenderRef ref="DailyRollingFile"/>
+ </Root>
+ </Loggers>
+</configuration>
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/microservice.yaml b/samples/EdgeService/src/main/resources/microservice.yaml
new file mode 100644
index 0000000..7531d52
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/microservice.yaml
@@ -0,0 +1,71 @@
+#
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# override common configurations in common module
+servicecomb-config-order: 100
+
+APPLICATION_ID: authentication-application
+service_description:
+ version: 0.0.1
+ name: edge-service
+ environment: development
+
+servicecomb:
+ service:
+ registry:
+ address: http://localhost:30100
+ instance:
+ watch: false
+
+ rest:
+ address: 0.0.0.0:9090
+
+ handler:
+ chain:
+ Consumer:
+ default: internalAccess,auth,qps-flowcontrol-consumer,loadbalance
+ service:
+ authentication-server: internalAccess,qps-flowcontrol-consumer,loadbalance
+ authentication-client: internalAccess,qps-flowcontrol-consumer,loadbalance
+
+ uploads:
+ directory: tmp_for_upload_gateway
+
+ samples:
+ logdir: D:\code\servicecomb-samples\porter_lightweight\gateway-service
+
+ inspector:
+ enabled: false
+
+ executors:
+ Provider:
+ log: servicecomb.samples.executor.groupThreadPool
+ inspector: servicecomb.samples.executor.groupThreadPool
+
+# disable all servicecomb difault dispatchers, all of them are overriden
+ http:
+ dispatcher:
+ edge:
+ default:
+ enabled: false # overriden by ApiDispatcher
+ rest:
+ eanbled: false # overriden by CustomVertxRestDispatcher
+
+# StaticWebpageDispatcher checking file exists is async, and will mark request status to ended, and VertxRestDispatcher read
+# body will print exception.
+#gateway.webroot: /code/servicecomb-samples/porter_lightweight/gateway-service/src/main/resources
diff --git a/samples/EdgeService/src/main/resources/ui/css/style.css b/samples/EdgeService/src/main/resources/ui/css/style.css
new file mode 100644
index 0000000..5731863
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/css/style.css
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.error {
+ font-family:verdana;
+ color:red;
+}
+
+.header {
+ background-color:black;
+ color:white;
+ text-align:center;
+ padding:5px;
+}
+
+.nav {
+ line-height:30px;
+ background-color:#eeeeee;
+ height:300px;
+ width:100px;
+ float:left;
+ padding:5px;
+}
+
+.section {
+ text-align:center;
+ padding:5px;
+}
+
+.footer {
+ color:red;
+ clear:both;
+ text-align:center;
+ padding:25px;
+}
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/ui/js/jquery-1.11.1.min.js b/samples/EdgeService/src/main/resources/ui/js/jquery-1.11.1.min.js
new file mode 100644
index 0000000..ab28a24
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/js/jquery-1.11.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b [...]
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&& [...]
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.prop [...]
diff --git a/samples/EdgeService/src/main/resources/ui/js/login.js b/samples/EdgeService/src/main/resources/ui/js/login.js
new file mode 100644
index 0000000..c7e7c8e
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/js/login.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function loginAction() {
+ var username = document.getElementById("username").value;
+ var password = document.getElementById("paasword").value;
+ var formData = {};
+ formData.userName = username;
+ formData.password = password;
+
+ $.ajax({
+ type: 'POST',
+ url: "/api/user-service/v1/user/login",
+ data: formData,
+ success: function (data) {
+ console.log(data);
+ setCookie("session-id", data.sessiondId, 1);
+ window.location = "/ui/upload.html";
+ },
+ error: function(data) {
+ console.log(data);
+ var error = document.getElementById("error");
+ error.textContent="Login failed";
+ error.hidden=false;
+ },
+ async: true
+ });
+}
+
+function setCookie(name,value,days) {
+ var expires = "";
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime() + (days*24*60*60*1000));
+ expires = "; expires=" + date.toUTCString();
+ }
+ document.cookie = name + "=" + (value || "") + expires + "; path=/";
+}
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/ui/js/upload.js b/samples/EdgeService/src/main/resources/ui/js/upload.js
new file mode 100644
index 0000000..7d66555
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/js/upload.js
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function uploadAction() {
+ var formData = new FormData(document.getElementById("upload_form"));
+
+ $.ajax({
+ type: 'POST',
+ url: "/api/file-service/upload",
+ data: formData,
+ processData:false,
+ contentType:false,
+ success: function (data) {
+ console.log(data);
+ var error = document.getElementById("error");
+ error.textContent="Upload Successfully";
+ error.hidden=false;
+ },
+ error: function(data) {
+ console.log(data);
+ var error = document.getElementById("error");
+ error.textContent="Upload failed";
+ error.hidden=false;
+ },
+ async: true
+ });
+}
+
+function deleteAction() {
+ var fileID = document.getElementById("fileID").value;
+ $.ajax({
+ type: 'DELETE',
+ url: "/api/file-service/delete?" + $.param({ id: fileID }),
+ data: {},
+ success: function (data) {
+ console.log(data);
+ var error = document.getElementById("error");
+ error.textContent="Delete successfully";
+ error.hidden=false;
+ },
+ error: function(data) {
+ console.log(data);
+ var error = document.getElementById("error");
+ error.textContent="Delete failed";
+ error.hidden=false;
+ },
+ async: true
+ });
+}
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/ui/login.html b/samples/EdgeService/src/main/resources/ui/login.html
new file mode 100644
index 0000000..c8b45fb
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/login.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<html>
+
+ <head>
+ <title>PORTER</title>
+ <link href="css/style.css" rel="stylesheet" type="text/css" media="all" />
+ <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
+ <script type="text/javascript" src="js/login.js"></script>
+ </head>
+
+ <body>
+ <div class="header">
+ <h2>Login</h2>
+ </div>
+ <div class="section">
+ <form method="POST" enctype="multipart/form-data">
+ <input id="username" type="text" placeholder="Username" required="true"/>
+ <input id="paasword" type="password" placeholder="Password" required="true"/>
+ <input type="button" value="Login" onclick="loginAction()">
+ </form>
+ </div>
+ <div class="footer">
+ <p id="error" hidden="true" class="error"/>
+ </div>
+ </body>
+
+</html>
\ No newline at end of file
diff --git a/samples/EdgeService/src/main/resources/ui/upload.html b/samples/EdgeService/src/main/resources/ui/upload.html
new file mode 100644
index 0000000..bd5eeff
--- /dev/null
+++ b/samples/EdgeService/src/main/resources/ui/upload.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<html>
+
+ <head>
+ <title>PORTER</title>
+ <link href="css/style.css" rel="stylesheet" type="text/css" media="all" />
+ <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
+ <script type="text/javascript" src="js/upload.js"></script>
+ </head>
+
+ <body>
+ <div class="header">
+ <h2>Upload</h2>
+ </div>
+ <div class="section">
+ <form id="upload_form" method="POST">
+ <p>
+ File Name: <input type="file" name="fileName"/>
+ </p>
+ <p>
+ <input type="button" value="Upload" onclick="uploadAction()">
+ </p>
+ </form>
+ </div>
+
+ <div class="header">
+ <h2>Delete file</h2>
+ </div>
+ <div class="section">
+ <form id="delete_form" method="DELETE">
+ <p>
+ File ID: <input id="fileID" type="text"/>
+ </p>
+ <p>
+ <input type="button" value="Delete" onclick="deleteAction()">
+ </p>
+ </form>
+ </div>
+ <div class="footer">
+ <p id="error" hidden="true" class="error"/>
+ </div>
+ </body>
+
+</html>
\ No newline at end of file
diff --git a/samples/EdgeService/test/org/apache/servicecomb/authentication/test/PatternTest.java b/samples/EdgeService/test/org/apache/servicecomb/authentication/test/PatternTest.java
new file mode 100644
index 0000000..e4b2151
--- /dev/null
+++ b/samples/EdgeService/test/org/apache/servicecomb/authentication/test/PatternTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.test;
+
+import java.util.regex.Pattern;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class PatternTest {
+ @Test
+ public void testPattern() {
+ String regex = "(/v1/log|/inspector|/v1/auth)/(.*)";
+ Pattern p = Pattern.compile(regex);
+ Assert.assertTrue(p.matcher("/v1/log/login").matches());
+ Assert.assertTrue(p.matcher("/inspector/login").matches());
+ Assert.assertTrue(p.matcher("/v1/auth/login").matches());
+ Assert.assertTrue(!p.matcher("/api/v1/auth/login").matches());
+ }
+}
diff --git a/samples/ResourceServer/pom.xml b/samples/ResourceServer/pom.xml
new file mode 100644
index 0000000..df24f7a
--- /dev/null
+++ b/samples/ResourceServer/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with ~
+ this work for additional information regarding copyright ownership. ~ The
+ ASF licenses this file to You under the Apache License, Version 2.0 ~ (the
+ "License"); you may not use this file except in compliance with ~ the License.
+ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ ~ Unless required by applicable law or agreed to in writing, software ~
+ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the
+ License for the specific language governing permissions and ~ limitations
+ under the License. -->
+
+<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>
+
+
+ <parent>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-samples</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>resource-server</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-resource-api-endpoint</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ <version>3.4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.46</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-resource-api-endpoint</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
new file mode 100644
index 0000000..712030d
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.jwt.crypto.sign.MacSigner;
+import org.springframework.security.jwt.crypto.sign.SignerVerifier;
+
+@Configuration
+public class AuthenticationConfiguration {
+ @Bean(name = "authSignerVerifier")
+ public SignerVerifier authSignerVerifier() {
+ return new MacSigner("Please change this key.");
+ }
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileEndpoint.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileEndpoint.java
new file mode 100644
index 0000000..4b6a5b6
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileEndpoint.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestSchema(schemaId = "FileEndpoint")
+@RequestMapping(path = "/v1/file")
+public class FileEndpoint {
+ @Autowired
+ private FileStoreService fileService;
+
+ @PostMapping(path = "/upload", produces = MediaType.TEXT_PLAIN_VALUE)
+ public String uploadFile(@RequestPart(name = "fileName") MultipartFile file) {
+ return fileService.uploadFile(file);
+ }
+
+ @DeleteMapping(path = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
+ public boolean deleteFile(@RequestParam(name = "id") String id) {
+ return fileService.deleteFile(id);
+ }
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileStoreService.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileStoreService.java
new file mode 100644
index 0000000..ed03665
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/FileStoreService.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * file storage service, can implement using file system, OBS, etc.
+ */
+public interface FileStoreService {
+
+ public String uploadFile(MultipartFile file);
+
+ public boolean deleteFile(String id);
+
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/HandlerAuthEndpoint.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/HandlerAuthEndpoint.java
new file mode 100644
index 0000000..347db46
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/HandlerAuthEndpoint.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RestSchema(schemaId = "HandlerAuthEndpoint")
+@RequestMapping(path = "/v1/auth/handler")
+public class HandlerAuthEndpoint {
+ @PostMapping(path = "/adminSayHello")
+ public String adminSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/guestSayHello")
+ public String guestSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/guestOrAdminSayHello")
+ public String guestOrAdminSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/everyoneSayHello")
+ public String everyoneSayHello(String name) {
+ return name;
+ }
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/LocalFileStoreService.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/LocalFileStoreService.java
new file mode 100644
index 0000000..d487144
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/LocalFileStoreService.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.UUID;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Simple file storage implementation.
+ * Caution: file check and other security constraints not implemented.
+ */
+@Component
+public class LocalFileStoreService implements FileStoreService {
+ // maxmum BUFFER_SIZE * BUFFER_NUM
+ private static final int BUFFER_SIZE = 10240;
+
+ private static final File BASE_FILE = new File(".");
+
+ @Override
+ public String uploadFile(MultipartFile file) {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ String fileId = UUID.randomUUID().toString();
+
+ File outFile = new File(BASE_FILE, fileId);
+ int len;
+ try (InputStream is = file.getInputStream(); OutputStream os = new FileOutputStream(outFile)) {
+ while ((len = is.read(buffer)) != -1) {
+ os.write(buffer, 0, len);
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ return fileId;
+ }
+
+ @Override
+ public boolean deleteFile(String id) {
+ File outFile = new File(BASE_FILE, id);
+ return outFile.delete();
+ }
+
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java
new file mode 100644
index 0000000..58df6a9
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
+import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
+
+@Configuration
+@EnableGlobalMethodSecurity(
+ prePostEnabled = true)
+public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
+ @Override
+ protected MethodSecurityExpressionHandler createExpressionHandler() {
+ DefaultMethodSecurityExpressionHandler h = (DefaultMethodSecurityExpressionHandler) super.createExpressionHandler();
+ h.setDefaultRolePrefix("");
+ return h;
+ }
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java
new file mode 100644
index 0000000..668f774
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RestSchema(schemaId = "PreMethodAuthEndpoint")
+@RequestMapping(path = "/v1/auth/method")
+public class PreMethodAuthEndpoint {
+ @PostMapping(path = "/adminSayHello")
+ @PreAuthorize("hasRole('ADMIN')")
+ public String adminSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/guestSayHello")
+ @PreAuthorize("hasRole('USER')")
+ public String guestSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/guestOrAdminSayHello")
+ @PreAuthorize("hasAnyRole('USER','ADMIN')")
+ public String guestOrAdminSayHello(String name) {
+ return name;
+ }
+
+ @PostMapping(path = "/everyoneSayHello")
+ public String everyoneSayHello(String name) {
+ return name;
+ }
+}
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceServerMain.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceServerMain.java
new file mode 100644
index 0000000..1964390
--- /dev/null
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceServerMain.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+
+public class ResourceServerMain {
+ public static void main(String[] args) {
+ try {
+ BeanUtils.init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/samples/ResourceServer/src/main/resources/log4j2.xml b/samples/ResourceServer/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..3c70391
--- /dev/null
+++ b/samples/ResourceServer/src/main/resources/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--this is sample configuration, please modify as your wish-->
+
+<configuration>
+ <Properties>
+ <Property name="log_path">./user/log/</Property>
+ </Properties>
+
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ </Console>
+ <RollingFile name="DailyRollingFile" fileName="${log_path}/output.log"
+ filePattern="${log_path}/zcrTest%d{yyyy-MM-dd}.log">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ <TimeBasedTriggeringPolicy interval="1"/>
+ <SizeBasedTriggeringPolicy size="10 MB"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ <AppenderRef ref="DailyRollingFile"/>
+ </Root>
+ </Loggers>
+</configuration>
\ No newline at end of file
diff --git a/samples/ResourceServer/src/main/resources/microservice.yaml b/samples/ResourceServer/src/main/resources/microservice.yaml
new file mode 100644
index 0000000..69b0ffc
--- /dev/null
+++ b/samples/ResourceServer/src/main/resources/microservice.yaml
@@ -0,0 +1,51 @@
+#
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# override common configurations in common module
+servicecomb-config-order: 100
+
+APPLICATION_ID: authentication-application
+service_description:
+ version: 0.0.1
+ name: resource-server
+ environment: development
+
+servicecomb:
+ service:
+ registry:
+ address: http://localhost:30100
+ instance:
+ watch: false
+
+ rest:
+ address: 0.0.0.0:9092
+
+ authencation:
+ access:
+ needAuth: true
+ roles:
+ HandlerAuthEndpoint:
+ adminSayHello: ADMIN
+ guestSayHello: GUEST
+ guestOrAdminSayHello: ADMIN,GUEST
+ # everyoneSayHello: all can
+
+ handler:
+ chain:
+ Provider:
+ default: qps-flowcontrol-provider,resource-auth-provider
\ No newline at end of file
diff --git a/samples/pom.xml b/samples/pom.xml
new file mode 100644
index 0000000..9bf4cac
--- /dev/null
+++ b/samples/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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>org.apache.servicecomb.authentication</groupId>
+ <artifactId>authentication-samples</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <modules>
+ <module>AuthenticationServer</module>
+ <module>ResourceServer</module>
+ <module>EdgeService</module>
+ <module>Client</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>1.2.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>solution-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>inspector</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <mainClass>${main.class}</mainClass>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
\ No newline at end of file