-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #52 from xezzon/feature/issue-49
第三方应用调用与校验
- Loading branch information
Showing
50 changed files
with
1,176 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* | ||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns="http://maven.apache.org/POM/4.0.0" | ||
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> | ||
<artifactId>geom-open-sdk</artifactId> | ||
<description>构造与geom开放平台交互的HTTP接口的SDK</description> | ||
<name>${project.groupId}:${project.artifactId}</name> | ||
|
||
<packaging>jar</packaging> | ||
<parent> | ||
<groupId>io.github.xezzon</groupId> | ||
<artifactId>geom</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<properties> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<artifactId>feign-core</artifactId> | ||
<groupId>io.github.openfeign</groupId> | ||
</dependency> | ||
<dependency> | ||
<artifactId>bcpkix-jdk18on</artifactId> | ||
<groupId>org.bouncycastle</groupId> | ||
<version>1.78.1</version> | ||
</dependency> | ||
<dependency> | ||
<artifactId>feign-jackson</artifactId> | ||
<groupId>io.github.openfeign</groupId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<artifactId>spring-boot-starter-webflux</artifactId> | ||
<groupId>org.springframework.boot</groupId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<artifactId>spring-boot-starter-test</artifactId> | ||
<groupId>org.springframework.boot</groupId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
15 changes: 15 additions & 0 deletions
15
geom-open-sdk/src/main/java/io/github/xezzon/geom/GeomOpenConstant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.github.xezzon.geom; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public class GeomOpenConstant { | ||
|
||
public static final String DIGEST_ALGORITHM = "HmacSHA256"; | ||
public static final String ACCESS_KEY_HEADER = "X-Access-Key"; | ||
public static final String TIMESTAMP_HEADER = "X-Timestamp"; | ||
public static final String SIGNATURE_HEADER = "X-Signature"; | ||
|
||
private GeomOpenConstant() { | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
geom-open-sdk/src/main/java/io/github/xezzon/geom/GeomOpenException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package io.github.xezzon.geom; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public class GeomOpenException extends RuntimeException { | ||
|
||
public GeomOpenException(Throwable cause) { | ||
super(cause); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
geom-open-sdk/src/main/java/io/github/xezzon/geom/GeomOpenRequestBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import feign.Feign; | ||
import feign.RequestInterceptor; | ||
import feign.RequestTemplate; | ||
import java.security.Security; | ||
import java.time.Instant; | ||
import java.util.Base64; | ||
import javax.crypto.Mac; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public class GeomOpenRequestBuilder { | ||
|
||
static { | ||
Security.addProvider(new BouncyCastleProvider()); | ||
} | ||
|
||
/** | ||
* 应用标识 | ||
*/ | ||
private final String accessKey; | ||
/** | ||
* 应用密钥(AES) | ||
*/ | ||
private final byte[] secretKey; | ||
|
||
public GeomOpenRequestBuilder(String accessKey, String secretKey) { | ||
this.accessKey = accessKey; | ||
this.secretKey = Base64.getDecoder().decode(secretKey); | ||
} | ||
|
||
public Feign.Builder builder() { | ||
return Feign.builder() | ||
.requestInterceptor(new GeomOpenRequestInterceptor()); | ||
} | ||
|
||
class GeomOpenRequestInterceptor implements RequestInterceptor { | ||
|
||
@Override | ||
public void apply(RequestTemplate requestTemplate) { | ||
// 应用标识 | ||
requestTemplate.header(GeomOpenConstant.ACCESS_KEY_HEADER, accessKey); | ||
// 时间戳 | ||
long timestamp = Instant.now().toEpochMilli(); | ||
requestTemplate.header(GeomOpenConstant.TIMESTAMP_HEADER, String.valueOf(timestamp)); | ||
// 摘要 | ||
byte[] body = requestTemplate.body(); | ||
try { | ||
Mac mac = Mac.getInstance(GeomOpenConstant.DIGEST_ALGORITHM); | ||
mac.init(new SecretKeySpec(secretKey, GeomOpenConstant.DIGEST_ALGORITHM)); | ||
mac.update(body); | ||
String signature = Base64.getEncoder().encodeToString(mac.doFinal()); | ||
requestTemplate.header(GeomOpenConstant.SIGNATURE_HEADER, signature); | ||
} catch (Exception e) { | ||
throw new GeomOpenException(e); | ||
} | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
geom-open-sdk/src/test/java/io/github/xezzon/geom/Entity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package io.github.xezzon.geom; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public record Entity(String name) { | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
geom-open-sdk/src/test/java/io/github/xezzon/geom/GeomOpenRequestBuilderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import static io.github.xezzon.geom.TestApplication.SECRET_KEY; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; | ||
import org.springframework.boot.test.web.server.LocalServerPort; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | ||
class GeomOpenRequestBuilderTest { | ||
|
||
@LocalServerPort | ||
private int port; | ||
|
||
@Test | ||
void test() { | ||
TestApi testApi = new RequestBuilder("hello", SECRET_KEY).builder() | ||
.target(TestApi.class, "http://localhost:" + this.port); | ||
Entity entity = new Entity("Alice"); | ||
String response = testApi.test(entity); | ||
Assertions.assertEquals("Hello, Alice", response); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
geom-open-sdk/src/test/java/io/github/xezzon/geom/RequestBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import feign.Feign.Builder; | ||
import feign.jackson.JacksonEncoder; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public class RequestBuilder extends GeomOpenRequestBuilder { | ||
|
||
public RequestBuilder(String accessKey, String secretKey) { | ||
super(accessKey, secretKey); | ||
} | ||
|
||
@Override | ||
public Builder builder() { | ||
return super.builder() | ||
.encoder(new JacksonEncoder()) | ||
; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
geom-open-sdk/src/test/java/io/github/xezzon/geom/TestApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import feign.Headers; | ||
import feign.RequestLine; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
public interface TestApi { | ||
|
||
@RequestLine("POST /test") | ||
@Headers("Content-Type: application/json") | ||
String test(Entity entity); | ||
} |
31 changes: 31 additions & 0 deletions
31
geom-open-sdk/src/test/java/io/github/xezzon/geom/TestApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Base64; | ||
import javax.crypto.KeyGenerator; | ||
import javax.crypto.SecretKey; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
@SpringBootApplication | ||
public class TestApplication { | ||
|
||
public static final String SECRET_KEY; | ||
|
||
static { | ||
try { | ||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); | ||
SecretKey key = keyGenerator.generateKey(); | ||
SECRET_KEY = Base64.getEncoder().encodeToString(key.getEncoded()); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(TestApplication.class, args); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
geom-open-sdk/src/test/java/io/github/xezzon/geom/TestController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package io.github.xezzon.geom; | ||
|
||
import static io.github.xezzon.geom.GeomOpenConstant.DIGEST_ALGORITHM; | ||
import static io.github.xezzon.geom.TestApplication.SECRET_KEY; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import jakarta.annotation.Resource; | ||
import java.io.IOException; | ||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.util.Base64; | ||
import javax.crypto.Mac; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestHeader; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/** | ||
* @author xezzon | ||
*/ | ||
@RestController | ||
public class TestController { | ||
|
||
@Resource | ||
private ObjectMapper objectMapper; | ||
|
||
@PostMapping("/test") | ||
public String test( | ||
@RequestBody byte[] body, | ||
@RequestHeader(GeomOpenConstant.ACCESS_KEY_HEADER) String accessKey, | ||
@RequestHeader(GeomOpenConstant.TIMESTAMP_HEADER) Instant timestamp, | ||
@RequestHeader(GeomOpenConstant.SIGNATURE_HEADER) String signature | ||
) throws NoSuchAlgorithmException, InvalidKeyException, IOException { | ||
Assertions.assertEquals("hello", accessKey); | ||
Assertions.assertTrue(timestamp.isBefore(Instant.now())); | ||
Assertions.assertTrue(Duration.between(timestamp, Instant.now()).toMinutes() < 2); | ||
Mac mac = Mac.getInstance(DIGEST_ALGORITHM); | ||
mac.init(new SecretKeySpec(Base64.getDecoder().decode(SECRET_KEY), DIGEST_ALGORITHM)); | ||
mac.update(body); | ||
Assertions.assertArrayEquals(Base64.getDecoder().decode(signature), mac.doFinal()); | ||
Entity entity = objectMapper.readValue(body, Entity.class); | ||
return "Hello, " + entity.name(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
...eom-service-open/src/main/java/io/github/xezzon/geom/call/SubscriptionCallController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package io.github.xezzon.geom.call; | ||
|
||
import static com.google.auth.http.AuthHttpConstants.BEARER; | ||
|
||
import io.github.xezzon.geom.GeomOpenConstant; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.time.Instant; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestHeader; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/** | ||
* 订阅服务调用记录 | ||
* @author xezzon | ||
*/ | ||
@RestController | ||
@RequestMapping("/subscription-call") | ||
public class SubscriptionCallController { | ||
|
||
private final SubscriptionCallService subscriptionCallService; | ||
|
||
public SubscriptionCallController(SubscriptionCallService subscriptionCallService) { | ||
this.subscriptionCallService = subscriptionCallService; | ||
} | ||
|
||
@PostMapping("/validate") | ||
public void validateCall( | ||
@RequestBody byte[] body, | ||
@RequestParam("path") String path, | ||
@RequestHeader(GeomOpenConstant.ACCESS_KEY_HEADER) String accessKey, | ||
@RequestHeader(GeomOpenConstant.TIMESTAMP_HEADER) Instant timestamp, | ||
@RequestHeader(GeomOpenConstant.SIGNATURE_HEADER) String signature, | ||
HttpServletResponse response | ||
) { | ||
/* 所有校验通过后发放令牌 */ | ||
String jwt = subscriptionCallService.signJwt(accessKey, path, body, signature, timestamp); | ||
response.setHeader(HttpHeaders.AUTHORIZATION, BEARER + " " + jwt); | ||
} | ||
} |
Oops, something went wrong.