|
| 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 | + |
0 commit comments