Skip to content

Commit ae6ca26

Browse files
committed
Initial commit
0 parents  commit ae6ca26

24 files changed

+2506
-0
lines changed

.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#Paths to ignore
2+
/bin/
3+
/build/
4+
/log/
5+
/target/
6+
/.gradle/
7+
/.settings/
8+
/.idea/
9+
10+
#IDE based project files
11+
*.iml
12+
*.classpath
13+
*.project
14+
15+
# Local configuration file (sdk path, etc)
16+
local.properties
17+
18+
# Windows thumbnail db
19+
Thumbs.db
20+
21+
# OSX files
22+
.DS_Store
23+
24+
# Java class files
25+
*.class

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Change Log
2+
3+
## Added
4+
### V1.0-SNAPSHOT
5+
+ Initial release with HMAC256 and RSA256 signing utility

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (C) 2017 GovTech, Government Digital Services, PDD-AI
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# APEX API Security Utility
2+
3+
A java helper utilities that form HTTP security header for authentication and verification
4+
5+
## Getting Started
6+
Include this helper class in your java project to perform API Security operations
7+
8+
This project use Maven or Gradle as its build and management tools
9+
10+
### Maven Guide
11+
12+
+ Download and Install Maven (3.5.0 or above)
13+
+ Java (1.8)
14+
15+
#### Build
16+
17+
**Option 1:** Compile and package into JAR
18+
19+
```bash
20+
21+
mvn package
22+
23+
```
24+
25+
The compiled _jar_ file will be located in the **target** folder
26+
+ java-apex-api-security-1.0-SNAPSHOT.jar
27+
+ java-apex-api-security-1.0-SNAPSHOT-jar-with-dependencies.jar (this includes log4j libraries)
28+
29+
Import this jar file into your java classpath to use the utility class
30+
31+
**Option 2:** Compile and install the package into your local maven repository
32+
33+
```bash
34+
mvn install
35+
```
36+
37+
1. The compiled _package_ file will be installed under _com.api.util.ApiSecurity_ in the .m2 repo
38+
39+
1. For Maven Client Project setup, add the following dependencies to your pom.xml file :
40+
41+
```xml
42+
<dependency>
43+
<groupId>com.api.util</groupId>
44+
<artifactId>ApiSecurity</artifactId>
45+
<version>1.0-SNAPSHOT</version>
46+
</dependency>
47+
48+
```
49+
50+
**Note:**
51+
* This project is leveraging on _slf4j-log4j12_ framework for the logging. If you are using logging implementation other than log4j, you can change to other type of implementation such as nop,simple,jdk14,logback. You could replace the following xml in pom.xml.
52+
* If your are using Log4j _Version2_, please refer to [Log4j2-SLF4J Binding](https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/index.html)
53+
54+
55+
```xml
56+
<dependency>
57+
<groupId>org.slf4j</groupId>
58+
<artifactId>slf4j-log4j12</artifactId>
59+
<version>1.7.25</version>
60+
</dependency>
61+
62+
```
63+
64+
### Gradle Guide
65+
66+
+ Download and Install Gradle (4.0 or above)
67+
+ Java (1.8)
68+
69+
#### Preparation
70+
As some of the test cases contains UTF-8 characters, you have to set following property before the JVM execute the Gradle Daemon.
71+
72+
```bash
73+
export GRADLE_OPTS="-Dfile.encoding=utf-8"
74+
```
75+
76+
#### Build
77+
**Option 1:** Compile and package into JAR
78+
79+
```bash
80+
gradle clean build
81+
```
82+
83+
#### Test
84+
To test with Jacoco and publish a html report
85+
86+
```bash
87+
gradle test jacocoTestReport
88+
```
89+
90+
The compiled _jar_ file will be located in the **build/libs** folder
91+
+ java-apex-api-security-1.0-SNAPSHOT.jar
92+
93+
Import this jar into your java classpath to use the utility class
94+
95+
**Option 2:** Compile and install the package into your local maven repository
96+
97+
1. Refer to Maven Guide > Build > Option 2, for the maven repo installation (excluding Maven Client Project setup)
98+
99+
1. For Gradle Client Project setup, add the following dependencies to your build.gradle file :
100+
101+
```text
102+
repositories {
103+
mavenLocal()
104+
}
105+
dependencies {
106+
compile group: 'com.api.util', name: 'ApiSecurity', version: '1.0-SNAPSHOT'
107+
}
108+
109+
```
110+
111+
#### Development
112+
113+
##### Preparing BaseString :
114+
115+
Method:
116+
* getBaseString
117+
118+
Params:
119+
* authPrefix - Authorization Header scheme prefix , i.e 'prefix_appId'
120+
* signatureMethod
121+
* appId - App ID created in Gateway
122+
* urlPath
123+
* httpMethod
124+
* formList - only needed for Content-Type: application/x-www-form-urlencoded
125+
* nonce - set to null for random generated number
126+
* timestamp - set to null for current timestamp
127+
128+
```java
129+
String url = "https://<<URL>>/api/v1/?param1=first&ab-param2=123";
130+
131+
ApiList formList = new ApiList();
132+
formList.add("param1", "data1");
133+
134+
String baseString;
135+
136+
try {
137+
baseString = ApiAuthorization.getBaseString(
138+
"<<authPrefix>>",
139+
"HMACSHA256",
140+
"<<appId>>",
141+
url,
142+
"post",
143+
formList,
144+
"6584351262900708156",
145+
"1502184161702"
146+
);
147+
148+
System.out.println(baseString);
149+
150+
} catch (ApiUtilException e) {
151+
e.printStackTrace();
152+
}
153+
154+
```
155+
156+
##### Preparing L1 Security Signature :
157+
158+
Method:
159+
* getL1Signature
160+
161+
Params:
162+
* baseString
163+
* secret
164+
165+
```java
166+
String baseString = "GET&https://<<URL>>/api/v1/&ap=裕廊坊 心邻坊&<<authPrefix>>_app_id=<<appID>&<<authPrefix>>_nonce=2851111144329605674&<<authPrefix>>_signature_method=HMACSHA256&<<authPrefix>>_timestamp=1502163903712&<<authPrefix>>_version=1.0";
167+
String secret = "<<appSecret>>";
168+
String L1Sig;
169+
170+
try {
171+
L1Sig = ApiAuthorization.getL1Signature(baseString, secret);
172+
System.out.println(L1Sig);
173+
174+
} catch (ApiUtilException e) {
175+
e.printStackTrace();
176+
}
177+
178+
```
179+
180+
##### Preparing L2 Security Signature :
181+
182+
Method:
183+
* getL2Signature
184+
185+
Params:
186+
* baseString
187+
* secret
188+
189+
```java
190+
String baseString = "GET&https://<<URL>/api/v1/&ap=裕廊坊 心邻坊&<<authPrefix>>_app_id=<<appId>>&<<authPrefix>>_nonce=7231415196459608363&<<authPrefix>>_signature_method=SHA256withRSA&<<authPrefix>>_timestamp=1502164219425&<<authPrefix>>_version=1.0&oq=c# nunit mac&q=c# nunit mac";
191+
String alias = "alpha";
192+
String password = "<<passphrase>>";
193+
String keyStoreFileName = "certificates/alpha.test.p12";
194+
String publicCertFileName = "certificates/alpha.test.cer";
195+
196+
try {
197+
198+
PrivateKey privateKey = ApiAuthorization.getPrivateKeyFromKeyStore(keyStoreFileName, password, alias);
199+
200+
String signature = ApiAuthorization.getL2Signature(baseString, privateKey);
201+
202+
System.out.println(expectedSignature);
203+
System.out.println(signature);
204+
205+
PublicKey publicKey = ApiAuthorization.getPublicKeyFromX509Certificate(publicCertFileName);
206+
207+
} catch (ApexUtilLibException e) {
208+
e.printStackTrace();
209+
}
210+
211+
```
212+
213+
##### Preparing Authorization Token :
214+
Params:
215+
* realm
216+
* authPrefix - Authorization Header scheme prefix , i.e 'prefix_appId'
217+
* httpMethod
218+
* urlPath
219+
* appId - App ID created in Gateway
220+
* secret - set to null for REST L2 SHA256WITHRSA
221+
* formList
222+
* password
223+
* alias
224+
* fileName
225+
* nonce - set to null for random generated number
226+
* timestamp - set to null for current timestamp
227+
228+
229+
```java
230+
String url = "https://<<URL>>/api/v1/?ap=裕廊坊%20心邻坊";
231+
String certFileName = "certificates/alpha.test.p12";
232+
String password = "<<passphrase>>";
233+
String alias = "alpha";
234+
String appId = "<<appId>>";
235+
String nonce = null;
236+
String timestamp = null;
237+
238+
try {
239+
String signature = ApiAuthorization.getToken("http://api.test.io/l2", "<<authPrefix>>", "get", url, appId, null, null, password, alias, certFileName, nonce, timestamp);
240+
} catch (ApiUtilException e) {
241+
e.printStackTrace();
242+
}
243+
```
244+
### Release:
245+
+ Checkout CHANGELOG.md
246+
247+
### Contribution:
248+
We welcome your involvement, be it fixing bugs or implementing new features that you find relevant to this library.
249+
250+
To contribute, you may follow the steps below:
251+
1. Fork the repo
252+
2. Create a new branch from `development` to work on your contribution
253+
3. Create a pull request back when you are done
254+
255+
Alternatively, you can raise an issue for this Github repository.
256+
257+
### Reference:
258+
+ [UTF-8 in Gradle](https://stackoverflow.com/questions/21267234/show-utf-8-text-properly-in-gradle)
259+
+ [SLF4J FAQ](https://www.slf4j.org/faq.html)
260+
+ [Akana API Consumer Security](http://docs.akana.com/ag/cm_policies/using_api_consumer_app_sec_policy.htm)
261+
+ [RSA and HMAC Request Signing Standard](http://tools.ietf.org/html/draft-cavage-http-signatures-05)
262+

build.gradle

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
plugins {
2+
id 'java'
3+
id 'jacoco'
4+
id 'com.github.kt3k.coveralls' version '2.6.3'
5+
}
6+
7+
version '1.0-SNAPSHOT'
8+
9+
sourceCompatibility = 1.8
10+
11+
tasks.withType(JavaCompile) {
12+
options.encoding = "UTF-8"
13+
}
14+
15+
repositories {
16+
mavenCentral()
17+
}
18+
19+
dependencies {
20+
compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.1'
21+
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
22+
testCompile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.25'
23+
testCompile group: 'junit', name: 'junit', version: '4.12'
24+
}
25+
26+
jar {
27+
//Evaluate at execution time where all the configurations and dependencies are resolved
28+
from {
29+
configurations.compile.collect {
30+
it.isDirectory() ? it : zipTree(it)
31+
}
32+
}
33+
manifest {
34+
attributes 'Main-Class': 'ApexAuthorization'
35+
}
36+
}
37+
38+
jacocoTestReport {
39+
group = "Reporting"
40+
reports {
41+
xml.enabled = true // coveralls plugin depends on xml format report
42+
html.enabled = true
43+
html.destination file("${buildDir}/jacocoHtml")
44+
}
45+
}
46+

0 commit comments

Comments
 (0)