tests for JWTTokenProvider, verifying the "Authentication" header

This test basically ensures that the requests made with a
JWTTokenProvider follow a valid Authentication pattern,
verifying that the header "conforms" to a valid JWT token
More information on JWT tokens can be found at:

- https://jwt.io/introduction/
This commit is contained in:
Marcos.Cela
2021-01-08 09:52:50 +01:00
parent ca7c809feb
commit a96275c286
3 changed files with 126 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
package org.kohsuke.github.extras.auth;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.junit.Test;
import org.kohsuke.github.AbstractGitHubWireMockTest;
import org.kohsuke.github.GitHub;
public class JWTTokenProviderTest extends AbstractGitHubWireMockTest {
private static String TEST_APP_ID_2 = "83009";
private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
/**
* This test will request an application ensuring that the header for the "Authorization" matches a valid JWT token.
* A JWT token in the Authorization header will always start with "ey" which is always the start of the base64
* encoding of the JWT Header , so a valid header will look like this:
*
* <pre>
* Authorization: Bearer ey{rest of the header}.{payload}.{signature}
* </pre>
*
* Matched by the regular expression:
*
* <pre>
* ^Bearer (?<JWTHeader>ey\S*)\.(?<JWTPayload>\S*)\.(?<JWTSignature>\S*)$
* </pre>
*
* Which is present in the wiremock matcher. Note that we need to use a matcher because the JWT token is encoded
* with a private key and a random nonce, so it will never be the same (under normal conditions). For more
* information on the format of a JWT token, see: https://jwt.io/introduction/
*/
@Test
public void testAuthorizationHeaderPattern() throws GeneralSecurityException, IOException {
JWTTokenProvider jwtTokenProvider = new JWTTokenProvider(TEST_APP_ID_2,
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()));
GitHub gh = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
.withAuthorizationProvider(jwtTokenProvider)
.build();
// Request the application, the wiremock matcher will ensure that the header
// for the authorization is present and has a the format of a valid JWT token
gh.getApp();
}
}

View File

@@ -0,0 +1,34 @@
{
"id": 83009,
"slug": "ghapi-test-app-2",
"node_id": "MDM6QXBwODMwMDk=",
"owner": {
"login": "hub4j-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
"type": "Organization",
"site_admin": false
},
"name": "GHApi Test app 2",
"description": "",
"external_url": "https://localhost",
"html_url": "https://github.com/apps/ghapi-test-app-2",
"created_at": "2020-09-30T15:02:20Z",
"updated_at": "2020-09-30T15:02:20Z",
"permissions": {},
"events": [],
"installations_count": 1
}

View File

@@ -0,0 +1,44 @@
{
"id": "bb7cf5bb-45b3-fba2-afd8-939b2c24787a",
"name": "app",
"request": {
"url": "/app",
"method": "GET",
"headers": {
"Authorization": {
"matches": "^Bearer (?<JWTHeader>ey\\S*)\\.(?<JWTPayload>\\S*)\\.(?<JWTSignature>\\S*)$"
},
"Accept": {
"equalTo": "application/vnd.github.machine-man-preview+json"
}
}
},
"response": {
"status": 200,
"bodyFileName": "app-1.json",
"headers": {
"Date": "Thu, 05 Nov 2020 20:42:31 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"Cache-Control": "public, max-age=60, s-maxage=60",
"Vary": [
"Accept",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"b3d319dbb4dba93fbda071208d874e5ab566d827e1ad1d7dc59f26d68694dc48\"",
"X-GitHub-Media-Type": "github.v3; param=machine-man-preview; format=json",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "9294:AE05:BDAC761:DB35838:5FA463B6"
}
},
"uuid": "bb7cf5bb-45b3-fba2-afd8-939b2c24787a",
"persistent": true,
"insertionIndex": 1
}