diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 909f794..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,62 +0,0 @@ -version: 2 -jobs: - java_7_build: - docker: - - image: openjdk:7u121-jdk - steps: - - checkout - - run: chmod +x gradlew - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "build.gradle" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - # run tests! - - run: ./gradlew clean check jacocoTestReport --continue --console=plain - - run: - name: Upload Coverage - when: on_success - command: bash <(curl -s https://codecov.io/bash) - - save_cache: - paths: - - ~/.m2 - key: v1-dependencies-{{ checksum "build.gradle" }} - environment: - GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"' - _JAVA_OPTIONS: "-Xms512m -Xmx1024m" - TERM: dumb - - java_8_build: - docker: - - image: openjdk:8-jdk - steps: - - checkout - - run: chmod +x gradlew - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "build.gradle" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - # run tests! - - run: ./gradlew clean check jacocoTestReport --continue --console=plain - - run: - name: Upload Coverage - when: on_success - command: bash <(curl -s https://codecov.io/bash) - - save_cache: - paths: - - ~/.m2 - key: v1-dependencies-{{ checksum "build.gradle" }} - environment: - GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"' - _JAVA_OPTIONS: "-Xms512m -Xmx1024m" - TERM: dumb - -workflows: - version: 2 - build: - jobs: - - java_7_build - - java_8_build diff --git a/.gitignore b/.gitignore index ab35b85..999c86d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,90 +1,173 @@ -# Created by .ignore support plugin (hsz.mobi) -### OSX template -*.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# Intellij -.idea/ -*.iml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ -/lib/out/ +# Maven Shaded Jar Artifact +dependency-reduced-pom.xml -# mpeltonen/sbt-idea plugin -.idea_modules/ +node_modules -# JIRA plugin -atlassian-ide-plugin.xml +# Ignore Eclipse stuff +.project +.settings +.classpath -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties +# Ignore Java and IntelliJ IDEA stuff +.idea +target +*.iml -### Java template -*.class +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +packages -# Package Files # -*.jar -*.war -*.ear +# User-specific files +*.suo +*.user +*.sln.docstates -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +# Build results -### Gradle template -.gradle +[Dd]ebug/ +[Rr]elease/ +x64/ build/ -target/ -dependency-reduced-pom.xml - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - +[Bb]in/ +[Oo]bj/ + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +!packages/*/build/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ef0da2f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: java +jdk: +- oraclejdk7 +branches: + only: + - master +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md deleted file mode 100644 index ac4aa97..0000000 --- a/AUTHORS.md +++ /dev/null @@ -1,6 +0,0 @@ -### This is the list of JWTs for Node authors for copyright purposes. -### This does not necessarily list everyone who has contributed code, since in -### some cases, their employer may be the copyright holder. To see the full list -### of contributors, see the revision history in source control. - -Auth0 LLC, Google LLC diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index d62283b..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,110 +0,0 @@ -Copyright (c) 2017 The Authors of 'JWTS for Java' - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# Change Log - -## [3.3.0](https://github.com/auth0/java-jwt/tree/3.3.0) (2017-11-06) -[Full Changelog](https://github.com/auth0/java-jwt/compare/3.2.0...3.3.0) -**Closed issues** -- Wrong ES256 signature length [\#187](https://github.com/auth0/java-jwt/issues/187) - -**Fixed** -- Rework ECDSA [\#212](https://github.com/auth0/java-jwt/pull/212) ([lbalmaceda](https://github.com/lbalmaceda)) -- Instantiate exception only when required [\#198](https://github.com/auth0/java-jwt/pull/198) ([rumdidumdum](https://github.com/rumdidumdum)) - -## [3.2.0](https://github.com/auth0/java-jwt/tree/3.2.0) (2017-05-04) -[Full Changelog](https://github.com/auth0/java-jwt/compare/3.1.0...3.2.0) -**Closed issues** -- Claim.isNull() returns true for JSON Object constructed claims [\#160](https://github.com/auth0/java-jwt/issues/160) -- Incorrectly rejects whitespace after JSON header as invalid [\#144](https://github.com/auth0/java-jwt/issues/144) -- No token type [\#136](https://github.com/auth0/java-jwt/issues/136) -- Timestamps are limited by Integer/int to 2038-01-19T04:14:07.000+0100 [\#132](https://github.com/auth0/java-jwt/issues/132) - -**Added** -- Refactor KeyProvider to receive the "Key Id" [\#167](https://github.com/auth0/java-jwt/pull/167) ([lbalmaceda](https://github.com/lbalmaceda)) -- Add Sign/Verify of Long type claims [\#157](https://github.com/auth0/java-jwt/pull/157) ([vrancic](https://github.com/vrancic)) -- added date validation dedicated exception [\#155](https://github.com/auth0/java-jwt/pull/155) ([Spyna](https://github.com/Spyna)) -- Allow to get a Claim as Map [\#152](https://github.com/auth0/java-jwt/pull/152) ([lbalmaceda](https://github.com/lbalmaceda)) -- Add Algorithm KeyProvider interface [\#149](https://github.com/auth0/java-jwt/pull/149) ([lbalmaceda](https://github.com/lbalmaceda)) -- Instantiate RSA/EC Algorithm with both keys [\#147](https://github.com/auth0/java-jwt/pull/147) ([lbalmaceda](https://github.com/lbalmaceda)) -- Add Key Id setter and set JWT Type after signing [\#138](https://github.com/auth0/java-jwt/pull/138) ([lbalmaceda](https://github.com/lbalmaceda)) - -**Changed** -- Change the JWT.decode() return type to DecodedJWT [\#150](https://github.com/auth0/java-jwt/pull/150) ([lbalmaceda](https://github.com/lbalmaceda)) - -**Fixed** -- Fix Claim.isNull() method for JSON Objects [\#161](https://github.com/auth0/java-jwt/pull/161) ([lbalmaceda](https://github.com/lbalmaceda)) -- Accept blanks, new line and carriage returns on JSON [\#151](https://github.com/auth0/java-jwt/pull/151) ([lbalmaceda](https://github.com/lbalmaceda)) -- Fix Date value conversion [\#137](https://github.com/auth0/java-jwt/pull/137) ([lbalmaceda](https://github.com/lbalmaceda)) - -## [3.1.0](https://github.com/auth0/java-jwt/tree/3.1.0) (2017-01-04) -[Full Changelog](https://github.com/auth0/java-jwt/compare/3.0.2...3.1.0) - -**Added** -- Make Clock customization accessible for verification [\#125](https://github.com/auth0/java-jwt/pull/125) ([lbalmaceda](https://github.com/lbalmaceda)) -- Add getter for all the Payload's Claims [\#124](https://github.com/auth0/java-jwt/pull/124) ([lbalmaceda](https://github.com/lbalmaceda)) -- Accept Array type on verification and creation. [\#123](https://github.com/auth0/java-jwt/pull/123) ([lbalmaceda](https://github.com/lbalmaceda)) - -## [3.0.2](https://github.com/auth0/java-jwt/tree/3.0.2) (2016-12-13) -[Full Changelog](https://github.com/auth0/java-jwt/compare/3.0.1...3.0.2) - -**Fixed** -- Add targetCompatibility to 1.7 [\#121](https://github.com/auth0/java-jwt/pull/121) ([hzalaz](https://github.com/hzalaz)) - -## [3.0.1](https://github.com/auth0/java-jwt/tree/3.0.0) (2016-12-05) -[Full Changelog](https://github.com/auth0/java-jwt/compare/3.0.0...3.0.1) - -Update to allow sync with Maven Central - -## [3.0.0](https://github.com/auth0/java-jwt/tree/3.0.0) (2016-12-05) - -Reimplemented java-jwt to improve API and include more signing algorithms - -## Installation - -### Maven - -```xml - - com.auth0 - java-jwt - 3.0.0 - -``` - -### Gradle - -```gradle -compile 'com.auth0:java-jwt:3.0.0' -``` - -## Available Algorithms - -The library implements JWT Verification and Signing using the following algorithms: - -| JWS | Algorithm | Description | -| :-------------: | :-------------: | :----- | -| HS256 | HMAC256 | HMAC with SHA-256 | -| HS384 | HMAC384 | HMAC with SHA-384 | -| HS512 | HMAC512 | HMAC with SHA-512 | -| RS256 | RSA256 | RSASSA-PKCS1-v1_5 with SHA-256 | -| RS384 | RSA384 | RSASSA-PKCS1-v1_5 with SHA-384 | -| RS512 | RSA512 | RSASSA-PKCS1-v1_5 with SHA-512 | -| ES256 | ECDSA256 | ECDSA with curve P-256 and SHA-256 | -| ES384 | ECDSA384 | ECDSA with curve P-384 and SHA-384 | -| ES512 | ECDSA512 | ECDSA with curve P-521 and SHA-512 | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 6d364e1..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution, -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. \ No newline at end of file diff --git a/LICENSE b/LICENSE.txt similarity index 99% rename from LICENSE rename to LICENSE.txt index 4a7a13a..bcd1854 100644 --- a/LICENSE +++ b/LICENSE.txt @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index 487c06d..93236bb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# JWTs for Java -This is not an officially supported Google product +# Java JWT -[![CircleCI](https://img.shields.io/circleci/project/github/auth0/java-jwt.svg?style=flat-square)](https://circleci.com/gh/auth0/java-jwt/tree/master) -[![Coverage Status](https://img.shields.io/codecov/c/github/auth0/java-jwt/v3.svg?style=flat-square)](https://codecov.io/github/auth0/java-jwt) +[![Build Status](https://travis-ci.org/auth0/java-jwt.svg?branch=master)](https://travis-ci.org/auth0/java-jwt) +[![Coverage Status](https://img.shields.io/codecov/c/github/auth0/java-jwt/master.svg?style=flat-square)](https://codecov.io/github/auth0/java-jwt) [![License](http://img.shields.io/:license-mit-blue.svg?style=flat)](http://doge.mit-license.org) +[![Maven Central](https://img.shields.io/maven-central/v/com.auth0/java-jwt.svg)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22java-jwt%22) -A Java implementation of [JSON Web Tokens (draft-ietf-oauth-json-web-token-08)](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html). - -If you're looking for an **Android** version of the JWT Decoder take a look at our [JWTDecode.Android](https://github.com/auth0/JWTDecode.Android) library. +An implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) developed against `draft-ietf-oauth-json-web-token-08`. ## Installation @@ -17,450 +15,74 @@ If you're looking for an **Android** version of the JWT Decoder take a look at o com.auth0 java-jwt - 3.3.0 + 2.2.1 ``` ### Gradle ```gradle -compile 'com.auth0:java-jwt:3.3.0' +compile 'com.auth0:java-jwt:2.2.1' ``` -## Available Algorithms - -The library implements JWT Verification and Signing using the following algorithms: - -| JWS | Algorithm | Description | -| :-------------: | :-------------: | :----- | -| HS256 | HMAC256 | HMAC with SHA-256 | -| HS384 | HMAC384 | HMAC with SHA-384 | -| HS512 | HMAC512 | HMAC with SHA-512 | -| RS256 | RSA256 | RSASSA-PKCS1-v1_5 with SHA-256 | -| RS384 | RSA384 | RSASSA-PKCS1-v1_5 with SHA-384 | -| RS512 | RSA512 | RSASSA-PKCS1-v1_5 with SHA-512 | -| ES256 | ECDSA256 | ECDSA with curve P-256 and SHA-256 | -| ES384 | ECDSA384 | ECDSA with curve P-384 and SHA-384 | -| ES512 | ECDSA512 | ECDSA with curve P-521 and SHA-512 | - -## Supported token profile types - -#### Basic Token - -- Standard claims: *iss, sub, iat, jti* -- Nonstandard claims: *aud, exp, nbf* - -#### Extended Token -- Standard claims: *name, email, picture, iss, sub, iat* -- Nonstandard claims: *aud, exp, nbf* - -#### Access Token -- Standard claims: *iss, sub, iat* -- Nonstandard claims: *aud, exp* - -#### Facebook Token -- Standard claims: *user_id, app_id, issued_at* -- Nonstandard claims: *expired_at* - -#### Google Token -- Standard claims: *name, email, picture, iss, sub, iat* -- Nonstandard claims: *exp, aud* - -#### Implicit Access Token -- Standard claims: *iss, sub, iat* -- Nonstandard claims: *aud* +## Usage -#### Refresh Token -- Standard claims: *refresh_token, access_token* - -#### Risc Token -- Standard claims: *jti, iss, sub, iat* -- Nonstandard claims: *aud, nbf, exp* - -#### Scoped Access Token -- Standard claims: *iss, sub, iat, scope* -- Nonstandard claims: *aud, exp* - -### Pick the Algorithm - -The Algorithm defines how a token is signed and verified. It can be instantiated with the raw value of the secret in the case of HMAC algorithms, or the key pairs or `KeyProvider` in the case of RSA and ECDSA algorithms. Once created, the instance is reusable for token signing and verification operations. - -When using RSA or ECDSA algorithms and you just need to **sign** JWTs you can avoid specifying a Public Key by passing a `null` value. The same can be done with the Private Key when you just need to **verify** JWTs. - - -#### Using static secrets or keys: +### Sign JWT (HS256) ```java -//HMAC -Algorithm algorithmHS = Algorithm.HMAC256("secret"); - -//RSA -RSAPublicKey publicKey = //Get the key instance -RSAPrivateKey privateKey = //Get the key instance -Algorithm algorithmRS = Algorithm.RSA256(publicKey, privateKey); -``` - -#### Using a KeyProvider: +final String issuer = "https://mydomain.com/"; +final String secret = "{{secret used for signing}}"; -By using a `KeyProvider` you can change in runtime the key used either to verify the token signature or to sign a new token for RSA or ECDSA algorithms. This is achieved by implementing either `RSAKeyProvider` or `ECDSAKeyProvider` methods: +final long iat = System.currentTimeMillis() / 1000L; // issued at claim +final long exp = iat + 60L; // expires claim. In this case the token expires in 60 seconds -- `getPublicKeyById(String kid)`: Its called during token signature verification and it should return the key used to verify the token. If key rotation is being used, e.g. [JWK](https://tools.ietf.org/html/rfc7517) it can fetch the correct rotation key using the id. (Or just return the same key all the time). -- `getPrivateKey()`: Its called during token signing and it should return the key that will be used to sign the JWT. -- `getPrivateKeyId()`: Its called during token signing and it should return the id of the key that identifies the one returned by `getPrivateKey()`. This value is preferred over the one set in the `JWTCreator.Builder#withKeyId(String)` method. If you don't need to set a `kid` value avoid instantiating an Algorithm using a `KeyProvider`. +final JWTSigner signer = new JWTSigner(secret); +final HashMap claims = new HashMap(); +claims.put("iss", issuer); +claims.put("exp", exp); +claims.put("iat", iat); - -The following snippet uses example classes showing how this would work: - - -```java -final JwkStore jwkStore = new JwkStore("{JWKS_FILE_HOST}"); -final RSAPrivateKey privateKey = //Get the key instance -final String privateKeyId = //Create an Id for the above key - -RSAKeyProvider keyProvider = new RSAKeyProvider() { - @Override - public RSAPublicKey getPublicKeyById(String kid) { - //Received 'kid' value might be null if it wasn't defined in the Token's header - RSAPublicKey publicKey = jwkStore.get(kid); - return (RSAPublicKey) publicKey; - } - - @Override - public RSAPrivateKey getPrivateKey() { - return privateKey; - } - - @Override - public String getPrivateKeyId() { - return privateKeyId; - } -}; - -Algorithm algorithm = Algorithm.RSA256(keyProvider); -//Use the Algorithm to create and verify JWTs. +final String jwt = signer.sign(claims); ``` -> For simple key rotation using JWKs try the [jwks-rsa-java](https://github.com/auth0/jwks-rsa-java) library. - - -### Create and Sign a Token - -You'll first need to create a `JWTCreator` instance by calling `JWT.create()`. Use the builder to define the custom Claims your token needs to have. Finally to get the String token call `sign()` and pass the `Algorithm` instance. - -* Example using `HS256` +### Verify JWT (HS256) ```java +final String secret = "{{secret used for signing}}"; try { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = JWT.create() - .withIssuer("auth0") - .sign(algorithm); -} catch (UnsupportedEncodingException exception){ - //UTF-8 encoding not supported -} catch (JWTCreationException exception){ - //Invalid Signing configuration / Couldn't convert Claims. + final JWTVerifier verifier = new JWTVerifier(secret); + final Map claims= verifier.verify(jwt); +} catch (JWTVerifyException e) { + // Invalid Token } ``` -* Example using `RS256` +### Validate aud & iss claims ```java -RSAPublicKey publicKey = //Get the key instance -RSAPrivateKey privateKey = //Get the key instance +final String secret = "{{secret used for signing}}"; try { - Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey); - String token = JWT.create() - .withIssuer("auth0") - .sign(algorithm); -} catch (JWTCreationException exception){ - //Invalid Signing configuration / Couldn't convert Claims. + final JWTVerifier verifier = new JWTVerifier(secret, "{{my-audience}}", "{{my-issuer}}"); + final Map claims= verifier.verify(jwt); +} catch (JWTVerifyException e) { + // Invalid Token } ``` -If a Claim couldn't be converted to JSON or the Key used in the signing process was invalid a `JWTCreationException` will raise. - -NOTE: Each token has a NoneAlgorithm boolean value which is set to False by default unless set explicitly. - -```java -GoogleJwtCreator.build().setIsNoneAlgorithmAllowed(true) -``` - -If the none algorithm property is set to true as done above, the following error will be thrown when algorithm 'none' is used: -"None algorithm isn't allowed". - -### Serializing a token - -When signing, you can encode via a 16-byte, 32-byte, the standard 64-byte, and a JSON encoding. -When you call the method standard `sign()` as in the example above, the token is 64-byte encoded. -To encode via a 16-byte, call `signBase16Encoding()`, via a 32-byte, call `signBase32Encoding()`, and -via a JSON encoding, call `signJSONEncoding()`. - -### Verify a Token - -You'll first need to create a `Verification` instance by calling `JWT.require()` and passing the `Algorithm` instance. Once you have the `Verification` instance, you can call the corresponding verifier method. For the example of Google, -you would have a `GoogleVerificiation` instance that has inherited from the `Verification` instance in order to call `createVerifierForGoogle()`, and you would pass in the claims that you would want to be verified. -Once you call `build`, you would get back a `JWT` object and with that, you would call `decode()` while passing in the token that was created after signing. You will get back a `DecodedJWT` object, which contains all of the claims, and you can verify -those claims against what's the expected claims by calling `verifyClaims()`. - -* Example using `HS256` - -```java -String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"; -Algorithm algorithm = Algorithm.HMAC256("secret"); -GoogleVerification verification = GoogleJWT.require(algorithm); -JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("accounts.fake.com"), asList("audience"), - NAME, 1, 1).build(); -DecodedJWT jwt = verifier.decode(token); -Map claims = jwt.getClaims(); -verifyClaims(claims, exp); -``` - -* Example using `RS256` - -```java -String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"; -RSAPublicKey publicKey = //Get the key instance -RSAPrivateKey privateKey = //Get the key instance - -Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey); -GoogleVerification verification = GoogleJWT.require(algorithm); -JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("accounts.fake.com"), asList("audience"), - NAME, 1, 1).build(); -DecodedJWT jwt = verifier.decode(token); -Map claims = jwt.getClaims(); -verifyClaims(claims, exp); -``` - -If the token has a Claim requirement that has not been met, an `InvalidClaimException` will raise. -If the token has an invalid signature, an `AlgorithmMismatchException` will raise. - -### Deserializing a token - -In order to recover the DecodedJWT after signing, you need to decode with the appropriate decode method -corresponding to the appropriate encode method. For the standard 64-byte encoding, to recover the DecodedJWT, -you call `decode()` as in the example above. When you encode via 16-bytes, you call `decode16Bytes()`, -via 32-bytes, call `decode32Bytes()`, and via a JSON encoding, call `decodeJSON()`. - -#### Time Validation - -The JWT token may include DateNumber fields that can be used to validate that: -* The token was issued in a past date `"iat" < TODAY` -* The token hasn't expired yet `"exp" > TODAY` and -* The token can already be used. `"nbf" > TODAY` - -When verifying a token the time validation occurs automatically, resulting in a `JWTVerificationException` being throw when the values are invalid. If any of the previous fields are missing they won't be considered in this validation. - -To specify a **nbf value** in which the Token should still be considered valid, use the `withNbf()` method in the respective `Creator` builder and pass a Date object. This applies to every item listed above. -**NOTE:** `Nbf` and `iat` date values should be in the past, but the `exp` value should be in the future. -```java -Verification verifier = JWT.require(algorithm) - .withNbf(new Date(2016,1,1)) - .build(); -``` - -You can also specify a custom value for a given Date claim and override the default one for only that claim. - -```java -Verification verifier = JWT.require(algorithm) - .withNbf(new Date(2016,1,1)) - .withExp(new Date(2100,1,1)) - .build(); -``` - -If you need to test this behaviour in your lib/app cast the `Verification` instance to a `BaseVerification` to gain visibility of the `verification.build()` method that accepts a custom `Clock`. e.g.: - -```java -BaseVerification verification = (BaseVerification) JWT.require(algorithm) - .acceptLeeway(1) - .acceptExpiresAt(5); -Clock clock = new CustomClock(); //Must implement Clock interface -JWT verifier = verification.build(clock); -``` - -### Decode a Token - -This example is for an Implicit JWT token and can be applied to all the types of tokens: -```java -String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOlsic3ViamVjdCJdLCJpc3MiOlsiYWNjb3VudHMuZmFrZS5jb20iXSwiYXVkIjoiYXVkaWVuY2UiLCJpYXQiOi0xMjQ1MjgxNTI3fQ.-eRoMolUy7PnEcpvfs-jTEvP6qagBZ1G_lqp1jY3Nqg"; -Verification verification = ImplicitJWT.require(algorithm); -JWT verifier = verification.createVerifierForImplicit(asList("accounts.fake.com"), asList("audience"), 1).build(); -DecodedJWT jwt = verifier.decode(token); -``` - -If the token has an invalid syntax or the header or payload are not JSONs, a `JWTDecodeException` will raise. - - -### Header Claims - -#### Algorithm ("alg") - -Returns the Algorithm value or null if it's not defined in the Header. - -```java -String algorithm = jwt.getAlgorithm(); -``` - -#### Type ("typ") - -Returns the Type value or null if it's not defined in the Header. - -```java -String type = jwt.getType(); -``` - -#### Content Type ("cty") - -Returns the Content Type value or null if it's not defined in the Header. - -```java -String contentType = jwt.getContentType(); -``` - -#### Key Id ("kid") - -Returns the Key Id value or null if it's not defined in the Header. - -```java -String keyId = jwt.getKeyId(); -``` - -#### Private Claims - -Additional Claims defined in the token's Header can be obtained by calling `getHeaderClaim()` and passing the Claim name. A Claim will always be returned, even if it can't be found. You can check if a Claim's value is null by calling `claim.isNull()`. - -```java -Claim claim = jwt.getHeaderClaim("owner"); -``` - -When creating a Token with the `JWTCreator.init()` you can specify header Claims by calling `withHeader()` and passing both the map of claims. - -```java -Map headerClaims = new HashMap(); -headerClaims.put("owner", "auth0"); -String token = JWTCreator.init() - .withHeader(headerClaims) - .sign(algorithm); -``` - -> The `alg` and `typ` values will always be included in the Header after the signing process. - - -### Payload Claims - -#### Issuer ("iss") - -Returns the Issuer value or null if it's not defined in the Payload. - -```java -String issuer = jwt.getIssuer(); -``` - -#### Subject ("sub") - -Returns the Subject value or null if it's not defined in the Payload. - -```java -String subject = jwt.getSubject(); -``` - -#### Audience ("aud") - -Returns the Audience value or null if it's not defined in the Payload. - -```java -List audience = jwt.getAudience(); -``` - -#### Expiration Time ("exp") - -Returns the Expiration Time value or null if it's not defined in the Payload. - -```java -Date expiresAt = jwt.getExpiresAt(); -``` - -#### Not Before ("nbf") - -Returns the Not Before value or null if it's not defined in the Payload. - -```java -Date notBefore = jwt.getNotBefore(); -``` - -#### Issued At ("iat") - -Returns the Issued At value or null if it's not defined in the Payload. - -```java -Date issuedAt = jwt.getIssuedAt(); -``` - -#### JWT ID ("jti") - -Returns the JWT ID value or null if it's not defined in the Payload. - -```java -String id = jwt.getId(); -``` - -#### Nonstandard Claims - -Nonstandard Claims defined in the token's Payload can be obtained by calling `getClaims()` or `getClaim()` and passing the Claim name. A Claim will always be returned, even if it can't be found. You can check if a Claim's value is null by calling `claim.isNull()`. - -```java -Map claims = jwt.getClaims(); //Key is the Claim name -Claim claim = claims.get("isAdmin"); -``` - -or - -```java -Claim claim = jwt.getClaim("isAdmin"); -``` - -When creating an Implicit Token for example with the `ImplicitJwtCreator.build()` you can specify a custom Claim by calling `withNonStandardClaim()` and passing both the name and the value. - -```java -String token = ImplicitJwtCreator.build() - .withNonStandardClaim("nonStandardClaim", 123) - .withArrayClaim("array", new Integer[]{1, 2, 3}) - .sign(algorithm); -``` - -**NOTE:** Nonstandard claims aside from `aud`, `exp`, and `nbf` do not need to verified. - -> Currently supported classes for custom JWT Claim creation and verification are: Boolean, Integer, Double, String, Date and Arrays of type String and Integer. - - -### Claim Class -The Claim class is a wrapper for the Claim values. It allows you to get the Claim as different class types. The available helpers are: - -#### Primitives -* **asBoolean()**: Returns the Boolean value or null if it can't be converted. -* **asInt()**: Returns the Integer value or null if it can't be converted. -* **asDouble()**: Returns the Double value or null if it can't be converted. -* **asLong()**: Returns the Long value or null if it can't be converted. -* **asString()**: Returns the String value or null if it can't be converted. -* **asDate()**: Returns the Date value or null if it can't be converted. This must be a NumericDate (Unix Epoch/Timestamp). Note that the [JWT Standard](https://tools.ietf.org/html/rfc7519#section-2) specified that all the *NumericDate* values must be in seconds. - -#### Custom Classes and Collections -To obtain a Claim as a Collection you'll need to provide the **Class Type** of the contents to convert from. -* **as(class)**: Returns the value parsed as **Class Type**. For collections you should use the `asArray` and `asList` methods. -* **asMap()**: Returns the value parsed as **Map**. -* **asArray(class)**: Returns the value parsed as an Array of elements of type **Class Type**, or null if the value isn't a JSON Array. -* **asList(class)**: Returns the value parsed as a List of elements of type **Class Type**, or null if the value isn't a JSON Array. +### Why another JSON Web Token implementation for Java? -If the values can't be converted to the given **Class Type** a `JWTDecodeException` will raise. +We believe existing JWT implementations in Java are either too complex or not tested enough. +This library aims to be simple and achieve the right level of abstraction. ## Issue Reporting -If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. +If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. -## Authors +## Author -Auth0 LLC, Google LLC +[Auth0](https://auth0.com/) ## License -This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info. +This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. diff --git a/build.gradle b/build.gradle deleted file mode 100644 index b18f759..0000000 --- a/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' - } -} - -allprojects { - group = 'com.auth0' - - repositories { - jcenter() - } -} diff --git a/.codecov.yml b/codecov.yml similarity index 100% rename from .codecov.yml rename to codecov.yml diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index aac7c9b..0000000 --- a/gradle.properties +++ /dev/null @@ -1,17 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 04e285f..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Mon Dec 28 10:00:20 PST 2015 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/gradlew b/gradlew deleted file mode 100755 index 9d82f78..0000000 --- a/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index aec9973..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/lib/.gitignore b/lib/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/lib/build.gradle b/lib/build.gradle deleted file mode 100644 index 2a7694c..0000000 --- a/lib/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -apply plugin: 'jacoco' -apply plugin: 'java' -apply from: '../scripts/release.gradle' -apply from: '../scripts/maven.gradle' -apply from: '../scripts/bintray.gradle' - -logger.lifecycle("Using version ${version} for ${group}.${name}") - -auth0 { - name "java jwt" - repo "java-jwt" - description "Java implementation of JSON Web Token (JWT)" - url 'http://www.jwt.io' - developer { - id = "auth0" - name = "Auth0" - email = "oss@auth0.com" - } - developer { - id = "lbalmaceda" - name = "Luciano Balmaceda" - email = "luciano.balmaceda@auth0.com" - } - developer { - id = "hzalaz" - name = "Hernan Zalazar" - email = "hernan@auth0.com" - } -} - -compileJava { - sourceCompatibility '1.7' - targetCompatibility '1.7' -} - -dependencies { - compile 'com.fasterxml.jackson.core:jackson-databind:2.9.2' - compile 'commons-codec:commons-codec:1.11' - compile 'com.google.code.gson:gson:2.8.2' - testCompile 'org.bouncycastle:bcprov-jdk15on:1.58' - testCompile 'junit:junit:4.12' - testCompile 'net.jodah:concurrentunit:0.4.3' - testCompile 'org.hamcrest:java-hamcrest:2.0.0.0' - testCompile 'org.mockito:mockito-core:2.11.0' -} - -jacocoTestReport { - reports { - xml.enabled = true - html.enabled = true - } -} - -test { - testLogging { - events "skipped", "failed", "standardError" - exceptionFormat "short" - } -} - -task clean(type: Delete) { - delete rootProject.buildDir - delete 'CHANGELOG.md.release' -} diff --git a/lib/src/main/java/com/auth0/jwt/ClockImpl.java b/lib/src/main/java/com/auth0/jwt/ClockImpl.java deleted file mode 100644 index 250c6a0..0000000 --- a/lib/src/main/java/com/auth0/jwt/ClockImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.interfaces.Clock; - -import java.util.Date; - -public final class ClockImpl implements Clock { - - public ClockImpl() { - } - - @Override - public Date getToday() { - return new Date(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/JWTDecoder.java b/lib/src/main/java/com/auth0/jwt/JWTDecoder.java deleted file mode 100644 index 7a967fb..0000000 --- a/lib/src/main/java/com/auth0/jwt/JWTDecoder.java +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.creators.JWTCreator; -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.impl.JWTParser; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Header; -import com.auth0.jwt.interfaces.Payload; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.binary.StringUtils; - -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * The JWTDecoder class holds the decode method to parse a given JWT token into it's JWT representation. - */ -@SuppressWarnings("WeakerAccess") -public final class JWTDecoder implements DecodedJWT { - - private final String[] parts; - private final Header header; - private final Payload payload; - - public JWTDecoder(String jwt, EncodeType encodeType) throws Exception { - parts = TokenUtils.splitToken(jwt); - final JWTParser converter = new JWTParser(); - String headerJson = null; - String payloadJson = null; - switch (encodeType) { - case Base16: - headerJson = URLDecoder.decode(new String(Hex.decodeHex(parts[0])), "UTF-8"); - payloadJson = URLDecoder.decode(new String(Hex.decodeHex(parts[1])), "UTF-8"); - break; - case Base32: - Base32 base32 = new Base32(); - headerJson = URLDecoder.decode(new String(base32.decode(parts[0]), "UTF-8")); - payloadJson = URLDecoder.decode(new String(base32.decode(parts[1]), "UTF-8")); - break; - case Base64: - headerJson = StringUtils.newStringUtf8(Base64.decodeBase64(parts[0])); - payloadJson = StringUtils.newStringUtf8(Base64.decodeBase64(parts[1])); - break; - } - header = converter.parseHeader(headerJson); - payload = converter.parsePayload(payloadJson); - } - - @Override - public String getAlgorithm() { - return header.getAlgorithm(); - } - - @Override - public String getType() { - return header.getType(); - } - - @Override - public String getContentType() { - return header.getContentType(); - } - - @Override - public String getKeyId() { - return header.getKeyId(); - } - - @Override - public Claim getHeaderClaim(String name) { - return header.getHeaderClaim(name); - } - - @Override - public List getIssuer() { - return payload.getIssuer(); - } - - @Override - public List getSubject() { - return payload.getSubject(); - } - - @Override - public List getAudience() { - return payload.getAudience(); - } - - @Override - public Date getExpiresAt() { - return payload.getExpiresAt(); - } - - @Override - public Date getNotBefore() { - return payload.getNotBefore(); - } - - @Override - public Date getIssuedAt() { - return payload.getIssuedAt(); - } - - @Override - public String getId() { - return payload.getId(); - } - - @Override - public Claim getClaim(String name) { - return payload.getClaim(name); - } - - @Override - public Map getClaims() { - return payload.getClaims(); - } - - @Override - public String getHeader() { - return parts[0]; - } - - @Override - public String getPayload() { - return parts[1]; - } - - @Override - public String getSignature() { - return parts[2]; - } - - @Override - public String getToken() { - return String.format("%s.%s.%s", parts[0], parts[1], parts[2]); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/TokenUtils.java b/lib/src/main/java/com/auth0/jwt/TokenUtils.java deleted file mode 100644 index ed691be..0000000 --- a/lib/src/main/java/com/auth0/jwt/TokenUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.exceptions.JWTDecodeException; - -public abstract class TokenUtils { - - /** - * Splits the given token on the "." chars into a String array with 3 parts. - * - * @param token the string to split. - * @return the array representing the 3 parts of the token. - * @throws JWTDecodeException if the Token doesn't have 3 parts. - */ - public static String[] splitToken(String token) throws JWTDecodeException { - String[] parts = token.split("\\."); - if (parts.length == 2 && token.endsWith(".")) { - //Tokens with alg='none' have empty String as Signature. - parts = new String[]{parts[0], parts[1], ""}; - } - if (parts.length != 3) { - throw new JWTDecodeException(String.format("The token was expected to have 3 parts, but got %s.", parts.length)); - } - return parts; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java deleted file mode 100644 index a63c454..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import com.auth0.jwt.interfaces.RSAKeyProvider; - -import java.io.UnsupportedEncodingException; -import java.security.interfaces.*; - -/** - * The Algorithm class represents an algorithm to be used in the Signing or Verification process of a Token. - */ -@SuppressWarnings("WeakerAccess") -public abstract class Algorithm { - - private final String name; - private final String description; - - /** - * Creates a new Algorithm instance using SHA256withRSA. Tokens specify this as "RS256". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid RSA256 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - */ - public static Algorithm RSA256(RSAKeyProvider keyProvider) throws IllegalArgumentException { - return new RSAAlgorithm("RS256", "SHA256withRSA", keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA256withRSA. Tokens specify this as "RS256". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid RSA256 Algorithm. - * @throws IllegalArgumentException if both provided Keys are null. - */ - public static Algorithm RSA256(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException { - return RSA256(RSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA256withRSA. Tokens specify this as "RS256". - * - * @param key the key to use in the verify or signing instance. - * @return a valid RSA256 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - * @deprecated use {@link #RSA256(RSAPublicKey, RSAPrivateKey)} or {@link #RSA256(RSAKeyProvider)} - */ - @Deprecated - public static Algorithm RSA256(RSAKey key) throws IllegalArgumentException { - RSAPublicKey publicKey = key instanceof RSAPublicKey ? (RSAPublicKey) key : null; - RSAPrivateKey privateKey = key instanceof RSAPrivateKey ? (RSAPrivateKey) key : null; - return RSA256(publicKey, privateKey); - } - - /** - * Creates a new Algorithm instance using SHA384withRSA. Tokens specify this as "RS384". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid RSA384 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - */ - public static Algorithm RSA384(RSAKeyProvider keyProvider) throws IllegalArgumentException { - return new RSAAlgorithm("RS384", "SHA384withRSA", keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA384withRSA. Tokens specify this as "RS384". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid RSA384 Algorithm. - * @throws IllegalArgumentException if both provided Keys are null. - */ - public static Algorithm RSA384(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException { - return RSA384(RSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA384withRSA. Tokens specify this as "RS384". - * - * @param key the key to use in the verify or signing instance. - * @return a valid RSA384 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - * @deprecated use {@link #RSA384(RSAPublicKey, RSAPrivateKey)} or {@link #RSA384(RSAKeyProvider)} - */ - @Deprecated - public static Algorithm RSA384(RSAKey key) throws IllegalArgumentException { - RSAPublicKey publicKey = key instanceof RSAPublicKey ? (RSAPublicKey) key : null; - RSAPrivateKey privateKey = key instanceof RSAPrivateKey ? (RSAPrivateKey) key : null; - return RSA384(publicKey, privateKey); - } - - /** - * Creates a new Algorithm instance using SHA512withRSA. Tokens specify this as "RS512". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid RSA512 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - */ - public static Algorithm RSA512(RSAKeyProvider keyProvider) throws IllegalArgumentException { - return new RSAAlgorithm("RS512", "SHA512withRSA", keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA512withRSA. Tokens specify this as "RS512". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid RSA512 Algorithm. - * @throws IllegalArgumentException if both provided Keys are null. - */ - public static Algorithm RSA512(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException { - return RSA512(RSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA512withRSA. Tokens specify this as "RS512". - * - * @param key the key to use in the verify or signing instance. - * @return a valid RSA512 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - * @deprecated use {@link #RSA512(RSAPublicKey, RSAPrivateKey)} or {@link #RSA512(RSAKeyProvider)} - */ - @Deprecated - public static Algorithm RSA512(RSAKey key) throws IllegalArgumentException { - RSAPublicKey publicKey = key instanceof RSAPublicKey ? (RSAPublicKey) key : null; - RSAPrivateKey privateKey = key instanceof RSAPrivateKey ? (RSAPrivateKey) key : null; - return RSA512(publicKey, privateKey); - } - - /** - * Creates a new Algorithm instance using HmacSHA256. Tokens specify this as "HS256". - * - * @param secret the secret to use in the verify or signing instance. - * @return a valid HMAC256 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - * @throws UnsupportedEncodingException if the current Java platform implementation doesn't support the UTF-8 character encoding. - */ - public static Algorithm HMAC256(String secret) throws IllegalArgumentException, UnsupportedEncodingException { - return new HMACAlgorithm("HS256", "HmacSHA256", secret); - } - - /** - * Creates a new Algorithm instance using HmacSHA384. Tokens specify this as "HS384". - * - * @param secret the secret to use in the verify or signing instance. - * @return a valid HMAC384 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - * @throws UnsupportedEncodingException if the current Java platform implementation doesn't support the UTF-8 character encoding. - */ - public static Algorithm HMAC384(String secret) throws IllegalArgumentException, UnsupportedEncodingException { - return new HMACAlgorithm("HS384", "HmacSHA384", secret); - } - - /** - * Creates a new Algorithm instance using HmacSHA512. Tokens specify this as "HS512". - * - * @param secret the secret to use in the verify or signing instance. - * @return a valid HMAC512 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - * @throws UnsupportedEncodingException if the current Java platform implementation doesn't support the UTF-8 character encoding. - */ - public static Algorithm HMAC512(String secret) throws IllegalArgumentException, UnsupportedEncodingException { - return new HMACAlgorithm("HS512", "HmacSHA512", secret); - } - - /** - * Creates a new Algorithm instance using HmacSHA256. Tokens specify this as "HS256". - * - * @param secret the secret bytes to use in the verify or signing instance. - * @return a valid HMAC256 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - */ - public static Algorithm HMAC256(byte[] secret) throws IllegalArgumentException { - return new HMACAlgorithm("HS256", "HmacSHA256", secret); - } - - /** - * Creates a new Algorithm instance using HmacSHA384. Tokens specify this as "HS384". - * - * @param secret the secret bytes to use in the verify or signing instance. - * @return a valid HMAC384 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - */ - public static Algorithm HMAC384(byte[] secret) throws IllegalArgumentException { - return new HMACAlgorithm("HS384", "HmacSHA384", secret); - } - - /** - * Creates a new Algorithm instance using HmacSHA512. Tokens specify this as "HS512". - * - * @param secret the secret bytes to use in the verify or signing instance. - * @return a valid HMAC512 Algorithm. - * @throws IllegalArgumentException if the provided Secret is null. - */ - public static Algorithm HMAC512(byte[] secret) throws IllegalArgumentException { - return new HMACAlgorithm("HS512", "HmacSHA512", secret); - } - - /** - * Creates a new Algorithm instance using SHA256withECDSA. Tokens specify this as "ES256". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid ECDSA256 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - */ - public static Algorithm ECDSA256(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { - return new ECDSAAlgorithm("ES256", "SHA256withECDSA", 32, keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA256withECDSA. Tokens specify this as "ES256". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid ECDSA256 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - */ - public static Algorithm ECDSA256(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException { - return ECDSA256(ECDSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA256withECDSA. Tokens specify this as "ES256". - * - * @param key the key to use in the verify or signing instance. - * @return a valid ECDSA256 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - * @deprecated use {@link #ECDSA256(ECPublicKey, ECPrivateKey)} or {@link #ECDSA256(ECDSAKeyProvider)} - */ - @Deprecated - public static Algorithm ECDSA256(ECKey key) throws IllegalArgumentException { - ECPublicKey publicKey = key instanceof ECPublicKey ? (ECPublicKey) key : null; - ECPrivateKey privateKey = key instanceof ECPrivateKey ? (ECPrivateKey) key : null; - return ECDSA256(publicKey, privateKey); - } - - /** - * Creates a new Algorithm instance using SHA384withECDSA. Tokens specify this as "ES384". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid ECDSA384 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - */ - public static Algorithm ECDSA384(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { - return new ECDSAAlgorithm("ES384", "SHA384withECDSA", 48, keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA384withECDSA. Tokens specify this as "ES384". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid ECDSA384 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - */ - public static Algorithm ECDSA384(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException { - return ECDSA384(ECDSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA384withECDSA. Tokens specify this as "ES384". - * - * @param key the key to use in the verify or signing instance. - * @return a valid ECDSA384 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - * @deprecated use {@link #ECDSA384(ECPublicKey, ECPrivateKey)} or {@link #ECDSA384(ECDSAKeyProvider)} - */ - @Deprecated - public static Algorithm ECDSA384(ECKey key) throws IllegalArgumentException { - ECPublicKey publicKey = key instanceof ECPublicKey ? (ECPublicKey) key : null; - ECPrivateKey privateKey = key instanceof ECPrivateKey ? (ECPrivateKey) key : null; - return ECDSA384(publicKey, privateKey); - } - - /** - * Creates a new Algorithm instance using SHA512withECDSA. Tokens specify this as "ES512". - * - * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. - * @return a valid ECDSA512 Algorithm. - * @throws IllegalArgumentException if the Key Provider is null. - */ - public static Algorithm ECDSA512(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { - return new ECDSAAlgorithm("ES512", "SHA512withECDSA", 66, keyProvider); - } - - /** - * Creates a new Algorithm instance using SHA512withECDSA. Tokens specify this as "ES512". - * - * @param publicKey the key to use in the verify instance. - * @param privateKey the key to use in the signing instance. - * @return a valid ECDSA512 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - */ - public static Algorithm ECDSA512(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException { - return ECDSA512(ECDSAAlgorithm.providerForKeys(publicKey, privateKey)); - } - - /** - * Creates a new Algorithm instance using SHA512withECDSA. Tokens specify this as "ES512". - * - * @param key the key to use in the verify or signing instance. - * @return a valid ECDSA512 Algorithm. - * @throws IllegalArgumentException if the provided Key is null. - * @deprecated use {@link #ECDSA512(ECPublicKey, ECPrivateKey)} or {@link #ECDSA512(ECDSAKeyProvider)} - */ - @Deprecated - public static Algorithm ECDSA512(ECKey key) throws IllegalArgumentException { - ECPublicKey publicKey = key instanceof ECPublicKey ? (ECPublicKey) key : null; - ECPrivateKey privateKey = key instanceof ECPrivateKey ? (ECPrivateKey) key : null; - return ECDSA512(publicKey, privateKey); - } - - - public static Algorithm none() { - return new NoneAlgorithm(); - } - - protected Algorithm(String name, String description) { - this.name = name; - this.description = description; - } - - /** - * Getter for the Id of the Private Key used to sign the tokens. This is usually specified as the `kid` claim in the Header. - * - * @return the Key Id that identifies the Signing Key or null if it's not specified. - */ - public String getSigningKeyId() { - return null; - } - - /** - * Getter for the name of this Algorithm, as defined in the JWT Standard. i.e. "HS256" - * - * @return the algorithm name. - */ - public String getName() { - return name; - } - - /** - * Getter for the description of this Algorithm, required when instantiating a Mac or Signature object. i.e. "HmacSHA256" - * - * @return the algorithm description. - */ - String getDescription() { - return description; - } - - @Override - public String toString() { - return description; - } - - /** - * Verify the given token using this Algorithm instance. - * - * @param jwt the already decoded JWT that it's going to be verified. - * @throws SignatureVerificationException if the Token's Signature is invalid, meaning that it doesn't match the signatureBytes, or if the Key is invalid. - */ - public abstract void verify(DecodedJWT jwt, EncodeType encodeType) throws Exception; - - /** - * Sign the given content using this Algorithm instance. - * - * @param contentBytes an array of bytes representing the base64 encoded content to be verified against the signature. - * @return the signature in a base64 encoded array of bytes - * @throws SignatureGenerationException if the Key is invalid. - */ - public abstract byte[] sign(byte[] contentBytes) throws SignatureGenerationException; - - @Override - public boolean equals(Object algorithmParam) { - if(this == algorithmParam) - return true; - if(algorithmParam == null) - return false; - if(getClass() != algorithmParam.getClass()) - return false; - - Algorithm algorithm = (Algorithm) algorithmParam; - return this.description.equals(algorithm.description) && this.name.equals(algorithm.name); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/CryptoHelper.java b/lib/src/main/java/com/auth0/jwt/algorithms/CryptoHelper.java deleted file mode 100644 index 43b6f82..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/CryptoHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.security.*; - -class CryptoHelper { - - boolean verifySignatureFor(String algorithm, byte[] secretBytes, byte[] contentBytes, byte[] signatureBytes) throws NoSuchAlgorithmException, InvalidKeyException { - return MessageDigest.isEqual(createSignatureFor(algorithm, secretBytes, contentBytes), signatureBytes); - } - - byte[] createSignatureFor(String algorithm, byte[] secretBytes, byte[] contentBytes) throws NoSuchAlgorithmException, InvalidKeyException { - final Mac mac = Mac.getInstance(algorithm); - mac.init(new SecretKeySpec(secretBytes, algorithm)); - return mac.doFinal(contentBytes); - } - - boolean verifySignatureFor(String algorithm, PublicKey publicKey, byte[] contentBytes, byte[] signatureBytes) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { - final Signature s = Signature.getInstance(algorithm); - s.initVerify(publicKey); - s.update(contentBytes); - return s.verify(signatureBytes); - } - - byte[] createSignatureFor(String algorithm, PrivateKey privateKey, byte[] contentBytes) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { - final Signature s = Signature.getInstance(algorithm); - s.initSign(privateKey); - s.update(contentBytes); - return s.sign(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/ECDSAAlgorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/ECDSAAlgorithm.java deleted file mode 100644 index 91a7fef..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/ECDSAAlgorithm.java +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.binary.StringUtils; - -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SignatureException; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; - -class ECDSAAlgorithm extends Algorithm { - - private final ECDSAKeyProvider keyProvider; - private final CryptoHelper crypto; - private final int ecNumberSize; - - //Visible for testing - ECDSAAlgorithm(CryptoHelper crypto, String id, String algorithm, int ecNumberSize, ECDSAKeyProvider keyProvider) throws IllegalArgumentException { - super(id, algorithm); - if (keyProvider == null) { - throw new IllegalArgumentException("The Key Provider cannot be null."); - } - this.keyProvider = keyProvider; - this.crypto = crypto; - this.ecNumberSize = ecNumberSize; - } - - ECDSAAlgorithm(String id, String algorithm, int ecNumberSize, ECDSAKeyProvider keyProvider) throws IllegalArgumentException { - this(new CryptoHelper(), id, algorithm, ecNumberSize, keyProvider); - } - - @Override - public void verify(DecodedJWT jwt, EncodeType encodeType) throws Exception { - byte[] contentBytes = String.format("%s.%s", jwt.getHeader(), jwt.getPayload()).getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = null; - String signature = jwt.getSignature(); - String urlDecoded = null; - switch (encodeType) { - case Base16: - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = Hex.decodeHex(urlDecoded); - break; - case Base32: - Base32 base32 = new Base32(); - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = base32.decode(urlDecoded); - break; - case Base64: - signatureBytes = Base64.decodeBase64(signature); - break; - } - - try { - ECPublicKey publicKey = keyProvider.getPublicKeyById(jwt.getKeyId()); - if (publicKey == null) { - throw new IllegalStateException("The given Public Key is null."); - } - boolean valid = crypto.verifySignatureFor(getDescription(), publicKey, contentBytes, JOSEToDER(signatureBytes)); - - if (!valid) { - throw new SignatureVerificationException(this); - } - } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalStateException e) { - throw new SignatureVerificationException(this, e); - } - } - - @Override - public byte[] sign(byte[] contentBytes) throws SignatureGenerationException { - try { - ECPrivateKey privateKey = keyProvider.getPrivateKey(); - if (privateKey == null) { - throw new IllegalStateException("The given Private Key is null."); - } - byte[] signature = crypto.createSignatureFor(getDescription(), privateKey, contentBytes); - return DERToJOSE(signature); - } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalStateException e) { - throw new SignatureGenerationException(this, e); - } - } - - @Override - public String getSigningKeyId() { - return keyProvider.getPrivateKeyId(); - } - - //Visible for testing - byte[] DERToJOSE(byte[] derSignature) throws SignatureException { - // DER Structure: http://crypto.stackexchange.com/a/1797 - boolean derEncoded = derSignature[0] == 0x30 && derSignature.length != ecNumberSize * 2; - if (!derEncoded) { - throw new SignatureException("Invalid DER signature format."); - } - - final byte[] joseSignature = new byte[ecNumberSize * 2]; - - //Skip 0x30 - int offset = 1; - if (derSignature[1] == (byte) 0x81) { - //Skip sign - offset++; - } - - //Convert to unsigned. Should match DER length - offset - int encodedLength = derSignature[offset++] & 0xff; - if (encodedLength != derSignature.length - offset) { - throw new SignatureException("Invalid DER signature format."); - } - - //Skip 0x02 - offset++; - - //Obtain R number length (Includes padding) and skip it - int rLength = derSignature[offset++]; - if (rLength > ecNumberSize + 1) { - throw new SignatureException("Invalid DER signature format."); - } - int rPadding = ecNumberSize - rLength; - //Retrieve R number - System.arraycopy(derSignature, offset + Math.max(-rPadding, 0), joseSignature, Math.max(rPadding, 0), rLength + Math.min(rPadding, 0)); - - //Skip R number and 0x02 - offset += rLength + 1; - - //Obtain S number length. (Includes padding) - int sLength = derSignature[offset++]; - if (sLength > ecNumberSize + 1) { - throw new SignatureException("Invalid DER signature format."); - } - int sPadding = ecNumberSize - sLength; - //Retrieve R number - System.arraycopy(derSignature, offset + Math.max(-sPadding, 0), joseSignature, ecNumberSize + Math.max(sPadding, 0), sLength + Math.min(sPadding, 0)); - - return joseSignature; - } - - //Visible for testing - byte[] JOSEToDER(byte[] joseSignature) throws SignatureException { - if (joseSignature.length != ecNumberSize * 2) { - throw new SignatureException("Invalid JOSE signature format."); - } - - // Retrieve R and S number's length and padding. - int rPadding = countPadding(joseSignature, 0, ecNumberSize); - int sPadding = countPadding(joseSignature, ecNumberSize, joseSignature.length); - int rLength = ecNumberSize - rPadding; - int sLength = ecNumberSize - sPadding; - - int length = 2 + rLength + 2 + sLength; - if (length > 255) { - throw new SignatureException("Invalid JOSE signature format."); - } - - final byte[] derSignature; - int offset; - if (length > 0x7f) { - derSignature = new byte[3 + length]; - derSignature[1] = (byte) 0x81; - offset = 2; - } else { - derSignature = new byte[2 + length]; - offset = 1; - } - - // DER Structure: http://crypto.stackexchange.com/a/1797 - // Header with signature length info - derSignature[0] = (byte) 0x30; - derSignature[offset++] = (byte) (length & 0xff); - - // Header with "min R" number length - derSignature[offset++] = (byte) 0x02; - derSignature[offset++] = (byte) rLength; - - // R number - if (rPadding < 0) { - //Sign - derSignature[offset++] = (byte) 0x00; - System.arraycopy(joseSignature, 0, derSignature, offset, ecNumberSize); - offset += ecNumberSize; - } else { - int copyLength = Math.min(ecNumberSize, rLength); - System.arraycopy(joseSignature, rPadding, derSignature, offset, copyLength); - offset += copyLength; - } - - // Header with "min S" number length - derSignature[offset++] = (byte) 0x02; - derSignature[offset++] = (byte) sLength; - - // S number - if (sPadding < 0) { - //Sign - derSignature[offset++] = (byte) 0x00; - System.arraycopy(joseSignature, ecNumberSize, derSignature, offset, ecNumberSize); - } else { - System.arraycopy(joseSignature, ecNumberSize + sPadding, derSignature, offset, Math.min(ecNumberSize, sLength)); - } - - return derSignature; - } - - private int countPadding(byte[] bytes, int fromIndex, int toIndex) { - int padding = 0; - while (fromIndex + padding < toIndex && bytes[fromIndex + padding] == 0) { - padding++; - } - return (bytes[fromIndex + padding] & 0xff) > 0x7f ? padding - 1 : padding; - } - - //Visible for testing - static ECDSAKeyProvider providerForKeys(final ECPublicKey publicKey, final ECPrivateKey privateKey) { - if (publicKey == null && privateKey == null) { - throw new IllegalArgumentException("Both provided Keys cannot be null."); - } - return new ECDSAKeyProvider() { - @Override - public ECPublicKey getPublicKeyById(String keyId) { - return publicKey; - } - - @Override - public ECPrivateKey getPrivateKey() { - return privateKey; - } - - @Override - public String getPrivateKeyId() { - return null; - } - }; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/HMACAlgorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/HMACAlgorithm.java deleted file mode 100644 index b7ee04a..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/HMACAlgorithm.java +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.creators.JWTCreator; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import org.apache.commons.codec.CharEncoding; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.binary.StringUtils; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -class HMACAlgorithm extends Algorithm { - - private final CryptoHelper crypto; - private final byte[] secret; - - //Visible for testing - HMACAlgorithm(CryptoHelper crypto, String id, String algorithm, byte[] secretBytes) throws IllegalArgumentException { - super(id, algorithm); - if (secretBytes == null) { - throw new IllegalArgumentException("The Secret cannot be null"); - } - this.secret = secretBytes; - this.crypto = crypto; - } - - HMACAlgorithm(String id, String algorithm, byte[] secretBytes) throws IllegalArgumentException { - this(new CryptoHelper(), id, algorithm, secretBytes); - } - - HMACAlgorithm(String id, String algorithm, String secret) throws IllegalArgumentException, UnsupportedEncodingException { - this(new CryptoHelper(), id, algorithm, getSecretBytes(secret)); - } - - //Visible for testing - static byte[] getSecretBytes(String secret) throws IllegalArgumentException, UnsupportedEncodingException { - if (secret == null) { - throw new IllegalArgumentException("The Secret cannot be null"); - } - return secret.getBytes(CharEncoding.UTF_8); - } - - @Override - public void verify(DecodedJWT jwt, EncodeType encodeType) throws Exception { - byte[] contentBytes = String.format("%s.%s", jwt.getHeader(), jwt.getPayload()).getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = null; - String signature = jwt.getSignature(); - String urlDecoded = null; - switch (encodeType) { - case Base16: - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = Hex.decodeHex(urlDecoded); - break; - case Base32: - Base32 base32 = new Base32(); - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = base32.decode(urlDecoded); - break; - case Base64: - signatureBytes = Base64.decodeBase64(signature); - break; - } - - try { - boolean valid = crypto.verifySignatureFor(getDescription(), secret, contentBytes, signatureBytes); - if (!valid) { - throw new SignatureVerificationException(this); - } - } catch (IllegalStateException | InvalidKeyException | NoSuchAlgorithmException e) { - throw new SignatureVerificationException(this, e); - } - } - - @Override - public byte[] sign(byte[] contentBytes) throws SignatureGenerationException { - try { - return crypto.createSignatureFor(getDescription(), secret, contentBytes); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new SignatureGenerationException(this, e); - } - } - -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/NoneAlgorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/NoneAlgorithm.java deleted file mode 100644 index 5c7e23a..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/NoneAlgorithm.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; - -import java.net.URLDecoder; - -class NoneAlgorithm extends Algorithm { - - NoneAlgorithm() { - super("none", "none"); - } - - @Override - public void verify(DecodedJWT jwt, EncodeType encodeType) throws Exception { - byte[] signatureBytes = null; - String signature = jwt.getSignature(); - String urlDecoded = null; - switch (encodeType) { - case Base16: - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = Hex.decodeHex(urlDecoded); - break; - case Base32: - Base32 base32 = new Base32(); - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = base32.decode(urlDecoded); - break; - case Base64: - signatureBytes = Base64.decodeBase64(signature); - break; - } - if (signatureBytes.length > 0) { - throw new SignatureVerificationException(this); - } - } - - @Override - public byte[] sign(byte[] contentBytes) throws SignatureGenerationException { - return new byte[0]; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/RSAAlgorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/RSAAlgorithm.java deleted file mode 100644 index bc312a2..0000000 --- a/lib/src/main/java/com/auth0/jwt/algorithms/RSAAlgorithm.java +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.RSAKeyProvider; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; - -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SignatureException; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; - -class RSAAlgorithm extends Algorithm { - - private final RSAKeyProvider keyProvider; - private final CryptoHelper crypto; - - //Visible for testing - RSAAlgorithm(CryptoHelper crypto, String id, String algorithm, RSAKeyProvider keyProvider) throws IllegalArgumentException { - super(id, algorithm); - if (keyProvider == null) { - throw new IllegalArgumentException("The Key Provider cannot be null."); - } - this.keyProvider = keyProvider; - this.crypto = crypto; - } - - RSAAlgorithm(String id, String algorithm, RSAKeyProvider keyProvider) throws IllegalArgumentException { - this(new CryptoHelper(), id, algorithm, keyProvider); - } - - @Override - public void verify(DecodedJWT jwt, EncodeType encodeType) throws Exception { - byte[] contentBytes = String.format("%s.%s", jwt.getHeader(), jwt.getPayload()).getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = null; - String signature = jwt.getSignature(); - String urlDecoded = null; - switch (encodeType) { - case Base16: - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = Hex.decodeHex(urlDecoded); - break; - case Base32: - Base32 base32 = new Base32(); - urlDecoded = URLDecoder.decode(signature, "UTF-8"); - signatureBytes = base32.decode(urlDecoded); - break; - case Base64: - signatureBytes = Base64.decodeBase64(signature); - break; - } - - try { - RSAPublicKey publicKey = keyProvider.getPublicKeyById(jwt.getKeyId()); - if (publicKey == null) { - throw new IllegalStateException("The given Public Key is null."); - } - boolean valid = crypto.verifySignatureFor(getDescription(), publicKey, contentBytes, signatureBytes); - if (!valid) { - throw new SignatureVerificationException(this); - } - } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalStateException e) { - throw new SignatureVerificationException(this, e); - } - } - - @Override - public byte[] sign(byte[] contentBytes) throws SignatureGenerationException { - try { - RSAPrivateKey privateKey = keyProvider.getPrivateKey(); - if (privateKey == null) { - throw new IllegalStateException("The given Private Key is null."); - } - return crypto.createSignatureFor(getDescription(), privateKey, contentBytes); - } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalStateException e) { - throw new SignatureGenerationException(this, e); - } - } - - @Override - public String getSigningKeyId() { - return keyProvider.getPrivateKeyId(); - } - - //Visible for testing - static RSAKeyProvider providerForKeys(final RSAPublicKey publicKey, final RSAPrivateKey privateKey) { - if (publicKey == null && privateKey == null) { - throw new IllegalArgumentException("Both provided Keys cannot be null."); - } - return new RSAKeyProvider() { - @Override - public RSAPublicKey getPublicKeyById(String keyId) { - return publicKey; - } - - @Override - public RSAPrivateKey getPrivateKey() { - return privateKey; - } - - @Override - public String getPrivateKeyId() { - return null; - } - }; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/AccessJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/AccessJwtCreator.java deleted file mode 100644 index 4b126c4..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/AccessJwtCreator.java +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The AccessJwtCreator class holds the sign method to generate a complete Access JWT (with Signature) from a given Header and Payload content. - */ -public class AccessJwtCreator { - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public AccessJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("Issuer", false); - put("Subject", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUER); - add(PublicClaims.SUBJECT); - add(PublicClaims.EXPIRES_AT); - add(PublicClaims.NOT_BEFORE); - add(PublicClaims.ISSUED_AT); - add(PublicClaims.JWT_ID); - add(PublicClaims.AUDIENCE); - }}; - } - - /** - * Add a specific Issuer ("issuer") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public AccessJwtCreator withIssuer(String... issuer) { - jwt.withIssuer(issuer); - addedClaims.put("Issuer", true); - return this; - } - - /** - * Add a specific Subject ("subject") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public AccessJwtCreator withSubject(String... subject) { - jwt.withSubject(subject); - addedClaims.put("Subject", true); - return this; - } - - /** - * Add a specific Audience ("audience") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public AccessJwtCreator withAudience(String... audience) { - jwt.withAudience(audience); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public AccessJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param exp the Expires At value. - * @return this same Builder instance. - */ - public AccessJwtCreator withExp(Date exp) { - jwt.withExpiresAt(exp); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public AccessJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public AccessJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static AccessJwtCreator build() { - return new AccessJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/EncodeType.java b/lib/src/main/java/com/auth0/jwt/creators/EncodeType.java deleted file mode 100644 index 9a4bd4d..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/EncodeType.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -public enum EncodeType { - Base16, Base32, Base64, JsonEncode; -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/ExtendedJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/ExtendedJwtCreator.java deleted file mode 100644 index 18e6917..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/ExtendedJwtCreator.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; - -import java.util.Date; - -/** - * The ExtendedJwtCreator class holds the sign method to generate a complete Extended JWT (with Signature) from a given Header and Payload content. - */ -public class ExtendedJwtCreator extends GoogleJwtCreator{ - - public ExtendedJwtCreator() { - super(); - } - - /** - * Add a specific Note Before ("nbf") claim to the Payload. - * - * @param nbf the nbf value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withNbf(Date nbf) { - jwt.withNotBefore(nbf); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static ExtendedJwtCreator build() { - return new ExtendedJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/FbJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/FbJwtCreator.java deleted file mode 100644 index e4ff44e..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/FbJwtCreator.java +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The FbJwtCreator class holds the sign method to generate a complete FB JWT (with Signature) from a given Header and Payload content. - */ -public class FbJwtCreator { - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public FbJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("UserId", false); - put("AppId", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUED_AT); - add(PublicClaims.EXPIRES_AT); - }}; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public FbJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param exp the Expires At value. - * @return this same Builder instance. - */ - public FbJwtCreator withExp(Date exp) { - jwt.withExpiresAt(exp); - return this; - } - - /** - * Require a specific userId ("userId") claim. - * - * @param userId the required userId value - * @return this same Verification instance. - */ - public FbJwtCreator withUserId(String userId) { - jwt.withNonStandardClaim("userId", userId); - addedClaims.put("UserId", true); - return this; - } - - /** - * Require a specific appId ("appId") claim. - * - * @param appId the required appId value - * @return this same Verification instance. - */ - public FbJwtCreator withAppId(String appId) { - jwt.withNonStandardClaim("appId", appId); - addedClaims.put("AppId", true); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public FbJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public FbJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static FbJwtCreator build() { - return new FbJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/GoogleJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/GoogleJwtCreator.java deleted file mode 100644 index ffd9e66..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/GoogleJwtCreator.java +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The GoogleJwtCreator class holds the sign method to generate a complete Google JWT (with Signature) from a given Header and Payload content. - */ -public class GoogleJwtCreator { - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public GoogleJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("Name", false); - put("Email", false); - put("Picture", false); - put("Issuer", false); - put("Subject", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUER); - add(PublicClaims.SUBJECT); - add(PublicClaims.EXPIRES_AT); - add(PublicClaims.NOT_BEFORE); - add(PublicClaims.ISSUED_AT); - add(PublicClaims.JWT_ID); - add(PublicClaims.AUDIENCE); - }}; - } - - - /** - * Add a specific Name ("name") claim to the Payload. - * - * @param name the Name value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withName(String name) { - jwt.withNonStandardClaim("name", name); - addedClaims.put("Name", true); - return this; - } - - /** - * Add a specific Email ("email") claim to the Payload. - * - * @param email the Email value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withEmail(String email) { - jwt.withNonStandardClaim("email", email); - addedClaims.put("Email", true); - return this; - } - - /** - * Add a specific Picture ("picture") claim to the Payload. - * - * @param picture the Picture value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withPicture(String picture) { - jwt.withNonStandardClaim("picture", picture); - addedClaims.put("Picture", true); - return this; - } - - /** - * Add a specific Issuer ("issuer") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withIssuer(String... issuer) { - jwt.withIssuer(issuer); - addedClaims.put("Issuer", true); - return this; - } - - /** - * Add a specific Subject ("subject") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withSubject(String... subject) { - jwt.withSubject(subject); - addedClaims.put("Subject", true); - return this; - } - - /** - * Add a specific Audience ("audience") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withAudience(String... audience) { - jwt.withAudience(audience); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param exp the Expires At value. - * @return this same Builder instance. - */ - public GoogleJwtCreator withExp(Date exp) { - jwt.withExpiresAt(exp); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public GoogleJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public GoogleJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static GoogleJwtCreator build() { - return new GoogleJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/ImplicitJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/ImplicitJwtCreator.java deleted file mode 100644 index 0130e4e..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/ImplicitJwtCreator.java +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The ImplicitJwtCreator class holds the sign method to generate a complete Implicit JWT (with Signature) from a given Header and Payload content. - */ -public class ImplicitJwtCreator { - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public ImplicitJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("Issuer", false); - put("Subject", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUER); - add(PublicClaims.SUBJECT); - add(PublicClaims.ISSUED_AT); - add(PublicClaims.AUDIENCE); - }}; - } - - /** - * Add a specific Issuer ("issuer") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public ImplicitJwtCreator withIssuer(String... issuer) { - jwt.withIssuer(issuer); - addedClaims.put("Issuer", true); - return this; - } - - /** - * Add a specific Subject ("subject") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public ImplicitJwtCreator withSubject(String... subject) { - jwt.withSubject(subject); - addedClaims.put("Subject", true); - return this; - } - - /** - * Add a specific Audience ("audience") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public ImplicitJwtCreator withAudience(String... audience) { - jwt.withAudience(audience); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public ImplicitJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public ImplicitJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public ImplicitJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static ImplicitJwtCreator build() { - return new ImplicitJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/JWTCreator.java b/lib/src/main/java/com/auth0/jwt/creators/JWTCreator.java deleted file mode 100644 index 54e4f13..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/JWTCreator.java +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.impl.ClaimsHolder; -import com.auth0.jwt.impl.PayloadSerializer; -import com.auth0.jwt.impl.PublicClaims; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import org.apache.commons.codec.Encoder; -import org.apache.commons.codec.binary.Base32; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.binary.StringUtils; - -import java.io.*; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * The JWTCreator class holds the sign method to generate a complete JWT (with Signature) from a given Header and Payload content. - */ -@SuppressWarnings("WeakerAccess") -public final class JWTCreator { - - private final Algorithm algorithm; - private final String headerJson; - private final String payloadJson; - - private JWTCreator(Algorithm algorithm, Map headerClaims, Map payloadClaims) throws JWTCreationException { - this.algorithm = algorithm; - try { - ObjectMapper mapper = new ObjectMapper(); - SimpleModule module = new SimpleModule(); - module.addSerializer(ClaimsHolder.class, new PayloadSerializer()); - mapper.registerModule(module); - mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true); - headerJson = mapper.writeValueAsString(headerClaims); - payloadJson = mapper.writeValueAsString(new ClaimsHolder(payloadClaims)); - } catch (JsonProcessingException e) { - throw new JWTCreationException("Some of the Claims couldn't be converted to a valid JSON format.", e); - } - } - - - /** - * Initialize a JWTCreator instance. - * - * @return a JWTCreator.Builder instance to configure. - */ - public static JWTCreator.Builder init() { - return new Builder(); - } - - /** - * The Builder class holds the Claims that defines the JWT to be created. - */ - public static class Builder { - private final Map payloadClaims; - private Map headerClaims; - private boolean isNoneAlgorithmAllowed; - - Builder() { - this.payloadClaims = new HashMap<>(); - this.headerClaims = new HashMap<>(); - this.isNoneAlgorithmAllowed = false; - } - - /** - * Add specific Claims to set as the Header. - * - * @param headerClaims the values to use as Claims in the token's Header. - * @return this same Builder instance. - */ - public Builder withHeader(Map headerClaims) { - this.headerClaims = new HashMap<>(headerClaims); - return this; - } - - /** - * Add a specific Key Id ("kid") claim to the Header. - * If the {@link Algorithm} used to sign this token was instantiated with a KeyProvider, the 'kid' value will be taken from that provider and this one will be ignored. - * - * @param keyId the Key Id value. - * @return this same Builder instance. - */ - public Builder withKeyId(String keyId) { - this.headerClaims.put(PublicClaims.KEY_ID, keyId); - return this; - } - - /** - * Add a specific Issuer ("iss") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public Builder withIssuer(String... issuer) { - addClaim(PublicClaims.ISSUER, issuer); - return this; - } - - /** - * Add a specific Subject ("sub") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public Builder withSubject(String... subject) { - addClaim(PublicClaims.SUBJECT, subject); - return this; - } - - /** - * Add a specific Audience ("aud") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public Builder withAudience(String... audience) { - addClaim(PublicClaims.AUDIENCE, audience); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param expiresAt the Expires At value. - * @return this same Builder instance. - */ - public Builder withExpiresAt(Date expiresAt) { - addClaim(PublicClaims.EXPIRES_AT, expiresAt); - return this; - } - - /** - * Add a specific Not Before ("nbf") claim to the Payload. - * - * @param notBefore the Not Before value. - * @return this same Builder instance. - */ - public Builder withNotBefore(Date notBefore) { - addClaim(PublicClaims.NOT_BEFORE, notBefore); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param issuedAt the Issued At value. - * @return this same Builder instance. - */ - public Builder withIssuedAt(Date issuedAt) { - addClaim(PublicClaims.ISSUED_AT, issuedAt); - return this; - } - - /** - * Add a specific JWT Id ("jti") claim to the Payload. - * - * @param jwtId the Token Id value. - * @return this same Builder instance. - */ - public Builder withJWTId(String jwtId) { - addClaim(PublicClaims.JWT_ID, jwtId); - return this; - } - - /** - * Developer specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public Builder setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - this.isNoneAlgorithmAllowed = isNoneAlgorithmAllowed; - return this; - } - - public boolean getIsNoneAlgorithmAllowed() { - return this.isNoneAlgorithmAllowed; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, String value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, value); - return this; - } - - /** - * Add a custom Array Claim with the given items. - * - * @param name the Claim's name. - * @param items the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withArrayClaim(String name, String[] items) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, items); - return this; - } - - /** - * Add a custom Array Claim with the given items. - * - * @param name the Claim's name. - * @param items the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withArrayClaim(String name, Integer[] items) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, items); - return this; - } - - /** - * Add a custom Array Claim with the given items. - * - * @param name the Claim's name. - * @param items the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public Builder withArrayClaim(String name, Long[] items) throws IllegalArgumentException { - assertNonNull(name); - addClaim(name, items); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm - * Defaults to Base64 encoding - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception{ - return sign(algorithm, EncodeType.Base64); - } - - /** - * Creates a new JWT and signs it with the given algorithm - * - * @param algorithm used to sign the JWT - * @param encodeType specifies which base encoding is required - * @return a new JWT token - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm, EncodeType encodeType) throws Exception { - if (algorithm == null) { - throw new IllegalArgumentException("The Algorithm cannot be null."); - } - if(encodeType == null) { - throw new IllegalArgumentException("Encodetype cannot be null."); - } - headerClaims.put(PublicClaims.ALGORITHM, algorithm.getName()); - headerClaims.put(PublicClaims.TYPE, "JWT"); - String signingKeyId = algorithm.getSigningKeyId(); - if (signingKeyId != null) { - withKeyId(signingKeyId); - } - JWTCreator jwtCreator = new JWTCreator(algorithm, headerClaims, payloadClaims); - String token = null; - switch (encodeType) { - case Base16: - token = jwtCreator.signBase16Encoding(); - break; - case Base32: - token = jwtCreator.signBase32Encoding(); - break; - case Base64: - token = jwtCreator.defaultSign(); - break; - } - - return token; - } - - protected void assertNonNull(String name) { - if (name == null) { - throw new IllegalArgumentException("The Custom Claim's name can't be null."); - } - } - - private void addClaim(String name, Object value) { - if (value == null) { - payloadClaims.remove(name); - return; - } - payloadClaims.put(name, value); - } - } - - private String signBase16Encoding() throws UnsupportedEncodingException { - String header = URLEncoder.encode(headerJson, "UTF-8"); - String payload = URLEncoder.encode(payloadJson, "UTF-8"); - - byte[] bHeader = header.getBytes("UTF-8"); - String encodedHeader = Hex.encodeHexString(bHeader); - - byte[] bPayload = payload.getBytes("UTF-8"); - String encodedPayload = Hex.encodeHexString(bPayload); - - String content = String.format("%s.%s", encodedHeader, encodedPayload); - byte[] signatureBytes = algorithm.sign(content.getBytes(StandardCharsets.UTF_8)); - String signature = Hex.encodeHexString(signatureBytes); - String signatureFinal = URLEncoder.encode(signature, "UTF-8"); - - return String.format("%s.%s", content, signatureFinal); - } - - private String signBase32Encoding() throws UnsupportedEncodingException{ - Base32 base32 = new Base32(); - String header = URLEncoder.encode(headerJson, "UTF-8"); - String payload = URLEncoder.encode(payloadJson, "UTF-8"); - - byte[] bHeader = header.getBytes("UTF-8"); - String encodedHeader = base32.encodeAsString(bHeader); - - byte[] bPayload = payload.getBytes("UTF-8"); - String encodedPayload = base32.encodeAsString(bPayload); - - String content = String.format("%s.%s", encodedHeader, encodedPayload); - byte[] signatureBytes = algorithm.sign(content.getBytes(StandardCharsets.UTF_8)); - String signature = base32.encodeAsString(signatureBytes); - String signatureFinal = URLEncoder.encode(signature, "UTF-8"); - - return String.format("%s.%s", content, signatureFinal); - } - - private String defaultSign() throws SignatureGenerationException { - String header = Base64.encodeBase64URLSafeString(headerJson.getBytes(StandardCharsets.UTF_8)); - String payload = Base64.encodeBase64URLSafeString(payloadJson.getBytes(StandardCharsets.UTF_8)); - String content = String.format("%s.%s", header, payload); - - byte[] signatureBytes = algorithm.sign(content.getBytes(StandardCharsets.UTF_8)); - String signature = Base64.encodeBase64URLSafeString(signatureBytes); - - return String.format("%s.%s", content, signature); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/Message.java b/lib/src/main/java/com/auth0/jwt/creators/Message.java deleted file mode 100644 index 45d252c..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/Message.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; - -public class Message { - - public String toUrlEncoded(String json) throws UnsupportedEncodingException { - return URLEncoder.encode(json, "UTF-8"); - } - - public String toUrlDecoded(String urlEncoded) throws UnsupportedEncodingException { - return URLDecoder.decode(urlEncoded, "UTF-8"); - } - - public String toJSON(HashMap hashMap) { - return new Gson().toJson(hashMap); - } - - public HashMap fromJSON(String json) throws IOException { - return new ObjectMapper().readValue(json, new TypeReference>(){}); - } - -} \ No newline at end of file diff --git a/lib/src/main/java/com/auth0/jwt/creators/RiscJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/RiscJwtCreator.java deleted file mode 100644 index 61e9dd8..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/RiscJwtCreator.java +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The RiscJwtCreator class holds the sign method to generate a complete Risc JWT (with Signature) from a given Header and Payload content. - */ -public class RiscJwtCreator { - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public RiscJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("Jti", false); - put("Issuer", false); - put("Subject", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUER); - add(PublicClaims.SUBJECT); - add(PublicClaims.EXPIRES_AT); - add(PublicClaims.NOT_BEFORE); - add(PublicClaims.ISSUED_AT); - add(PublicClaims.JWT_ID); - add(PublicClaims.AUDIENCE); - }}; - } - - /** - * Require a specific JWT Id ("jti") claim. - * - * @param jwtId the required Id value - * @return this same Verification instance. - */ - public RiscJwtCreator withJWTId(String jwtId) { - jwt.withJWTId(jwtId); - addedClaims.put("Jti", true); - return this; - } - - /** - * Add a specific Issuer ("issuer") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public RiscJwtCreator withIssuer(String... issuer) { - jwt.withIssuer(issuer); - addedClaims.put("Issuer", true); - return this; - } - - /** - * Add a specific Subject ("subject") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public RiscJwtCreator withSubject(String... subject) { - jwt.withSubject(subject); - addedClaims.put("Subject", true); - return this; - } - - /** - * Add a specific Audience ("audience") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public RiscJwtCreator withAudience(String... audience) { - jwt.withAudience(audience); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public RiscJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param exp the Expires At value. - * @return this same Builder instance. - */ - public RiscJwtCreator withExp(Date exp) { - jwt.withExpiresAt(exp); - return this; - } - - /** - * Add a specific Note Before ("nbf") claim to the Payload. - * - * @param nbf the nbf value. - * @return this same Builder instance. - */ - public RiscJwtCreator withNbf(Date nbf) { - jwt.withNotBefore(nbf); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public RiscJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public RiscJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static RiscJwtCreator build() { - return new RiscJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/creators/ScopedJwtCreator.java b/lib/src/main/java/com/auth0/jwt/creators/ScopedJwtCreator.java deleted file mode 100644 index f27c8cb..0000000 --- a/lib/src/main/java/com/auth0/jwt/creators/ScopedJwtCreator.java +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * The ScopedJwtCreator class holds the sign method to generate a complete Scoped JWT (with Signature) from a given Header and Payload content. - */ -public class ScopedJwtCreator{ - - protected JWTCreator.Builder jwt; - protected HashMap addedClaims; - protected Set publicClaims; - - public ScopedJwtCreator() { - jwt = JWT.create(); - addedClaims = new HashMap() {{ - put("Scope", false); - put("Issuer", false); - put("Subject", false); - put("Iat", false); - }}; - publicClaims = new HashSet() {{ - add(PublicClaims.ISSUER); - add(PublicClaims.SUBJECT); - add(PublicClaims.EXPIRES_AT); - add(PublicClaims.NOT_BEFORE); - add(PublicClaims.ISSUED_AT); - add(PublicClaims.JWT_ID); - add(PublicClaims.AUDIENCE); - }}; - } - - /** - * Add a specific Scope ("scope") claim to the Payload. - * Allows for multiple issuers - * - * @param scope the Scope value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withScope(String scope) { - jwt.withNonStandardClaim("scope", scope); - addedClaims.put("Scope", true); - return this; - } - - /** - * Add a specific Issuer ("issuer") claim to the Payload. - * Allows for multiple issuers - * - * @param issuer the Issuer value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withIssuer(String... issuer) { - jwt.withIssuer(issuer); - addedClaims.put("Issuer", true); - return this; - } - - /** - * Add a specific Subject ("subject") claim to the Payload. - * Allows for multiple subjects - * - * @param subject the Subject value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withSubject(String... subject) { - jwt.withSubject(subject); - addedClaims.put("Subject", true); - return this; - } - - /** - * Add a specific Audience ("audience") claim to the Payload. - * Allows for multiple audience - * - * @param audience the Audience value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withAudience(String... audience) { - jwt.withAudience(audience); - return this; - } - - /** - * Add a specific Issued At ("iat") claim to the Payload. - * - * @param iat the Issued At value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withIat(Date iat) { - jwt.withIssuedAt(iat); - addedClaims.put("Iat", true); - return this; - } - - /** - * Add a specific Expires At ("exp") claim to the Payload. - * - * @param exp the Expires At value. - * @return this same Builder instance. - */ - public ScopedJwtCreator withExp(Date exp) { - jwt.withExpiresAt(exp); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, String value) { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Add a custom Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Builder instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - jwt.withNonStandardClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - public ScopedJwtCreator withArrayClaim(String name, String... items) throws IllegalArgumentException { - jwt.withArrayClaim(name, items); - if(publicClaims.contains(name)) - addedClaims.put(name, true); - return this; - } - - /** - * Developer explicitly specifies whether they want to accept - * NONE algorithms or not. - * - * @param isNoneAlgorithmAllowed - * @return - */ - public ScopedJwtCreator setIsNoneAlgorithmAllowed(boolean isNoneAlgorithmAllowed) { - jwt.setIsNoneAlgorithmAllowed(isNoneAlgorithmAllowed); - return this; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String sign(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase16Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base16); - verifyClaims(); - return JWS; - } - - /** - * Creates a new JWT and signs it with the given algorithm. - * - * @param algorithm used to sign the JWT - * @return a new JWT token - * @throws IllegalAccessException if the developer didn't want NONE algorithm to be allowed and it was passed in - * @throws IllegalArgumentException if the provided algorithm is null. - * @throws JWTCreationException if the claims could not be converted to a valid JSON or there was a problem with the signing key. - */ - public String signBase32Encoding(Algorithm algorithm) throws Exception { - if(!jwt.getIsNoneAlgorithmAllowed() && algorithm.equals(Algorithm.none())) { - throw new IllegalAccessException("None algorithm isn't allowed"); - } - String JWS = jwt.sign(algorithm, EncodeType.Base32); - verifyClaims(); - return JWS; - } - - /** - * Verifies that all the standard claims were provided - * @throws Exception if all the standard claims weren't provided - */ - private void verifyClaims() throws Exception { - for(String claim : addedClaims.keySet()) - if(!addedClaims.get(claim)) - throw new Exception("Standard claim: " + claim + " has not been set"); - } - - public static ScopedJwtCreator build() { - return new ScopedJwtCreator(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/AlgorithmMismatchException.java b/lib/src/main/java/com/auth0/jwt/exceptions/AlgorithmMismatchException.java deleted file mode 100644 index 0406588..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/AlgorithmMismatchException.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -public class AlgorithmMismatchException extends JWTVerificationException { - public AlgorithmMismatchException(String message) { - super(message); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/InvalidClaimException.java b/lib/src/main/java/com/auth0/jwt/exceptions/InvalidClaimException.java deleted file mode 100644 index 01d6eb0..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/InvalidClaimException.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - - -public class InvalidClaimException extends JWTVerificationException { - public InvalidClaimException(String message) { - super(message); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/JWTCreationException.java b/lib/src/main/java/com/auth0/jwt/exceptions/JWTCreationException.java deleted file mode 100644 index 4c73dd0..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/JWTCreationException.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -public class JWTCreationException extends RuntimeException { - public JWTCreationException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/JWTDecodeException.java b/lib/src/main/java/com/auth0/jwt/exceptions/JWTDecodeException.java deleted file mode 100644 index b03511d..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/JWTDecodeException.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -public class JWTDecodeException extends JWTVerificationException { - public JWTDecodeException(String message) { - this(message, null); - } - - public JWTDecodeException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/JWTVerificationException.java b/lib/src/main/java/com/auth0/jwt/exceptions/JWTVerificationException.java deleted file mode 100644 index b249ffc..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/JWTVerificationException.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -public class JWTVerificationException extends RuntimeException { - public JWTVerificationException(String message) { - this(message, null); - } - - public JWTVerificationException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/SignatureGenerationException.java b/lib/src/main/java/com/auth0/jwt/exceptions/SignatureGenerationException.java deleted file mode 100644 index 970e756..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/SignatureGenerationException.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -import com.auth0.jwt.algorithms.Algorithm; - -public class SignatureGenerationException extends JWTCreationException { - public SignatureGenerationException(Algorithm algorithm, Throwable cause) { - super("The Token's Signature couldn't be generated when signing using the Algorithm: " + algorithm, cause); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/SignatureVerificationException.java b/lib/src/main/java/com/auth0/jwt/exceptions/SignatureVerificationException.java deleted file mode 100644 index f017c83..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/SignatureVerificationException.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -import com.auth0.jwt.algorithms.Algorithm; - -public class SignatureVerificationException extends JWTVerificationException { - public SignatureVerificationException(Algorithm algorithm) { - this(algorithm, null); - } - - public SignatureVerificationException(Algorithm algorithm, Throwable cause) { - super("The Token's Signature resulted invalid when verified using the Algorithm: " + algorithm, cause); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/exceptions/TokenExpiredException.java b/lib/src/main/java/com/auth0/jwt/exceptions/TokenExpiredException.java deleted file mode 100644 index de929dc..0000000 --- a/lib/src/main/java/com/auth0/jwt/exceptions/TokenExpiredException.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.exceptions; - -public class TokenExpiredException extends JWTVerificationException { - - private static final long serialVersionUID = -7076928975713577708L; - - public TokenExpiredException(String message) { - super(message); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/BasicHeader.java b/lib/src/main/java/com/auth0/jwt/impl/BasicHeader.java deleted file mode 100644 index d6c502d..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/BasicHeader.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.Header; -import com.fasterxml.jackson.databind.JsonNode; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static com.auth0.jwt.impl.JsonNodeClaim.extractClaim; - -/** - * The BasicHeader class implements the Header interface. - */ -class BasicHeader implements Header { - private final String algorithm; - private final String type; - private final String contentType; - private final String keyId; - private final Map tree; - - BasicHeader(String algorithm, String type, String contentType, String keyId, Map tree) { - this.algorithm = algorithm; - this.type = type; - this.contentType = contentType; - this.keyId = keyId; - this.tree = Collections.unmodifiableMap(tree == null ? new HashMap() : tree); - } - - Map getTree() { - return tree; - } - - @Override - public String getAlgorithm() { - return algorithm; - } - - @Override - public String getType() { - return type; - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public String getKeyId() { - return keyId; - } - - @Override - public Claim getHeaderClaim(String name) { - return extractClaim(name, tree); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/ClaimsHolder.java b/lib/src/main/java/com/auth0/jwt/impl/ClaimsHolder.java deleted file mode 100644 index fe6f7bc..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/ClaimsHolder.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import java.util.HashMap; -import java.util.Map; - -/** - * The ClaimsHolder class is just a wrapper for the Map of Claims used for building a JWT. - */ -public final class ClaimsHolder { - private Map claims; - - public ClaimsHolder(Map claims) { - this.claims = claims == null ? new HashMap() : claims; - } - - Map getClaims() { - return claims; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/HeaderDeserializer.java b/lib/src/main/java/com/auth0/jwt/impl/HeaderDeserializer.java deleted file mode 100644 index 2c2b916..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/HeaderDeserializer.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -import java.io.IOException; -import java.util.Map; - -class HeaderDeserializer extends StdDeserializer { - - HeaderDeserializer() { - this(null); - } - - private HeaderDeserializer(Class vc) { - super(vc); - } - - @Override - public BasicHeader deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - Map tree = p.getCodec().readValue(p, new TypeReference>() { - }); - if (tree == null) { - throw new JWTDecodeException("Parsing the Header's JSON resulted on a Null map"); - } - - String algorithm = getString(tree, PublicClaims.ALGORITHM); - String type = getString(tree, PublicClaims.TYPE); - String contentType = getString(tree, PublicClaims.CONTENT_TYPE); - String keyId = getString(tree, PublicClaims.KEY_ID); - return new BasicHeader(algorithm, type, contentType, keyId, tree); - } - - String getString(Map tree, String claimName) { - JsonNode node = tree.get(claimName); - if (node == null || node.isNull()) { - return null; - } - return node.asText(null); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/JWTParser.java b/lib/src/main/java/com/auth0/jwt/impl/JWTParser.java deleted file mode 100644 index d471f82..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/JWTParser.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Header; -import com.auth0.jwt.interfaces.JWTPartsParser; -import com.auth0.jwt.interfaces.Payload; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; - -import java.io.IOException; - -public class JWTParser implements JWTPartsParser { - private ObjectMapper mapper; - - public JWTParser() { - this(getDefaultObjectMapper()); - } - - JWTParser(ObjectMapper mapper) { - addDeserializers(mapper); - this.mapper = mapper; - } - - @Override - public Payload parsePayload(String json) throws JWTDecodeException { - return convertFromJSON(json, Payload.class); - } - - @Override - public Header parseHeader(String json) throws JWTDecodeException { - return convertFromJSON(json, Header.class); - } - - private void addDeserializers(ObjectMapper mapper) { - SimpleModule module = new SimpleModule(); - module.addDeserializer(Payload.class, new PayloadDeserializer()); - module.addDeserializer(Header.class, new HeaderDeserializer()); - mapper.registerModule(module); - } - - static ObjectMapper getDefaultObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); - return mapper; - } - - @SuppressWarnings("WeakerAccess") - T convertFromJSON(String json, Class tClazz) throws JWTDecodeException { - if (json == null) { - throw exceptionForInvalidJson(null); - } - try { - return mapper.readValue(json, tClazz); - } catch (IOException e) { - throw exceptionForInvalidJson(json); - } - } - - private JWTDecodeException exceptionForInvalidJson(String json) { - return new JWTDecodeException(String.format("The string '%s' doesn't have a valid JSON format.", json)); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/JsonNodeClaim.java b/lib/src/main/java/com/auth0/jwt/impl/JsonNodeClaim.java deleted file mode 100644 index 9b41403..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/JsonNodeClaim.java +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Claim; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.IOException; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * The JsonNodeClaim retrieves a claim value from a JsonNode object. - */ -class JsonNodeClaim implements Claim { - - private final JsonNode data; - - private JsonNodeClaim(JsonNode node) { - this.data = node; - } - - @Override - public Boolean asBoolean() { - return !data.isBoolean() ? null : data.asBoolean(); - } - - @Override - public Integer asInt() { - return !data.isNumber() ? null : data.asInt(); - } - - @Override - public Long asLong() { - return !data.isNumber() ? null : data.asLong(); - } - - @Override - public Double asDouble() { - return !data.isNumber() ? null : data.asDouble(); - } - - @Override - public String asString() { - return !data.isTextual() ? null : data.asText(); - } - - @Override - public Date asDate() { - if (!data.canConvertToLong()) { - return null; - } - long seconds = data.asLong(); - return new Date(seconds * 1000); - } - - @Override - @SuppressWarnings("unchecked") - public T[] asArray(Class tClazz) throws JWTDecodeException { - if (!data.isArray()) { - return null; - } - - T[] arr = (T[]) Array.newInstance(tClazz, data.size()); - for (int i = 0; i < data.size(); i++) { - try { - arr[i] = getObjectMapper().treeToValue(data.get(i), tClazz); - } catch (JsonProcessingException e) { - throw new JWTDecodeException("Couldn't map the Claim's array contents to " + tClazz.getSimpleName(), e); - } - } - return arr; - } - - @Override - public List asList(Class tClazz) throws JWTDecodeException { - if (!data.isArray()) { - return null; - } - - List list = new ArrayList<>(); - for (int i = 0; i < data.size(); i++) { - try { - list.add(getObjectMapper().treeToValue(data.get(i), tClazz)); - } catch (JsonProcessingException e) { - throw new JWTDecodeException("Couldn't map the Claim's array contents to " + tClazz.getSimpleName(), e); - } - } - return list; - } - - @Override - public Map asMap() throws JWTDecodeException { - if (!data.isObject()) { - return null; - } - - try { - TypeReference> mapType = new TypeReference>() { - }; - ObjectMapper thisMapper = getObjectMapper(); - JsonParser thisParser = thisMapper.treeAsTokens(data); - return thisParser.readValueAs(mapType); - } catch (IOException e) { - throw new JWTDecodeException("Couldn't map the Claim value to Map", e); - } - } - - @Override - public T as(Class tClazz) throws JWTDecodeException { - try { - return getObjectMapper().treeAsTokens(data).readValueAs(tClazz); - } catch (IOException e) { - throw new JWTDecodeException("Couldn't map the Claim value to " + tClazz.getSimpleName(), e); - } - } - - @Override - public boolean isNull() { - return false; - } - - /** - * Helper method to extract a Claim from the given JsonNode tree. - * - * @param claimName the Claim to search for. - * @param tree the JsonNode tree to search the Claim in. - * @return a valid non-null Claim. - */ - static Claim extractClaim(String claimName, Map tree) { - JsonNode node = tree.get(claimName); - return claimFromNode(node); - } - - /** - * Helper method to create a Claim representation from the given JsonNode. - * - * @param node the JsonNode to convert into a Claim. - * @return a valid Claim instance. If the node is null or missing, a NullClaim will be returned. - */ - static Claim claimFromNode(JsonNode node) { - if (node == null || node.isNull() || node.isMissingNode()) { - return new NullClaim(); - } - return new JsonNodeClaim(node); - } - - //Visible for testing - ObjectMapper getObjectMapper() { - return new ObjectMapper(); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/NullClaim.java b/lib/src/main/java/com/auth0/jwt/impl/NullClaim.java deleted file mode 100644 index 82e7c03..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/NullClaim.java +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Claim; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * The {@link NullClaim} class is a Claim implementation that returns null when any of it's methods it's called. - */ -public class NullClaim implements Claim { - @Override - public boolean isNull() { - return true; - } - - @Override - public Boolean asBoolean() { - return null; - } - - @Override - public Integer asInt() { - return null; - } - - @Override - public Long asLong() { - return null; - } - - @Override - public Double asDouble() { - return null; - } - - @Override - public String asString() { - return null; - } - - @Override - public Date asDate() { - return null; - } - - @Override - public T[] asArray(Class tClazz) throws JWTDecodeException { - return null; - } - - @Override - public List asList(Class tClazz) throws JWTDecodeException { - return null; - } - - @Override - public Map asMap() throws JWTDecodeException { - return null; - } - - @Override - public T as(Class tClazz) throws JWTDecodeException { - return null; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java b/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java deleted file mode 100644 index babc935..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Payload; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - -import java.io.IOException; -import java.util.*; - -class PayloadDeserializer extends StdDeserializer { - - PayloadDeserializer() { - this(null); - } - - private PayloadDeserializer(Class vc) { - super(vc); - } - - @Override - public Payload deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - Map tree = p.getCodec().readValue(p, new TypeReference>() { - }); - if (tree == null) { - throw new JWTDecodeException("Parsing the Payload's JSON resulted on a Null map"); - } - - List issuer = getStringOrArray(tree, PublicClaims.ISSUER); - List subject = getStringOrArray(tree, PublicClaims.SUBJECT); - List audience = getStringOrArray(tree, PublicClaims.AUDIENCE); - Date expiresAt = getDateFromSeconds(tree, PublicClaims.EXPIRES_AT); - Date notBefore = getDateFromSeconds(tree, PublicClaims.NOT_BEFORE); - Date issuedAt = getDateFromSeconds(tree, PublicClaims.ISSUED_AT); - String jwtId = getString(tree, PublicClaims.JWT_ID); - - return new PayloadImpl(issuer, subject, audience, expiresAt, notBefore, issuedAt, jwtId, tree); - } - - List getStringOrArray(Map tree, String claimName) throws JWTDecodeException { - JsonNode node = tree.get(claimName); - if (node == null || node.isNull() || !(node.isArray() || node.isTextual())) { - return null; - } - if (node.isTextual() && !node.asText().isEmpty()) { - return Collections.singletonList(node.asText()); - } - - ObjectMapper mapper = new ObjectMapper(); - List list = new ArrayList<>(node.size()); - for (int i = 0; i < node.size(); i++) { - try { - list.add(mapper.treeToValue(node.get(i), String.class)); - } catch (JsonProcessingException e) { - throw new JWTDecodeException("Couldn't map the Claim's array contents to String", e); - } - } - return list; - } - - Date getDateFromSeconds(Map tree, String claimName) { - JsonNode node = tree.get(claimName); - if (node == null || node.isNull() || !node.canConvertToLong()) { - return null; - } - final long ms = node.asLong() * 1000; - return new Date(ms); - } - - String getString(Map tree, String claimName) { - JsonNode node = tree.get(claimName); - if (node == null || node.isNull()) { - return null; - } - return node.asText(null); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/PayloadImpl.java b/lib/src/main/java/com/auth0/jwt/impl/PayloadImpl.java deleted file mode 100644 index a732416..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/PayloadImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.Payload; -import com.fasterxml.jackson.databind.JsonNode; - -import java.util.*; - -import static com.auth0.jwt.impl.JsonNodeClaim.extractClaim; - -/** - * The PayloadImpl class implements the Payload interface. - */ -class PayloadImpl implements Payload { - private final List issuer; - private final List subject; - private final List audience; - private final Date expiresAt; - private final Date notBefore; - private final Date issuedAt; - private final String jwtId; - private final Map tree; - - PayloadImpl(List issuer, List subject, List audience, Date expiresAt, Date notBefore, Date issuedAt, String jwtId, Map tree) { - this.issuer = issuer; - this.subject = subject; - this.audience = audience; - this.expiresAt = expiresAt; - this.notBefore = notBefore; - this.issuedAt = issuedAt; - this.jwtId = jwtId; - this.tree = Collections.unmodifiableMap(tree == null ? new HashMap() : tree); - } - - Map getTree() { - return tree; - } - - @Override - public List getIssuer() { - return issuer; - } - - @Override - public List getSubject() { - return subject; - } - - @Override - public List getAudience() { - return audience; - } - - @Override - public Date getExpiresAt() { - return expiresAt; - } - - @Override - public Date getNotBefore() { - return notBefore; - } - - @Override - public Date getIssuedAt() { - return issuedAt; - } - - @Override - public String getId() { - return jwtId; - } - - @Override - public Claim getClaim(String name) { - return extractClaim(name, tree); - } - - @Override - public Map getClaims() { - Map claims = new HashMap<>(); - for (String name : tree.keySet()) { - claims.put(name, extractClaim(name, tree)); - } - return Collections.unmodifiableMap(claims); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java b/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java deleted file mode 100644 index 09915f8..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -import java.io.IOException; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -public class PayloadSerializer extends StdSerializer { - - public PayloadSerializer() { - this(null); - } - - private PayloadSerializer(Class t) { - super(t); - } - - @Override - public void serialize(ClaimsHolder holder, JsonGenerator gen, SerializerProvider provider) throws IOException { - HashMap safePayload = new HashMap<>(); - for (Map.Entry e : holder.getClaims().entrySet()) { - switch (e.getKey()) { - case PublicClaims.AUDIENCE: - if (e.getValue() instanceof String) { - safePayload.put(e.getKey(), e.getValue()); - break; - } - String[] audArray = (String[]) e.getValue(); - if (audArray.length == 1) { - safePayload.put(e.getKey(), audArray[0]); - } else if (audArray.length > 1) { - safePayload.put(e.getKey(), audArray); - } - break; - case PublicClaims.EXPIRES_AT: - case PublicClaims.ISSUED_AT: - case PublicClaims.NOT_BEFORE: - safePayload.put(e.getKey(), dateToSeconds((Date) e.getValue())); - break; - default: - if (e.getValue() instanceof Date) { - safePayload.put(e.getKey(), dateToSeconds((Date) e.getValue())); - } else { - safePayload.put(e.getKey(), e.getValue()); - } - break; - } - } - - gen.writeObject(safePayload); - } - - private long dateToSeconds(Date date) { - return date.getTime() / 1000; - } -} diff --git a/lib/src/main/java/com/auth0/jwt/impl/PublicClaims.java b/lib/src/main/java/com/auth0/jwt/impl/PublicClaims.java deleted file mode 100644 index b7594e1..0000000 --- a/lib/src/main/java/com/auth0/jwt/impl/PublicClaims.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - - -public interface PublicClaims { - - //Header - String ALGORITHM = "alg"; - String CONTENT_TYPE = "cty"; - String TYPE = "typ"; - String KEY_ID = "kid"; - - //Payload - String ISSUER = "iss"; - String SUBJECT = "sub"; - String EXPIRES_AT = "exp"; - String NOT_BEFORE = "nbf"; - String ISSUED_AT = "iat"; - String JWT_ID = "jti"; - String AUDIENCE = "aud"; - -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/Claim.java b/lib/src/main/java/com/auth0/jwt/interfaces/Claim.java deleted file mode 100644 index 6ec9d67..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/Claim.java +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import com.auth0.jwt.exceptions.JWTDecodeException; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * The Claim class holds the value in a generic way so that it can be recovered in many representations. - */ -public interface Claim { - - /** - * Whether this Claim has a null value or not. - * - * @return whether this Claim has a null value or not. - */ - boolean isNull(); - - /** - * Get this Claim as a Boolean. - * If the value isn't of type Boolean or it can't be converted to a Boolean, null will be returned. - * - * @return the value as a Boolean or null. - */ - Boolean asBoolean(); - - /** - * Get this Claim as an Integer. - * If the value isn't of type Integer or it can't be converted to an Integer, null will be returned. - * - * @return the value as an Integer or null. - */ - Integer asInt(); - - /** - * Get this Claim as an Long. - * If the value isn't of type Long or it can't be converted to an Long, null will be returned. - * - * @return the value as an Long or null. - */ - Long asLong(); - - /** - * Get this Claim as a Double. - * If the value isn't of type Double or it can't be converted to a Double, null will be returned. - * - * @return the value as a Double or null. - */ - Double asDouble(); - - /** - * Get this Claim as a String. - * If the value isn't of type String or it can't be converted to a String, null will be returned. - * - * @return the value as a String or null. - */ - String asString(); - - /** - * Get this Claim as a Date. - * If the value can't be converted to a Date, null will be returned. - * - * @return the value as a Date or null. - */ - Date asDate(); - - /** - * Get this Claim as an Array of type T. - * If the value isn't an Array, null will be returned. - * - * @return the value as an Array or null. - * @throws JWTDecodeException if the values inside the Array can't be converted to a class T. - */ - T[] asArray(Class tClazz) throws JWTDecodeException; - - /** - * Get this Claim as a List of type T. - * If the value isn't an Array, null will be returned. - * - * @return the value as a List or null. - * @throws JWTDecodeException if the values inside the List can't be converted to a class T. - */ - List asList(Class tClazz) throws JWTDecodeException; - - /** - * Get this Claim as a generic Map of values. - * - * @return the value as instance of Map. - * @throws JWTDecodeException if the value can't be converted to a Map. - */ - Map asMap() throws JWTDecodeException; - - /** - * Get this Claim as a custom type T. - * - * @return the value as instance of T. - * @throws JWTDecodeException if the value can't be converted to a class T. - */ - T as(Class tClazz) throws JWTDecodeException; -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/Clock.java b/lib/src/main/java/com/auth0/jwt/interfaces/Clock.java deleted file mode 100644 index 2742adf..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/Clock.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.util.Date; - -/** - * The Clock class is used to wrap calls to Date class. - */ -public interface Clock { - - /** - * Returns a new Date representing Today's time. - * - * @return a new Date representing Today's time. - */ - Date getToday(); -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/DecodedJWT.java b/lib/src/main/java/com/auth0/jwt/interfaces/DecodedJWT.java deleted file mode 100644 index 20d39ac..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/DecodedJWT.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -/** - * Class that represents a Json Web Token that was decoded from it's string representation. - */ -public interface DecodedJWT extends Payload, Header { - /** - * Getter for the String Token used to create this JWT instance. - * - * @return the String Token. - */ - String getToken(); - - /** - * Getter for the Header contained in the JWT as a Base64 encoded String. - * This represents the first part of the token. - * - * @return the Header of the JWT. - */ - String getHeader(); - - /** - * Getter for the Payload contained in the JWT as a Base64 encoded String. - * This represents the second part of the token. - * - * @return the Payload of the JWT. - */ - String getPayload(); - - /** - * Getter for the Signature contained in the JWT as a Base64 encoded String. - * This represents the third part of the token. - * - * @return the Signature of the JWT. - */ - String getSignature(); -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/ECDSAKeyProvider.java b/lib/src/main/java/com/auth0/jwt/interfaces/ECDSAKeyProvider.java deleted file mode 100644 index 2a667da..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/ECDSAKeyProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; - -/** - * Elliptic Curve (EC) Public/Private Key provider. - */ -public interface ECDSAKeyProvider extends KeyProvider { -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/ExtendedVerification.java b/lib/src/main/java/com/auth0/jwt/interfaces/ExtendedVerification.java deleted file mode 100644 index 433a2b2..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/ExtendedVerification.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -public interface ExtendedVerification { -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/GoogleVerification.java b/lib/src/main/java/com/auth0/jwt/interfaces/GoogleVerification.java deleted file mode 100644 index c7b66cc..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/GoogleVerification.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.util.Date; -import java.util.List; - -public interface GoogleVerification extends Verification{ - - Verification createVerifierForGoogle(String picture, String email, List issuer, - List audience, String name, long expLeeway, long iatLeeway); - - Verification withPicture(String picture); - - Verification withEmail(String email); - - GoogleVerification withName(String name); - - Verification createVerifierForExtended(String picture, String email, List issuer, - List audience, String name, long nbf, long expLeeway, long iatLeeway); - -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/Header.java b/lib/src/main/java/com/auth0/jwt/interfaces/Header.java deleted file mode 100644 index 16e438a..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/Header.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -/** - * The Header class represents the 1st part of the JWT, where the Header value is hold. - */ -public interface Header { - - /** - * Getter for the Algorithm "alg" claim defined in the JWT's Header. If the claim is missing it will return null. - * - * @return the Algorithm defined or null. - */ - String getAlgorithm(); - - /** - * Getter for the Type "typ" claim defined in the JWT's Header. If the claim is missing it will return null. - * - * @return the Type defined or null. - */ - String getType(); - - /** - * Getter for the Content Type "cty" claim defined in the JWT's Header. If the claim is missing it will return null. - * - * @return the Content Type defined or null. - */ - String getContentType(); - - /** - * Get the value of the "kid" claim, or null if it's not available. - * - * @return the Key ID value or null. - */ - String getKeyId(); - - /** - * Get a Private Claim given it's name. If the Claim wasn't specified in the Header, a NullClaim will be returned. - * - * @param name the name of the Claim to retrieve. - * @return a non-null Claim. - */ - Claim getHeaderClaim(String name); -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/JWTPartsParser.java b/lib/src/main/java/com/auth0/jwt/interfaces/JWTPartsParser.java deleted file mode 100644 index 70e3d0c..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/JWTPartsParser.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import com.auth0.jwt.exceptions.JWTDecodeException; - -/** - * The JWTPartsParser class defines which parts of the JWT should be converted to it's specific Object representation instance. - */ -public interface JWTPartsParser { - - /** - * Parses the given JSON into a Payload instance. - * - * @param json the content of the Payload in a JSON representation. - * @return the Payload. - * @throws JWTDecodeException if the json doesn't have a proper JSON format. - */ - Payload parsePayload(String json) throws JWTDecodeException; - - /** - * Parses the given JSON into a Header instance. - * - * @param json the content of the Header in a JSON representation. - * @return the Header. - * @throws JWTDecodeException if the json doesn't have a proper JSON format. - */ - Header parseHeader(String json) throws JWTDecodeException; -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/KeyProvider.java b/lib/src/main/java/com/auth0/jwt/interfaces/KeyProvider.java deleted file mode 100644 index bba760c..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/KeyProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.security.PrivateKey; -import java.security.PublicKey; - -/** - * Generic Public/Private Key provider. - * - * @param the class that represents the Public Key - * @param the class that represents the Private Key - */ -interface KeyProvider { - - /** - * Getter for the Public Key instance with the given Id. Used to verify the signature on the JWT verification stage. - * - * @param keyId the Key Id specified in the Token's Header or null if none is available. Provides a hint on which Public Key to use to verify the token's signature. - * @return the Public Key instance - */ - U getPublicKeyById(String keyId); - - /** - * Getter for the Private Key instance. Used to sign the content on the JWT signing stage. - * - * @return the Private Key instance - */ - R getPrivateKey(); - - /** - * Getter for the Id of the Private Key used to sign the tokens. This represents the `kid` claim and will be placed in the Header. - * - * @return the Key Id that identifies the Private Key or null if it's not specified. - */ - String getPrivateKeyId(); -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/Payload.java b/lib/src/main/java/com/auth0/jwt/interfaces/Payload.java deleted file mode 100644 index d9a4e00..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/Payload.java +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * The Payload class represents the 2nd part of the JWT, where the Payload value is hold. - */ -public interface Payload { - - /** - * Get the value(s) of the "iss" claim, or null if it's not available. - * - * @return the Issuer value or null. - */ - List getIssuer(); - - /** - * Get the value(s) of the "sub" claim, or null if it's not available. - * - * @return the Subject value or null. - */ - List getSubject(); - - /** - * Get the value(s) of the "aud" claim, or null if it's not available. - * - * @return the Audience value or null. - */ - List getAudience(); - - /** - * Get the value of the "exp" claim, or null if it's not available. - * - * @return the Expiration Time value or null. - */ - Date getExpiresAt(); - - /** - * Get the value of the "nbf" claim, or null if it's not available. - * - * @return the Not Before value or null. - */ - Date getNotBefore(); - - /** - * Get the value of the "iat" claim, or null if it's not available. - * - * @return the Issued At value or null. - */ - Date getIssuedAt(); - - /** - * Get the value of the "jti" claim, or null if it's not available. - * - * @return the JWT ID value or null. - */ - String getId(); - - /** - * Get a Claim given it's name. If the Claim wasn't specified in the Payload, a NullClaim will be returned. - * - * @param name the name of the Claim to retrieve. - * @return a non-null Claim. - */ - Claim getClaim(String name); - - /** - * Get the Claims defined in the Token. - * - * @return a non-null Map containing the Claims defined in the Token. - */ - Map getClaims(); -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/RSAKeyProvider.java b/lib/src/main/java/com/auth0/jwt/interfaces/RSAKeyProvider.java deleted file mode 100644 index 7433e79..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/RSAKeyProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; - -/** - * RSA Public/Private Key provider. - */ -public interface RSAKeyProvider extends KeyProvider { -} diff --git a/lib/src/main/java/com/auth0/jwt/interfaces/Verification.java b/lib/src/main/java/com/auth0/jwt/interfaces/Verification.java deleted file mode 100644 index 82ffaba..0000000 --- a/lib/src/main/java/com/auth0/jwt/interfaces/Verification.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.interfaces; - -import com.auth0.jwt.jwts.JWT; - -import java.util.Date; -import java.util.List; - -public interface Verification { - Verification withIssuer(String... issuer); - - Verification withSubject(String... subject); - - Verification withAudience(String... audience); - - Verification acceptLeeway(long leeway) throws IllegalArgumentException; - - Verification acceptExpiresAt(long leeway) throws IllegalArgumentException; - - Verification acceptNotBefore(long leeway) throws IllegalArgumentException; - - Verification acceptIssuedAt(long leeway) throws IllegalArgumentException; - - Verification withJWTId(String jwtId); - - Verification withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException; - - Verification withNonStandardClaim(String name, Integer value) throws IllegalArgumentException; - - Verification withNonStandardClaim(String name, Long value) throws IllegalArgumentException; - - Verification withNonStandardClaim(String name, Double value) throws IllegalArgumentException; - - Verification withNonStandardClaim(String name, String value) throws IllegalArgumentException; - - Verification withNonStandardClaim(String name, Date value) throws IllegalArgumentException; - - Verification withArrayClaim(String name, String... items) throws IllegalArgumentException; - - Verification withArrayClaim(String name, Integer... items) throws IllegalArgumentException; - - Verification withNbf(long nbf); - - Verification createVerifierForScoped(String scope, List issuer, - List audience, long expLeeway, long iatLeeway); - - Verification createVerifierForImplicit(List issuer, - List audience, long iatLeeway); - - Verification createVerifierForFb(String userId, String appId); - - Verification withUserId(String userId); - - Verification withAppId(String appId); - - Verification createVerifierForAccess(List issuer, - List audience, long expLeeway, long iatLeeway); - - Verification createVerifierForRisc(String jti, List issuer, - List audience, long iatLeeway, long expLeeway, long nbf); - - JWT build(); -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/AccessJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/AccessJWT.java deleted file mode 100644 index aa58cee..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/AccessJWT.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class AccessJWT extends JWT.BaseVerification implements Verification { - - AccessJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @param issuer - * @param audience - * @param expLeeway - * @param iatLeeway - * @return - */ - public Verification createVerifierForAccess(List issuer, - List audience, long expLeeway, long iatLeeway) { - return withIssuer(issuer.toArray(new String[issuer.size()])).withAudience(audience.toArray(new String[audience.size()])) - .acceptExpiresAt(expLeeway).acceptIssuedAt(iatLeeway); - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return AccessJWT.init(algorithm); - } - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a AccessJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new AccessJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/ExtendedJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/ExtendedJWT.java deleted file mode 100644 index 4887dcd..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/ExtendedJWT.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.GoogleVerification; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class ExtendedJWT extends GoogleJWT implements GoogleVerification{ - - ExtendedJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - - public Verification createVerifierForExtended(String picture, String email, List issuer, - List audience, String name, long nbf, long expLeeway, long iatLeeway) { - Verification verification = createVerifierForGoogle(picture, email, issuer, audience, name, expLeeway, iatLeeway); - return verification.withNbf(nbf); - } - - public static GoogleVerification require(Algorithm algorithm) { - return ExtendedJWT.init(algorithm); - } - - static GoogleVerification init(Algorithm algorithm) throws IllegalArgumentException { - return new ExtendedJWT(algorithm); - } - - /** - * Require a specific Not Before ("nbf") claim. - * - * @param nbf the required Not Before value - * @return this same Verification instance. - */ - @Override - public Verification withNbf(long nbf) { - requireClaim("nbf", nbf); - return this; - } - -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/FbJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/FbJWT.java deleted file mode 100644 index 83d746f..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/FbJWT.java +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.Verification; - -public class FbJWT extends JWT.BaseVerification implements Verification{ - - FbJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @param userId - * @param appId - * @return - */ - public Verification createVerifierForFb(String userId, String appId) { - return withUserId(userId).withAppId(appId); - } - - /** - * Require a specific userId ("userId") claim. - * - * @param userId the required userId value - * @return this same Verification instance. - */ - public Verification withUserId(String userId) { - requireClaim("userId", userId); - return this; - } - - /** - * Require a specific appId ("appId") claim. - * - * @param appId the required appId value - * @return this same Verification instance. - */ - public Verification withAppId(String appId) { - requireClaim("appId", appId); - return this; - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return FbJWT.init(algorithm); - } - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a FbJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new FbJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/GoogleJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/GoogleJWT.java deleted file mode 100644 index 1aaf574..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/GoogleJWT.java +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.GoogleVerification; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class GoogleJWT extends JWT.BaseVerification implements GoogleVerification{ - - GoogleJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @param picture - * @param email - * @param issuer - * @param audience - * @param name - * @return - */ - public Verification createVerifierForGoogle(String picture, String email, List issuer, - List audience, String name, long expLeeway, long iatLeeway) { - return withPicture(picture).withName(name).withEmail(email).withIssuer(issuer.toArray(new String[issuer.size()])).withAudience(audience.toArray(new String[audience.size()])) - .acceptExpiresAt(expLeeway).acceptIssuedAt(iatLeeway); - } - - /** - * Require a specific Picture ("picture") claim. - * - * @param picture the required Picture value - * @return this same Verification instance. - */ - @Override - public GoogleVerification withPicture(String picture) { - requireClaim("picture", picture); - return this; - } - - /** - * Require a specific Email ("email") claim. - * - * @param email the required Email value - * @return this same Verification instance. - */ - @Override - public GoogleVerification withEmail(String email) { - requireClaim("email", email); - return this; - } - - /** - * Require a specific Name ("name") claim. - * - * @param name the required Name value - * @return this same Verification instance. - */ - @Override - public GoogleVerification withName(String name) { - requireClaim("name", name); - return this; - } - - @Override - public Verification createVerifierForExtended(String picture, String email, List issuer, List audience, String name, long nbf, long expLeeway, long iatLeeway) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - /** - * Returns a {GoogleVerification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return GoogleVerification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static GoogleVerification require(Algorithm algorithm) { - return GoogleJWT.init(algorithm); - } - - /** - * Initialize a GoogleVerification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a GoogleJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static GoogleVerification init(Algorithm algorithm) throws IllegalArgumentException { - return new GoogleJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/ImplicitJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/ImplicitJWT.java deleted file mode 100644 index 91eb070..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/ImplicitJWT.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class ImplicitJWT extends JWT.BaseVerification implements Verification{ - - ImplicitJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @issuer scope - * @param issuer - * @param audience - * @return - */ - public Verification createVerifierForImplicit(List issuer, - List audience, long iatLeeway) { - return withIssuer(issuer.toArray(new String[issuer.size()])).withAudience(audience.toArray(new String[audience.size()])) - .acceptIssuedAt(iatLeeway); - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return ImplicitJWT.init(algorithm); - } - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a ImplicitJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new ImplicitJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/JWT.java b/lib/src/main/java/com/auth0/jwt/jwts/JWT.java deleted file mode 100644 index 4557a67..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/JWT.java +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.creators.JWTCreator; -import com.auth0.jwt.JWTDecoder; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.*; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.verification.VerificationAndAssertion; - -import java.util.*; - -@SuppressWarnings("WeakerAccess") -public class JWT { - - private final Algorithm algorithm; - final Map claims; - private final Clock clock; - - JWT(Algorithm algorithm, Map claims, Clock clock) { - this.algorithm = algorithm; - this.claims = Collections.unmodifiableMap(claims); - this.clock = clock; - } - - /** - * Convert the given token to a DecodedJWT - *

- * Note that this method doesn't verify the token's signature! Use it only if you trust the token or you already verified it. - * - * @param token with jwt format as string. - * @return a decoded JWT. - * @throws AlgorithmMismatchException if the algorithm stated in the token's header it's not equal to the one defined in the {@link JWT}. - * @throws SignatureVerificationException if the signature is invalid. - * @throws TokenExpiredException if the token has expired. - * @throws InvalidClaimException if a claim contained a different value than the expected one. - */ - public DecodedJWT decode(String token) throws Exception { - DecodedJWT jwt = new JWTDecoder(token, EncodeType.Base64); - VerificationAndAssertion.verifyAlgorithm(jwt, algorithm); - algorithm.verify(jwt, EncodeType.Base64); - VerificationAndAssertion.verifyClaims(clock, jwt, claims); - return jwt; - } - - /** - * Convert the given token to a DecodedJWT - *

- * Note that this method doesn't verify the token's signature! Use it only if you trust the token or you already verified it. - * - * @param token with jwt format as string. - * @return a decoded JWT. - * @throws AlgorithmMismatchException if the algorithm stated in the token's header it's not equal to the one defined in the {@link JWT}. - * @throws SignatureVerificationException if the signature is invalid. - * @throws TokenExpiredException if the token has expired. - * @throws InvalidClaimException if a claim contained a different value than the expected one. - */ - public DecodedJWT decode16Bytes(String token) throws Exception { - DecodedJWT jwt = new JWTDecoder(token, EncodeType.Base16); - VerificationAndAssertion.verifyAlgorithm(jwt, algorithm); - algorithm.verify(jwt, EncodeType.Base16); - VerificationAndAssertion.verifyClaims(clock, jwt, claims); - return jwt; - } - - /** - * Convert the given token to a DecodedJWT - *

- * Note that this method doesn't verify the token's signature! Use it only if you trust the token or you already verified it. - * - * @param token with jwt format as string. - * @return a decoded JWT. - * @throws AlgorithmMismatchException if the algorithm stated in the token's header it's not equal to the one defined in the {@link JWT}. - * @throws SignatureVerificationException if the signature is invalid. - * @throws TokenExpiredException if the token has expired. - * @throws InvalidClaimException if a claim contained a different value than the expected one. - */ - public DecodedJWT decode32Bytes(String token) throws Exception { - DecodedJWT jwt = new JWTDecoder(token, EncodeType.Base32); - VerificationAndAssertion.verifyAlgorithm(jwt, algorithm); - algorithm.verify(jwt, EncodeType.Base32); - VerificationAndAssertion.verifyClaims(clock, jwt, claims); - return jwt; - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return JWT.init(algorithm); - } - - /** - * Returns a Json Web Token builder used to create and sign tokens - * - * @return a token builder. - */ - public static JWTCreator.Builder create() { - return JWTCreator.init(); - } - - //----------------this is from JWTVerifier-------- - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a JWT.BaseVerification instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new JWT.BaseVerification(algorithm); - } - - /** - * The Verification class holds the Claims required by a JWT to be valid. - */ - public static class BaseVerification implements Verification { - protected final Algorithm algorithm; - protected final Map claims; - private long defaultLeeway; - - BaseVerification(Algorithm algorithm) throws IllegalArgumentException { - if (algorithm == null) { - throw new IllegalArgumentException("The Algorithm cannot be null."); - } - - this.algorithm = algorithm; - this.claims = new HashMap<>(); - this.defaultLeeway = 0; - } - - @Override - public Verification withNbf(long nbf) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification createVerifierForRisc(String jti, List issuer, - List audience, long iatLeeway, long expLeeway, long nbf) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification createVerifierForScoped(String scope, List issuer, List audience, long expLeeway, long iatLeeway) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification createVerifierForImplicit(List issuer, List audience, long iatLeeway) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification createVerifierForFb(String userId, String appId) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification withUserId(String userId) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification withAppId(String appId) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - @Override - public Verification createVerifierForAccess(List issuer, List audience, long expLeeway, long iatLeeway) { - throw new UnsupportedOperationException("you shouldn't be calling this method"); - } - - /** - * Require a specific Issuer ("iss") claim. - * Allows for multiple issuers - * - * @param issuer the required Issuer value - * @return this same Verification instance. - */ - @Override - public Verification withIssuer(String... issuer) { - requireClaim(PublicClaims.ISSUER, Arrays.asList(issuer)); - return this; - } - - /** - * Require a specific Subject ("sub") claim. - * Allows for multiple subjects - * - * @param subject the required Subject value - * @return this same Verification instance. - */ - @Override - public Verification withSubject(String... subject) { - requireClaim(PublicClaims.SUBJECT, Arrays.asList(subject)); - return this; - } - - /** - * Require a specific Audience ("aud") claim. - * Allows for multiple audience - * - * @param audience the required Audience value - * @return this same Verification instance. - */ - @Override - public Verification withAudience(String... audience) { - requireClaim(PublicClaims.AUDIENCE, Arrays.asList(audience)); - return this; - } - - /** - * Define the default window in seconds in which the Not Before, Issued At and Expires At Claims will still be valid. - * Setting a specific leeway value on a given Claim will override this value for that Claim. - * - * @param leeway the window in seconds in which the Not Before, Issued At and Expires At Claims will still be valid. - * @return this same Verification instance. - * @throws IllegalArgumentException if leeway is negative. - */ - @Override - public Verification acceptLeeway(long leeway) throws IllegalArgumentException { - VerificationAndAssertion.assertPositive(leeway); - this.defaultLeeway = leeway; - return this; - } - - /** - * Set a specific leeway window in seconds in which the Expires At ("exp") Claim will still be valid. - * Expiration Date is always verified when the value is present. This method overrides the value set with acceptLeeway - * - * @param leeway the window in seconds in which the Expires At Claim will still be valid. - * @return this same Verification instance. - * @throws IllegalArgumentException if leeway is negative. - */ - @Override - public Verification acceptExpiresAt(long leeway) throws IllegalArgumentException { - VerificationAndAssertion.assertPositive(leeway); - requireClaim(PublicClaims.EXPIRES_AT, leeway); - return this; - } - - /** - * Set a specific leeway window in seconds in which the Not Before ("nbf") Claim will still be valid. - * Not Before Date is always verified when the value is present. This method overrides the value set with acceptLeeway - * - * @param leeway the window in seconds in which the Not Before Claim will still be valid. - * @return this same Verification instance. - * @throws IllegalArgumentException if leeway is negative. - */ - @Override - public Verification acceptNotBefore(long leeway) throws IllegalArgumentException { - VerificationAndAssertion.assertPositive(leeway); - requireClaim(PublicClaims.NOT_BEFORE, leeway); - return this; - } - - /** - * Set a specific leeway window in seconds in which the Issued At ("iat") Claim will still be valid. - * Issued At Date is always verified when the value is present. This method overrides the value set with acceptLeeway - * - * @param leeway the window in seconds in which the Issued At Claim will still be valid. - * @return this same Verification instance. - * @throws IllegalArgumentException if leeway is negative. - */ - @Override - public Verification acceptIssuedAt(long leeway) throws IllegalArgumentException { - VerificationAndAssertion.assertPositive(leeway); - requireClaim(PublicClaims.ISSUED_AT, leeway); - return this; - } - - /** - * Require a specific JWT Id ("jti") claim. - * - * @param jwtId the required Id value - * @return this same Verification instance. - */ - @Override - public Verification withJWTId(String jwtId) { - requireClaim(PublicClaims.JWT_ID, jwtId); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, Boolean value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, Integer value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, Long value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, Double value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, String value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Claim value. - * - * @param name the Claim's name. - * @param value the Claim's value. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withNonStandardClaim(String name, Date value) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, value); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withArrayClaim(String name, String... items) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, items); - return this; - } - - /** - * Require a specific Array Claim to contain at least the given items. - * - * @param name the Claim's name. - * @param items the items the Claim must contain. - * @return this same Verification instance. - * @throws IllegalArgumentException if the name is null. - */ - @Override - public Verification withArrayClaim(String name, Integer... items) throws IllegalArgumentException { - VerificationAndAssertion.assertNonNull(name); - requireClaim(name, items); - return this; - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } - - protected void addLeewayToDateClaims() { - if (!claims.containsKey(PublicClaims.EXPIRES_AT)) { - claims.put(PublicClaims.EXPIRES_AT, defaultLeeway); - } - if (!claims.containsKey(PublicClaims.NOT_BEFORE)) { - claims.put(PublicClaims.NOT_BEFORE, defaultLeeway); - } - if (!claims.containsKey(PublicClaims.ISSUED_AT)) { - claims.put(PublicClaims.ISSUED_AT, defaultLeeway); - } - } - - protected void requireClaim(String name, Object value) { - if (value == null) { - claims.remove(name); - return; - } - claims.put(name, value); - } - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/RiscJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/RiscJWT.java deleted file mode 100644 index 5d126b8..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/RiscJWT.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class RiscJWT extends JWT.BaseVerification implements Verification { - - RiscJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @param jti - * @param issuer - * @param audience - * @param iatLeeway - * @param expLeeway - * @return - */ - public Verification createVerifierForRisc(String jti, List issuer, - List audience, long iatLeeway, long expLeeway, long nbf) { - Verification verification = withJWTId(jti).withIssuer(issuer.toArray(new String[issuer.size()])).acceptIssuedAt(iatLeeway); - - if(audience != null && !audience.isEmpty()) { - verification.withAudience(audience.toArray(new String[audience.size()])); - } - - if(nbf >= 0) { - verification.acceptNotBefore(iatLeeway); - } - - if(expLeeway >= 0) { - verification.acceptExpiresAt(expLeeway); - } - - return verification; - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return RiscJWT.init(algorithm); - } - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a RiscJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new RiscJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/jwts/ScopedJWT.java b/lib/src/main/java/com/auth0/jwt/jwts/ScopedJWT.java deleted file mode 100644 index 0354502..0000000 --- a/lib/src/main/java/com/auth0/jwt/jwts/ScopedJWT.java +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.jwts; - -import com.auth0.jwt.ClockImpl; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.Verification; - -import java.util.List; - -public class ScopedJWT extends JWT.BaseVerification implements Verification{ - - ScopedJWT(Algorithm algorithm) throws IllegalArgumentException { - super(algorithm); - } - - /** - * Create Verification object for verification purposes - * @issuer scope - * @param issuer - * @param audience - * @return - */ - public Verification createVerifierForScoped(String scope, List issuer, - List audience, long expLeeway, long iatLeeway) { - return withScope(scope).withIssuer(issuer.toArray(new String[issuer.size()])).withAudience(audience.toArray(new String[audience.size()])) - .acceptExpiresAt(expLeeway).acceptIssuedAt(iatLeeway); - } - - /** - * Require a specific Scope ("scope") claim. - * - * @param scope the required Scope value - * @return this same Verification instance. - */ - public Verification withScope(String scope) { - requireClaim("scope", scope); - return this; - } - - /** - * Returns a {Verification} to be used to validate token signature. - * - * @param algorithm that will be used to verify the token's signature. - * @return Verification - * @throws IllegalArgumentException if the provided algorithm is null. - */ - public static Verification require(Algorithm algorithm) { - return ScopedJWT.init(algorithm); - } - - /** - * Initialize a Verification instance using the given Algorithm. - * - * @param algorithm the Algorithm to use on the JWT verification. - * @return a ScopedJWT instance to configure. - * @throws IllegalArgumentException if the provided algorithm is null. - */ - static Verification init(Algorithm algorithm) throws IllegalArgumentException { - return new ScopedJWT(algorithm); - } - - /** - * Creates a new and reusable instance of the JWT with the configuration already provided. - * - * @return a new JWT instance. - */ - @Override - public JWT build() { - return this.build(new ClockImpl()); - } - - /** - * Creates a new and reusable instance of the JWT the configuration already provided. - * ONLY FOR TEST PURPOSES. - * - * @param clock the instance that will handle the current time. - * @return a new JWT instance with a custom Clock. - */ - public JWT build(Clock clock) { - addLeewayToDateClaims(); - return new JWT(algorithm, claims, clock); - } -} diff --git a/lib/src/main/java/com/auth0/jwt/verification/VerificationAndAssertion.java b/lib/src/main/java/com/auth0/jwt/verification/VerificationAndAssertion.java deleted file mode 100644 index f8fff86..0000000 --- a/lib/src/main/java/com/auth0/jwt/verification/VerificationAndAssertion.java +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.verification; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.DecodedJWT; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; - -public class VerificationAndAssertion { - - public static void assertPositive(long leeway) { - if (leeway < 0) { - throw new IllegalArgumentException("Leeway value can't be negative."); - } - } - - public static void assertNonNull(String name) { - if (name == null) { - throw new IllegalArgumentException("The Custom Claim's name can't be null."); - } - } - - public static void verifyAlgorithm(DecodedJWT jwt, Algorithm expectedAlgorithm) throws AlgorithmMismatchException { - if (!expectedAlgorithm.getName().equals(jwt.getAlgorithm())) { - throw new AlgorithmMismatchException("The provided Algorithm doesn't match the one defined in the JWT's Header."); - } - } - - public static void verifyClaims(Clock clock, DecodedJWT jwt, Map claims) throws TokenExpiredException, InvalidClaimException { - for (Map.Entry entry : claims.entrySet()) { - switch (entry.getKey()) { - case PublicClaims.AUDIENCE: - //noinspection unchecked - VerificationAndAssertion.assertValidAudienceClaim(jwt.getAudience(), (List) entry.getValue()); - break; - case PublicClaims.EXPIRES_AT: - assertValidDateClaim(clock, jwt.getExpiresAt(), (Long) entry.getValue(), true); - break; - case PublicClaims.ISSUED_AT: - assertValidDateClaim(clock, jwt.getIssuedAt(), (Long) entry.getValue(), false); - break; - case PublicClaims.NOT_BEFORE: - assertValidDateClaim(clock, jwt.getNotBefore(), (Long) entry.getValue(), false); - break; - case PublicClaims.ISSUER: - VerificationAndAssertion.assertValidIssuerClaim(jwt.getIssuer(), (List) entry.getValue()); - break; - case PublicClaims.JWT_ID: - VerificationAndAssertion.assertValidStringClaim(entry.getKey(), jwt.getId(), (String) entry.getValue()); - break; - default: - VerificationAndAssertion.assertValidClaim(jwt.getClaim(entry.getKey()), entry.getKey(), entry.getValue()); - break; - } - } - } - - private static void assertValidDateClaim(Clock clock, Date date, long leeway, boolean shouldBeFuture) { - Date today = clock.getToday(); - today.setTime((long) Math.floor((today.getTime() / 1000) * 1000)); // truncate millis - if (shouldBeFuture) { - VerificationAndAssertion.assertDateIsFuture(date, leeway, today); - } else { - VerificationAndAssertion.assertDateIsPast(date, leeway, today); - } - } - - private static void assertValidClaim(Claim claim, String claimName, Object value) { - boolean isValid = false; - if (value instanceof String) { - isValid = value.equals(claim.asString()); - } else if (value instanceof Integer) { - isValid = value.equals(claim.asInt()); - } else if (value instanceof Long) { - isValid = value.equals(claim.asLong()); - } else if (value instanceof Boolean) { - isValid = value.equals(claim.asBoolean()); - } else if (value instanceof Double) { - isValid = value.equals(claim.asDouble()); - } else if (value instanceof Date) { - isValid = value.equals(claim.asDate()); - } else if (value instanceof Object[]) { - List claimArr = Arrays.asList(claim.as(Object[].class)); - List valueArr = Arrays.asList((Object[]) value); - isValid = claimArr.containsAll(valueArr); - } - - if (!isValid) { - throw new InvalidClaimException(String.format("The Claim '%s' value doesn't match the required one.", claimName)); - } - } - - private static void assertValidStringClaim(String claimName, String value, String expectedValue) { - if (!expectedValue.equals(value)) { - throw new InvalidClaimException(String.format("The Claim '%s' value doesn't match the required one.", claimName)); - } - } - - private static void assertDateIsFuture(Date date, long leeway, Date today) { - today.setTime(today.getTime() - leeway * 1000); - if (date != null && today.after(date)) { - throw new TokenExpiredException(String.format("The Token has expired on %s.", date)); - } - } - - private static void assertDateIsPast(Date date, long leeway, Date today) { - today.setTime(today.getTime() + leeway * 1000); - if (date != null && today.before(date)) { - throw new InvalidClaimException(String.format("The Token can't be used before %s.", date)); - } - } - - private static void assertValidAudienceClaim(List audience, List value) { - if (audience == null || !audience.containsAll(value) || audience.size() != value.size()) { - throw new InvalidClaimException("The Claim 'aud' value doesn't contain the required audience."); - } - } - - private static void assertValidIssuerClaim(List issuer, List value) { - if (issuer == null || !issuer.containsAll(value) || issuer.size() != value.size()) { - throw new InvalidClaimException("The Claim 'iss' value doesn't match the required one."); - } - } -} diff --git a/lib/src/test/java/com/auth0/jwt/ClockImplTest.java b/lib/src/test/java/com/auth0/jwt/ClockImplTest.java deleted file mode 100644 index 6fdb01b..0000000 --- a/lib/src/test/java/com/auth0/jwt/ClockImplTest.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.interfaces.Clock; -import org.junit.Test; - -import java.util.Date; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.*; - -public class ClockImplTest { - - @Test - public void shouldGetToday() throws Exception{ - Clock clock = new ClockImpl(); - Date clockToday = clock.getToday(); - assertThat(clockToday, is(notNullValue())); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/ConcurrentVerifyTest.java b/lib/src/test/java/com/auth0/jwt/ConcurrentVerifyTest.java deleted file mode 100644 index 64120dd..0000000 --- a/lib/src/test/java/com/auth0/jwt/ConcurrentVerifyTest.java +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.jwts.JWT; -import net.jodah.concurrentunit.Waiter; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.security.interfaces.ECKey; -import java.security.interfaces.RSAKey; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.*; - -import static com.auth0.jwt.PemUtils.readPublicKeyFromFile; - -//@Ignore("Skipping concurrency tests") -public class ConcurrentVerifyTest { - - private static final long TIMEOUT = 10 * 1000 * 1000; //1 min - private static final int THREAD_COUNT = 100; - private static final int REPEAT_COUNT = 1000; - private static final String PUBLIC_KEY_FILE = "src/test/resources/rsa-public.pem"; - private static final String PUBLIC_KEY_FILE_256 = "src/test/resources/ec256-key-public.pem"; - private static final String PUBLIC_KEY_FILE_384 = "src/test/resources/ec384-key-public.pem"; - private static final String PUBLIC_KEY_FILE_512 = "src/test/resources/ec512-key-public.pem"; - - @Rule - public ExpectedException exception = ExpectedException.none(); - private static ExecutorService executor; - - @BeforeClass - public static void beforeAll() throws Exception { - executor = Executors.newFixedThreadPool(THREAD_COUNT); - } - - @AfterClass - public static void afterAll() throws Exception { - executor.shutdown(); - } - - @SuppressWarnings("Convert2Lambda") - private void concurrentVerify(final JWT jwt, final String token) throws TimeoutException, InterruptedException { - final Waiter waiter = new Waiter(); - List tasks = Collections.nCopies(REPEAT_COUNT, new VerifyTask(waiter, jwt, token)); - executor.invokeAll(tasks, TIMEOUT, TimeUnit.MILLISECONDS); - waiter.await(TIMEOUT, REPEAT_COUNT); - } - - private static class VerifyTask implements Callable { - - private final Waiter waiter; - private final JWT jwt; - private final String token; - - VerifyTask(Waiter waiter, final JWT jwt, final String token) { - this.waiter = waiter; - this.jwt = jwt; - this.token = token; - } - - @Override - public DecodedJWT call() throws Exception { - DecodedJWT decodedJWT = null; - try { - decodedJWT = jwt.decode(token); - waiter.assertNotNull(decodedJWT); - } catch (Exception e) { - waiter.fail(e); - } - waiter.resume(); - return decodedJWT; - } - } - - @Test - public void shouldPassHMAC256Verification() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M"; - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassHMAC384Verification() throws Exception { - String token = "eyJhbGciOiJIUzM4NCIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.uztpK_wUMYJhrRv8SV-1LU4aPnwl-EM1q-wJnqgyb5DHoDteP6lN_gE1xnZJH5vw"; - Algorithm algorithm = Algorithm.HMAC384("secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassHMAC512Verification() throws Exception { - String token = "eyJhbGciOiJIUzUxMiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.VUo2Z9SWDV-XcOc_Hr6Lff3vl7L9e5Vb8ThXpmGDFjHxe3Dr1ZBmUChYF-xVA7cAdX1P_D4ZCUcsv3IefpVaJw"; - Algorithm algorithm = Algorithm.HMAC512("secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassRSA256Verification() throws Exception { - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassRSA384Verification() throws Exception { - String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; - Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassRSA512Verification() throws Exception { - String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; - Algorithm algorithm = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassECDSA256VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - Algorithm algorithm = Algorithm.ECDSA256(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassECDSA384VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.50UU5VKNdF1wfykY8jQBKpvuHZoe6IZBJm5NvoB8bR-hnRg6ti-CHbmvoRtlLfnHfwITa_8cJMy6TenMC2g63GQHytc8rYoXqbwtS4R0Ko_AXbLFUmfxnGnMC6v4MS_z"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - Algorithm algorithm = Algorithm.ECDSA384(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - - @Test - public void shouldPassECDSA512VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AeCJPDIsSHhwRSGZCY6rspi8zekOw0K9qYMNridP1Fu9uhrA1QrG-EUxXlE06yvmh2R7Rz0aE7kxBwrnq8L8aOBCAYAsqhzPeUvyp8fXjjgs0Eto5I0mndE2QHlgcMSFASyjHbU8wD2Rq7ZNzGQ5b2MZfpv030WGUajT-aZYWFUJHVg2"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - Algorithm algorithm = Algorithm.ECDSA512(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - - concurrentVerify(jwt, token); - } - -} diff --git a/lib/src/test/java/com/auth0/jwt/JWTDecoderTest.java b/lib/src/test/java/com/auth0/jwt/JWTDecoderTest.java deleted file mode 100644 index 8ff3844..0000000 --- a/lib/src/test/java/com/auth0/jwt/JWTDecoderTest.java +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.hamcrest.collection.IsCollectionWithSize; -import org.hamcrest.core.IsCollectionContaining; -import org.junit.Assert; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.Map; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -public class JWTDecoderTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void getSubject() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).withNonStandardClaim("admin", true).withNonStandardClaim("name", "John Doe").build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT.getSubject(), is(notNullValue())); - assertTrue(decodedJWT.getSubject().contains("1234567890")); - } - - // Exceptions - @Test - public void shouldThrowIfLessThan3Parts() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The token was expected to have 3 parts, but got 2."); - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).withNonStandardClaim("admin", true).withNonStandardClaim("name", "John Doe").build(); - DecodedJWT decodedJWT = jwt.decode("two.parts"); - } - - @Test - public void shouldThrowIfMoreThan3Parts() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The token was expected to have 3 parts, but got 4."); - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).withNonStandardClaim("admin", true).withNonStandardClaim("name", "John Doe").build(); - DecodedJWT decodedJWT = jwt.decode("this.has.four.parts"); - } - - @Test - public void shouldThrowIfPayloadHasInvalidJSONFormat() throws Exception { - String validJson = "{}"; - String invalidJson = "}{"; - exception.expect(JWTDecodeException.class); - exception.expectMessage(String.format("The string '%s' doesn't have a valid JSON format.", invalidJson)); - customJWT(validJson, invalidJson, "signature"); - } - - @Test - public void shouldThrowIfHeaderHasInvalidJSONFormat() throws Exception { - String validJson = "{}"; - String invalidJson = "}{"; - exception.expect(JWTDecodeException.class); - exception.expectMessage(String.format("The string '%s' doesn't have a valid JSON format.", invalidJson)); - customJWT(invalidJson, validJson, "signature"); - } - - // Parts - - @Test - public void shouldGetStringToken() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getToken(), is(notNullValue())); - assertThat(decodedJWT.getToken(), is("eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ")); - } - - @Test - public void shouldGetHeader() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getHeader(), is("eyJhbGciOiJIUzI1NiJ9")); - } - - @Test - public void shouldGetPayload() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getPayload(), is("e30")); - } - - @Test - public void shouldGetSignature() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getSignature(), is("XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ")); - } - - // Public PublicClaims - - @Test - public void shouldGetIssuer() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJKb2huIERvZSJ9.SgXosfRR_IwCgHq5lF3tlM-JHtpucWCRSaVuoHTbWbQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertTrue(decodedJWT.getIssuer().contains("John Doe")); - } - - @Test - public void shouldGetSubject() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJUb2szbnMifQ.RudAxkslimoOY3BLl2Ghny3BrUKu9I1ZrXzCZGDJtNs"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertTrue(decodedJWT.getSubject().contains("Tok3ns")); - } - - @Test - public void shouldGetArrayAudience() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiSG9wZSIsIlRyYXZpcyIsIlNvbG9tb24iXX0.Tm4W8WnfPjlmHSmKFakdij0on2rWPETpoM7Sh0u6-S4"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getAudience(), is(IsCollectionWithSize.hasSize(3))); - assertThat(decodedJWT.getAudience(), is(IsCollectionContaining.hasItems("Hope", "Travis", "Solomon"))); - } - - @Test - public void shouldGetStringAudience() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJKYWNrIFJleWVzIn0.a4I9BBhPt1OB1GW67g2P1bEHgi6zgOjGUL4LvhE9Dgc"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getAudience(), is(IsCollectionWithSize.hasSize(1))); - assertThat(decodedJWT.getAudience(), is(IsCollectionContaining.hasItems("Jack Reyes"))); - } - - @Test - public void shouldGetExpirationTime() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NzY3MjcwODZ9.L9dcPHEDQew2u9MkDCORFkfDGcSOsgoPqNY-LUMLEHg"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).acceptExpiresAt(1476727086).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getExpiresAt(), is(instanceOf(Date.class))); - long ms = 1476727086L * 1000; - Date expectedDate = new Date(ms); - assertThat(decodedJWT.getExpiresAt(), is(notNullValue())); - assertThat(decodedJWT.getExpiresAt(), is(equalTo(expectedDate))); - } - - @Test - public void shouldGetNotBefore() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE0NzY3MjcwODZ9.tkpD3iCPQPVqjnjpDVp2bJMBAgpVCG9ZjlBuMitass0"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).acceptNotBefore(1476727086).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getNotBefore(), is(instanceOf(Date.class))); - long ms = 1476727086L * 1000; - Date expectedDate = new Date(ms); - assertThat(decodedJWT.getNotBefore(), is(notNullValue())); - assertThat(decodedJWT.getNotBefore(), is(equalTo(expectedDate))); - } - - @Test - public void shouldGetIssuedAt() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NzY3MjcwODZ9.KPjGoW665E8V5_27Jugab8qSTxLk2cgquhPCBfAP0_w"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).acceptIssuedAt(1476727086).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getIssuedAt(), is(instanceOf(Date.class))); - long ms = 1476727086L * 1000; - Date expectedDate = new Date(ms); - assertThat(decodedJWT.getIssuedAt(), is(notNullValue())); - assertThat(decodedJWT.getIssuedAt(), is(equalTo(expectedDate))); - } - - @Test - public void shouldGetId() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMjM0NTY3ODkwIn0.m3zgEfVUFOd-CvL3xG5BuOWLzb0zMQZCqiVNQQOPOvA"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getId(), is("1234567890")); - } - - @Test - public void shouldGetContentType() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6ImF3ZXNvbWUifQ.e30.AIm-pJDOaAyct9qKMlN-lQieqNDqc3d4erqUZc5SHAs"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getContentType(), is("awesome")); - } - - @Test - public void shouldGetType() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.e30.WdFmrzx8b9v_a-r6EHC2PTAaWywgm_8LiP8RBRhYwkI"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getType(), is("JWS")); - } - - @Test - public void shouldGetAlgorithm() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.e30.XmNK3GpH3Ys_7wsYBfq4C3M6goz71I7dTgUkuIa5lyQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getAlgorithm(), is("HS256")); - } - - //Private PublicClaims - - - @Test - public void shouldGetValidClaim() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJvYmplY3QiOnsibmFtZSI6ImpvaG4ifX0.lrU1gZlOdlmTTeZwq0VI-pZx2iV46UWYd5-lCjy6-c4"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getClaim("object"), is(notNullValue())); - assertThat(decodedJWT.getClaim("object"), is(instanceOf(Claim.class))); - } - - - @Test - public void shouldNotGetNullClaimIfClaimIsEmptyObject() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJvYmplY3QiOnt9fQ.d3nUeeL_69QsrHL0ZWij612LHEQxD8EZg1rNoY3a4aI"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - assertThat(decodedJWT.getClaim("object"), is(notNullValue())); - assertThat(decodedJWT.getClaim("object").isNull(), is(false)); - } - - @Test - public void shouldGetCustomClaimOfTypeInteger() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoxMjN9.XZAudnA7h3_Al5kJydzLjw6RzZC3Q6OvnLEYlhNW7HA"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asInt(), is(123)); - } - - @Test - public void shouldGetCustomClaimOfTypeDouble() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoyMy40NX0.7pyX2OmEGaU9q15T8bGFqRm-d3RVTYnqmZNZtxMKSlA"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asDouble(), is(23.45)); - } - - @Test - public void shouldGetCustomClaimOfTypeBoolean() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjp0cnVlfQ.FwQ8VfsZNRqBa9PXMinSIQplfLU4-rkCLfIlTLg_MV0"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asBoolean(), is(true)); - } - - @Test - public void shouldGetCustomClaimOfTypeDate() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoxNDc4ODkxNTIxfQ.mhioumeok8fghQEhTKF3QtQAksSvZ_9wIhJmgZLhJ6c"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Date date = new Date(1478891521000L); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asDate().getTime(), is(date.getTime())); - } - - @Test - public void shouldGetCustomArrayClaimOfTypeString() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjpbInRleHQiLCIxMjMiLCJ0cnVlIl19.lxM8EcmK1uSZRAPd0HUhXGZJdauRmZmLjoeqz4J9yAA"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asArray(String.class), arrayContaining("text", "123", "true")); - } - - @Test - public void shouldGetCustomArrayClaimOfTypeInteger() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjpbMSwyLDNdfQ.UEuMKRQYrzKAiPpPLhIVawWkKWA1zj0_GderrWUIyFE"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Assert.assertThat(decodedJWT.getClaim("name").asArray(Integer.class), arrayContaining(1, 2, 3)); - } - - @Test - public void shouldGetCustomMapClaim() throws Exception { - String token = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjp7InN0cmluZyI6InZhbHVlIiwibnVtYmVyIjoxLCJib29sZWFuIjp0cnVlfX0.-8aIaXd2-rp1lLuDEQmCeisCBX9X_zbqdPn2llGxNoc"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - Assert.assertThat(decodedJWT, is(notNullValue())); - Map map = decodedJWT.getClaim("name").asMap(); - Assert.assertThat(map, hasEntry("string", (Object) "value")); - Assert.assertThat(map, hasEntry("number", (Object) 1)); - Assert.assertThat(map, hasEntry("boolean", (Object) true)); - } - - @Test - public void shouldGetAvailableClaims() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwiaWF0IjoiMTIzNDU2Nzg5MCIsIm5iZiI6IjEyMzQ1Njc4OTAiLCJqdGkiOiJodHRwczovL2p3dC5pby8iLCJhdWQiOiJodHRwczovL2RvbWFpbi5hdXRoMC5jb20iLCJzdWIiOiJsb2dpbiIsImlzcyI6ImF1dGgwIiwiZXh0cmFDbGFpbSI6IkpvaG4gRG9lIn0.TX9Ct4feGp9YyeGK9Zl91tO0YBOrguJ4As9jeqgHdZQ"; - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(token); - assertThat(decodedJWT, is(notNullValue())); - Map claims = decodedJWT.getClaims(); - assertThat(claims, is(notNullValue())); - assertThat(claims, is(instanceOf(Map.class))); - assertThat(claims.get("exp"), is(notNullValue())); - assertThat(claims.get("iat"), is(notNullValue())); - assertThat(claims.get("nbf"), is(notNullValue())); - assertThat(claims.get("jti"), is(notNullValue())); - assertThat(claims.get("aud"), is(notNullValue())); - assertThat(claims.get("sub"), is(notNullValue())); - assertThat(claims.get("iss"), is(notNullValue())); - assertThat(claims.get("extraClaim"), is(notNullValue())); - } - - //Helper Methods - - private DecodedJWT customJWT(String jsonHeader, String jsonPayload, String signature) throws Exception{ - String header = Base64.encodeBase64URLSafeString(jsonHeader.getBytes(StandardCharsets.UTF_8)); - String body = Base64.encodeBase64URLSafeString(jsonPayload.getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(Algorithm.HMAC256("secret")).build(); - DecodedJWT decodedJWT = jwt.decode(String.format("%s.%s.%s", header, body, signature)); - return decodedJWT; - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/JWTTest.java b/lib/src/test/java/com/auth0/jwt/JWTTest.java deleted file mode 100644 index b368d43..0000000 --- a/lib/src/test/java/com/auth0/jwt/JWTTest.java +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.Clock; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.hamcrest.collection.IsCollectionWithSize; -import org.hamcrest.core.IsCollectionContaining; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.interfaces.ECKey; -import java.security.interfaces.RSAKey; -import java.util.Date; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class JWTTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void testWithNbf() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).withNbf(5); - } - - @Test - public void testCreateVerifierForRisc() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).createVerifierForRisc(null, null, null, 5, 5, 5); - } - - @Test - public void testCreateVerifierForScoped() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).createVerifierForScoped(null, null, null, 5, 5); - } - - @Test - public void testCreateVerifierForImplicit() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).createVerifierForImplicit(null, null, 5); - } - - @Test - public void testCreateVerifierForFB() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).createVerifierForFb(null, null); - } - - @Test - public void testCreateVerifierForAccess() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).createVerifierForAccess(null, null, 5, 5); - } - - @Test - public void testWithUserId() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).withUserId(null); - } - - @Test - public void testWithAppId() { - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - JWT.require(Algorithm.none()).withAppId(null); - } - - @Test - public void testWithSubjectId() { - JWT.require(Algorithm.none()).withSubject("subject1", "subject2"); - } - - @Test - public void testAcceptLeeway() { - JWT.require(Algorithm.none()).acceptLeeway(5); - } - - @Test - public void testAcceptNotBefore() { - JWT.require(Algorithm.none()).acceptNotBefore(5); - } - - @Test - public void testWithJWTId() { - JWT.require(Algorithm.none()).withJWTId("jwtId"); - } - - @Test - public void testJWTNonStandardClaimBoolean() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", true); - } - - @Test - public void testJWTNonStandardClaimInteger() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", 5); - } - - @Test - public void testJWTNonStandardClaimLong() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", 5L); - } - - @Test - public void testJWTNonStandardClaimDouble() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", 9.99); - } - - @Test - public void testJWTNonStandardClaimString() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue"); - } - - @Test - public void testJWTNonStandardClaimDate() throws Exception { - JWT.require(Algorithm.none()).withNonStandardClaim("nonStandardClaim", new Date()); - } - - @Test - public void testJWTWithArrayClaimStrings() throws Exception { - JWT.require(Algorithm.none()).withArrayClaim("arrayKey", "arrayValue1", "arrayValue2"); - } - - @Test - public void testJWTWithArrayClaimIntegers() throws Exception { - JWT.require(Algorithm.none()).withArrayClaim("arrayKey", 1, 2).build(); - } - - @Test - public void testJWTNullAlgorithm() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("The Algorithm cannot be null."); - JWT.require(null); - } -} diff --git a/lib/src/test/java/com/auth0/jwt/JsonMatcher.java b/lib/src/test/java/com/auth0/jwt/JsonMatcher.java deleted file mode 100644 index 8a79a23..0000000 --- a/lib/src/test/java/com/auth0/jwt/JsonMatcher.java +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeDiagnosingMatcher; - -import java.lang.reflect.Array; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class JsonMatcher extends TypeSafeDiagnosingMatcher { - - private final String entry; - private final String key; - private final Matcher matcher; - - private JsonMatcher(String key, Object value, Matcher valueMatcher) { - this.key = key; - this.matcher = valueMatcher; - if (value != null) { - String stringValue = objectToString(value); - entry = getStringKey(key) + stringValue; - } else { - entry = null; - } - } - - @Override - protected boolean matchesSafely(String item, Description mismatchDescription) { - if (item == null) { - mismatchDescription.appendText("JSON was null"); - return false; - } - if (matcher != null) { - if (!matcher.matches(item)) { - matcher.describeMismatch(item, mismatchDescription); - return false; - } - if (!item.contains(getStringKey(key))) { - mismatchDescription.appendText("JSON didn't contained the key ").appendValue(key); - return false; - } - } - if (entry != null && !item.contains(entry)) { - mismatchDescription.appendText("JSON was ").appendValue(item); - return false; - } - - return true; - } - - @Override - public void describeTo(Description description) { - if (matcher == null) { - description.appendText("A JSON with entry ") - .appendValue(entry); - } else { - matcher.describeTo(description); - } - } - - public static JsonMatcher hasEntry(String key, Object value) { - return new JsonMatcher(key, value, null); - } - - public static JsonMatcher hasEntry(String key, Matcher valueMatcher) { - return new JsonMatcher(key, null, valueMatcher); - } - - private String getStringKey(String key) { - return "\"" + key + "\":"; - } - - private String objectToString(Object value) { - String stringValue; - if (value == null) { - stringValue = "null"; - } else if (value instanceof String) { - stringValue = "\"" + value + "\""; - } else if (value instanceof Map) { - stringValue = mapToString((Map) value); - } else if (value instanceof Array) { - stringValue = arrayToString((Object[]) value); - } else if (value instanceof List) { - stringValue = listToString((List) value); - } else { - stringValue = value.toString(); - } - return stringValue; - } - - private String arrayToString(Object[] array) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (int i = 0; i < array.length; i++) { - Object o = array[i]; - sb.append(objectToString(o)); - if (i + 1 < array.length) { - sb.append(","); - } - } - sb.append("]"); - return sb.toString(); - } - - private String listToString(List list) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - Iterator it = list.iterator(); - while (it.hasNext()) { - Object o = it.next(); - sb.append(objectToString(o)); - if (it.hasNext()) { - sb.append(","); - } - } - sb.append("]"); - return sb.toString(); - } - - private String mapToString(Map map) { - StringBuilder sb = new StringBuilder(); - sb.append("{"); - Iterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry e = it.next(); - sb.append("\"" + e.getKey() + "\":" + objectToString(e.getValue())); - if (it.hasNext()) { - sb.append(","); - } - } - sb.append("}"); - return sb.toString(); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/MainTestSignatures.java b/lib/src/test/java/com/auth0/jwt/MainTestSignatures.java deleted file mode 100644 index bc298eb..0000000 --- a/lib/src/test/java/com/auth0/jwt/MainTestSignatures.java +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.GoogleJwtCreator; -import com.auth0.jwt.creators.GoogleJwtCreatorTest; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.GoogleVerification; -import com.auth0.jwt.jwts.GoogleJWT; -import com.auth0.jwt.jwts.JWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -public class MainTestSignatures { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private Date exp = generateRandomExpDateInFuture(); - private Date iat = generateRandomIatDateInPast(); - - @Test - public void testComplainOnNone() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("The Algorithm cannot be null."); - - String token = JWT.create().withIssuer("accounts.fake.com").withSubject("subject") - .withAudience("audience") - .sign(null); - GoogleVerification verification = GoogleJWT.require(null); - JWT verifier = verification.createVerifierForGoogle(GoogleJwtCreatorTest.PICTURE, GoogleJwtCreatorTest.EMAIL, asList("accounts.fake.com"), asList("audience"), - GoogleJwtCreatorTest.NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testVerifyingWithEmptyKey() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Empty key"); - Algorithm algorithm = Algorithm.HMAC256(""); - String token = GoogleJwtCreator.build() - .withPicture(GoogleJwtCreatorTest.PICTURE) - .withEmail(GoogleJwtCreatorTest.EMAIL) - .withIssuer("accounts.fake.com") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(GoogleJwtCreatorTest.NAME) - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(GoogleJwtCreatorTest.PICTURE, GoogleJwtCreatorTest.EMAIL,asList("accounts.fake.com"), asList("audience"), - GoogleJwtCreatorTest.NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testConfigurableToMultipleKeys() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(GoogleJwtCreatorTest.PICTURE) - .withEmail(GoogleJwtCreatorTest.EMAIL) - .withSubject("subject", "subject2") - .withAudience("audience", "audience2") - .withExp(exp) - .withIat(iat) - .withName(GoogleJwtCreatorTest.NAME) - .withIssuer("issuer", "issuer2") - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(GoogleJwtCreatorTest.PICTURE, GoogleJwtCreatorTest.EMAIL, asList("issuer", "issuer2"), asList("audience", "audience2"), - GoogleJwtCreatorTest.NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - assertTrue(claims.get(GoogleJwtCreatorTest.PICTURE).asString().equals(GoogleJwtCreatorTest.PICTURE)); - assertTrue(claims.get(GoogleJwtCreatorTest.EMAIL).asString().equals(GoogleJwtCreatorTest.EMAIL)); - List issuers = claims.get(PublicClaims.ISSUER).asList(String.class); - assertTrue(issuers.get(0).equals("issuer")); - assertTrue(issuers.get(1).equals("issuer2")); - List subjects = claims.get(PublicClaims.SUBJECT).asList(String.class); - assertTrue(subjects.get(0).equals("subject")); - assertTrue(subjects.get(1).equals("subject2")); - List audience = claims.get(PublicClaims.AUDIENCE).asList(String.class); - assertTrue(audience.get(0).equals("audience")); - assertTrue(audience.get(1).equals("audience2")); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - assertTrue(claims.get(GoogleJwtCreatorTest.NAME).asString().equals(GoogleJwtCreatorTest.NAME)); - } - - @Test - public void testConfigurableToIncorrectNumberMultipleKeysForAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String[] arr = {"accounts.fake.com", "subject"}; - String token = GoogleJwtCreator.build() - .withPicture(GoogleJwtCreatorTest.PICTURE) - .withEmail(GoogleJwtCreatorTest.EMAIL) - .withSubject("subject", "subject2") - .withAudience("audience", "audience2") - .withExp(exp) - .withIat(iat) - .withName(GoogleJwtCreatorTest.NAME) - .withIssuer("issuer", "issuer2") - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(GoogleJwtCreatorTest.PICTURE, GoogleJwtCreatorTest.EMAIL, asList("issuer", "issuer2"), asList("audience"), - GoogleJwtCreatorTest.NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testConfigurableToIncorrectValueMultipleKeysForAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String[] arr = {"accounts.fake.com", "subject"}; - String token = GoogleJwtCreator.build() - .withPicture(GoogleJwtCreatorTest.PICTURE) - .withEmail(GoogleJwtCreatorTest.EMAIL) - .withSubject("subject", "subject2") - .withAudience("audience", "audience2") - .withExp(exp) - .withIat(iat) - .withName(GoogleJwtCreatorTest.NAME) - .withIssuer("issuer", "issuer2") - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(GoogleJwtCreatorTest.PICTURE, GoogleJwtCreatorTest.EMAIL, asList("issuer", "issuer2"), asList("audience", "audience3"), - GoogleJwtCreatorTest.NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/PemUtils.java b/lib/src/test/java/com/auth0/jwt/PemUtils.java deleted file mode 100644 index 7b23244..0000000 --- a/lib/src/test/java/com/auth0/jwt/PemUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemReader; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; - -public class PemUtils { - - private static byte[] parsePEMFile(File pemFile) throws IOException { - if (!pemFile.isFile() || !pemFile.exists()) { - throw new FileNotFoundException(String.format("The file '%s' doesn't exist.", pemFile.getAbsolutePath())); - } - PemReader reader = new PemReader(new FileReader(pemFile)); - PemObject pemObject = reader.readPemObject(); - byte[] content = pemObject.getContent(); - reader.close(); - return content; - } - - private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) { - PublicKey publicKey = null; - try { - KeyFactory kf = KeyFactory.getInstance(algorithm); - EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - publicKey = kf.generatePublic(keySpec); - } catch (NoSuchAlgorithmException e) { - System.out.println("Could not reconstruct the public key, the given algorithm could not be found."); - } catch (InvalidKeySpecException e) { - System.out.println("Could not reconstruct the public key"); - } - - return publicKey; - } - - private static PrivateKey getPrivateKey(byte[] keyBytes, String algorithm) { - PrivateKey privateKey = null; - try { - KeyFactory kf = KeyFactory.getInstance(algorithm); - EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); - privateKey = kf.generatePrivate(keySpec); - } catch (NoSuchAlgorithmException e) { - System.out.println("Could not reconstruct the private key, the given algorithm could not be found."); - } catch (InvalidKeySpecException e) { - System.out.println("Could not reconstruct the private key"); - } - - return privateKey; - } - - public static PublicKey readPublicKeyFromFile(String filepath, String algorithm) throws IOException { - byte[] bytes = PemUtils.parsePEMFile(new File(filepath)); - return PemUtils.getPublicKey(bytes, algorithm); - } - - public static PrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException { - byte[] bytes = PemUtils.parsePEMFile(new File(filepath)); - return PemUtils.getPrivateKey(bytes, algorithm); - } - -} diff --git a/lib/src/test/java/com/auth0/jwt/TimeUtil.java b/lib/src/test/java/com/auth0/jwt/TimeUtil.java deleted file mode 100644 index db50e89..0000000 --- a/lib/src/test/java/com/auth0/jwt/TimeUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Random; - -public class TimeUtil { - - public static Date generateRandomExpDateInFuture() { - Random rnd = new Random(); - return new Date(Math.abs(System.currentTimeMillis() + rnd.nextLong())); - } - - public static Date generateRandomIatDateInPast() { - GregorianCalendar gc = new GregorianCalendar(); - int year = randBetween(1900, 2010); - gc.set(gc.YEAR, year); - int dayOfYear = randBetween(1, gc.getActualMaximum(gc.DAY_OF_YEAR)); - gc.set(gc.DAY_OF_YEAR, dayOfYear); - - return new Date(gc.getTimeInMillis()); - } - - public static int randBetween(int start, int end) { - return start + (int)Math.round(Math.random() * (end - start)); - } - -} diff --git a/lib/src/test/java/com/auth0/jwt/TokenUtilsTest.java b/lib/src/test/java/com/auth0/jwt/TokenUtilsTest.java deleted file mode 100644 index c0f375e..0000000 --- a/lib/src/test/java/com/auth0/jwt/TokenUtilsTest.java +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; - -public class TokenUtilsTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void shouldSplitToken() throws Exception { - String token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhdXRoMCJ9.W1mx_Y0hbAMbPmfW9whT605AAcxB7REFuJiDAHk2Sdc"; - String[] parts = TokenUtils.splitToken(token); - - assertThat(parts, is(notNullValue())); - assertThat(parts, is(arrayWithSize(3))); - assertThat(parts[0], is("eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0")); - assertThat(parts[1], is("eyJpc3MiOiJhdXRoMCJ9")); - assertThat(parts[2], is("W1mx_Y0hbAMbPmfW9whT605AAcxB7REFuJiDAHk2Sdc")); - } - - @Test - public void shouldSplitTokenWithEmptySignature() throws Exception { - String token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhdXRoMCJ9."; - String[] parts = TokenUtils.splitToken(token); - - assertThat(parts, is(notNullValue())); - assertThat(parts, is(arrayWithSize(3))); - assertThat(parts[0], is("eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0")); - assertThat(parts[1], is("eyJpc3MiOiJhdXRoMCJ9")); - assertThat(parts[2], is(isEmptyString())); - } - - @Test - public void shouldThrowOnSplitTokenWithMoreThan3Parts() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The token was expected to have 3 parts, but got 4."); - String token = "this.has.four.parts"; - TokenUtils.splitToken(token); - } - - @Test - public void shouldThrowOnSplitTokenWithLessThan3Parts() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The token was expected to have 3 parts, but got 2."); - String token = "two.parts"; - TokenUtils.splitToken(token); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/UserPojo.java b/lib/src/test/java/com/auth0/jwt/UserPojo.java deleted file mode 100644 index 99e8a0f..0000000 --- a/lib/src/test/java/com/auth0/jwt/UserPojo.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt; - -public class UserPojo { - private String name; - private int id; - - @SuppressWarnings("unused") - public UserPojo() { - //Required Empty Constructor - } - - public UserPojo(String name, int id) { - this.name = name; - this.id = id; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - UserPojo userPojo = (UserPojo) o; - - return id == userPojo.id && (name != null ? name.equals(userPojo.name) : userPojo.name == null); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/AlgorithmTest.java b/lib/src/test/java/com/auth0/jwt/algorithms/AlgorithmTest.java deleted file mode 100644 index 048a712..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/AlgorithmTest.java +++ /dev/null @@ -1,568 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import com.auth0.jwt.interfaces.RSAKeyProvider; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.interfaces.*; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; - -public class AlgorithmTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - - @Test - public void shouldThrowHMAC256InstanceWithNullSecretBytes() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - byte[] secret = null; - Algorithm.HMAC256(secret); - } - - @Test - public void shouldThrowHMAC384InstanceWithNullSecretBytes() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - byte[] secret = null; - Algorithm.HMAC384(secret); - } - - @Test - public void shouldThrowHMAC512InstanceWithNullSecretBytes() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - byte[] secret = null; - Algorithm.HMAC512(secret); - } - - @Test - public void shouldThrowHMAC256InstanceWithNullSecret() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - String secret = null; - Algorithm.HMAC256(secret); - } - - @Test - public void shouldThrowHMAC384InstanceWithNullSecret() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - String secret = null; - Algorithm.HMAC384(secret); - } - - @Test - public void shouldThrowHMAC512InstanceWithNullSecret() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Secret cannot be null"); - String secret = null; - Algorithm.HMAC512(secret); - } - - @Test - public void shouldThrowRSA256InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - RSAKey key = null; - Algorithm.RSA256(key); - } - - @Test - public void shouldThrowRSA256InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.RSA256(null, null); - } - - @Test - public void shouldThrowRSA256InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - RSAKeyProvider provider = null; - Algorithm.RSA256(provider); - } - - @Test - public void shouldThrowRSA384InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - RSAKey key = null; - Algorithm.RSA384(key); - } - - @Test - public void shouldThrowRSA384InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.RSA384(null, null); - } - - @Test - public void shouldThrowRSA384InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - RSAKeyProvider provider = null; - Algorithm.RSA384(provider); - } - - @Test - public void shouldThrowRSA512InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - RSAKey key = null; - Algorithm.RSA512(key); - } - - @Test - public void shouldThrowRSA512InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.RSA512(null, null); - } - - @Test - public void shouldThrowRSA512InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - RSAKeyProvider provider = null; - Algorithm.RSA512(provider); - } - - @Test - public void shouldThrowECDSA256InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - ECKey key = null; - Algorithm.ECDSA256(key); - } - - @Test - public void shouldThrowECDSA256InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.ECDSA256(null, null); - } - - @Test - public void shouldThrowECDSA256InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - ECDSAKeyProvider provider = null; - Algorithm.ECDSA256(provider); - } - - @Test - public void shouldThrowECDSA384InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - ECKey key = null; - Algorithm.ECDSA384(key); - } - - @Test - public void shouldThrowECDSA384InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.ECDSA384(null, null); - } - - @Test - public void shouldThrowECDSA384InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - ECDSAKeyProvider provider = null; - Algorithm.ECDSA384(provider); - } - - @Test - public void shouldThrowECDSA512InstanceWithNullKey() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - ECKey key = null; - Algorithm.ECDSA512(key); - } - - @Test - public void shouldThrowECDSA512InstanceWithNullKeys() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Both provided Keys cannot be null."); - Algorithm.ECDSA512(null, null); - } - - @Test - public void shouldThrowECDSA512InstanceWithNullKeyProvider() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Key Provider cannot be null."); - ECDSAKeyProvider provider = null; - Algorithm.ECDSA512(provider); - } - - @Test - public void shouldCreateHMAC256AlgorithmWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret".getBytes(StandardCharsets.UTF_8)); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA256")); - assertThat(algorithm.getName(), is("HS256")); - } - - @Test - public void shouldCreateHMAC384AlgorithmWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC384("secret".getBytes(StandardCharsets.UTF_8)); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA384")); - assertThat(algorithm.getName(), is("HS384")); - } - - @Test - public void shouldCreateHMAC512AlgorithmWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC512("secret".getBytes(StandardCharsets.UTF_8)); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA512")); - assertThat(algorithm.getName(), is("HS512")); - } - - @Test - public void shouldCreateHMAC256AlgorithmWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA256")); - assertThat(algorithm.getName(), is("HS256")); - } - - @Test - public void shouldCreateHMAC384AlgorithmWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC384("secret"); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA384")); - assertThat(algorithm.getName(), is("HS384")); - } - - @Test - public void shouldCreateHMAC512AlgorithmWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC512("secret"); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(HMACAlgorithm.class))); - assertThat(algorithm.getDescription(), is("HmacSHA512")); - assertThat(algorithm.getName(), is("HS512")); - } - - @Test - public void shouldCreateRSA256AlgorithmWithPublicKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPublicKey.class)); - Algorithm algorithm = Algorithm.RSA256(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withRSA")); - assertThat(algorithm.getName(), is("RS256")); - } - - @Test - public void shouldCreateRSA256AlgorithmWithPrivateKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPrivateKey.class)); - Algorithm algorithm = Algorithm.RSA256(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withRSA")); - assertThat(algorithm.getName(), is("RS256")); - } - - @Test - public void shouldCreateRSA256AlgorithmWithBothKeys() throws Exception { - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withRSA")); - assertThat(algorithm.getName(), is("RS256")); - } - - @Test - public void shouldCreateRSA256AlgorithmWithProvider() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - Algorithm algorithm = Algorithm.RSA256(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withRSA")); - assertThat(algorithm.getName(), is("RS256")); - } - - @Test - public void shouldCreateRSA384AlgorithmWithPublicKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPublicKey.class)); - Algorithm algorithm = Algorithm.RSA384(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withRSA")); - assertThat(algorithm.getName(), is("RS384")); - } - - @Test - public void shouldCreateRSA384AlgorithmWithPrivateKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPrivateKey.class)); - Algorithm algorithm = Algorithm.RSA384(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withRSA")); - assertThat(algorithm.getName(), is("RS384")); - } - - @Test - public void shouldCreateRSA384AlgorithmWithBothKeys() throws Exception { - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - Algorithm algorithm = Algorithm.RSA384(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withRSA")); - assertThat(algorithm.getName(), is("RS384")); - } - - @Test - public void shouldCreateRSA384AlgorithmWithProvider() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - Algorithm algorithm = Algorithm.RSA384(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withRSA")); - assertThat(algorithm.getName(), is("RS384")); - } - - @Test - public void shouldCreateRSA512AlgorithmWithPublicKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPublicKey.class)); - Algorithm algorithm = Algorithm.RSA512(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withRSA")); - assertThat(algorithm.getName(), is("RS512")); - } - - @Test - public void shouldCreateRSA512AlgorithmWithPrivateKey() throws Exception { - RSAKey key = mock(RSAKey.class, withSettings().extraInterfaces(RSAPrivateKey.class)); - Algorithm algorithm = Algorithm.RSA512(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withRSA")); - assertThat(algorithm.getName(), is("RS512")); - } - - @Test - public void shouldCreateRSA512AlgorithmWithBothKeys() throws Exception { - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - Algorithm algorithm = Algorithm.RSA512(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withRSA")); - assertThat(algorithm.getName(), is("RS512")); - } - - @Test - public void shouldCreateRSA512AlgorithmWithProvider() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - Algorithm algorithm = Algorithm.RSA512(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(RSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withRSA")); - assertThat(algorithm.getName(), is("RS512")); - } - - @Test - public void shouldCreateECDSA256AlgorithmWithPublicKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPublicKey.class)); - Algorithm algorithm = Algorithm.ECDSA256(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withECDSA")); - assertThat(algorithm.getName(), is("ES256")); - } - - @Test - public void shouldCreateECDSA256AlgorithmWithPrivateKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class)); - Algorithm algorithm = Algorithm.ECDSA256(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withECDSA")); - assertThat(algorithm.getName(), is("ES256")); - } - - @Test - public void shouldCreateECDSA256AlgorithmWithBothKeys() throws Exception { - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - Algorithm algorithm = Algorithm.ECDSA256(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withECDSA")); - assertThat(algorithm.getName(), is("ES256")); - } - - @Test - public void shouldCreateECDSA256AlgorithmWithProvider() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - Algorithm algorithm = Algorithm.ECDSA256(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA256withECDSA")); - assertThat(algorithm.getName(), is("ES256")); - } - - @Test - public void shouldCreateECDSA384AlgorithmWithPublicKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPublicKey.class)); - Algorithm algorithm = Algorithm.ECDSA384(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withECDSA")); - assertThat(algorithm.getName(), is("ES384")); - } - - @Test - public void shouldCreateECDSA384AlgorithmWithPrivateKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class)); - Algorithm algorithm = Algorithm.ECDSA384(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withECDSA")); - assertThat(algorithm.getName(), is("ES384")); - } - - @Test - public void shouldCreateECDSA384AlgorithmWithBothKeys() throws Exception { - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - Algorithm algorithm = Algorithm.ECDSA384(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withECDSA")); - assertThat(algorithm.getName(), is("ES384")); - } - - @Test - public void shouldCreateECDSA384AlgorithmWithProvider() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - Algorithm algorithm = Algorithm.ECDSA384(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA384withECDSA")); - assertThat(algorithm.getName(), is("ES384")); - } - - @Test - public void shouldCreateECDSA512AlgorithmWithPublicKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPublicKey.class)); - Algorithm algorithm = Algorithm.ECDSA512(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withECDSA")); - assertThat(algorithm.getName(), is("ES512")); - } - - @Test - public void shouldCreateECDSA512AlgorithmWithPrivateKey() throws Exception { - ECKey key = mock(ECKey.class, withSettings().extraInterfaces(ECPrivateKey.class)); - Algorithm algorithm = Algorithm.ECDSA512(key); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withECDSA")); - assertThat(algorithm.getName(), is("ES512")); - } - - @Test - public void shouldCreateECDSA512AlgorithmWithBothKeys() throws Exception { - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - Algorithm algorithm = Algorithm.ECDSA512(publicKey, privateKey); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withECDSA")); - assertThat(algorithm.getName(), is("ES512")); - } - - @Test - public void shouldCreateECDSA512AlgorithmWithProvider() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - Algorithm algorithm = Algorithm.ECDSA512(provider); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(ECDSAAlgorithm.class))); - assertThat(algorithm.getDescription(), is("SHA512withECDSA")); - assertThat(algorithm.getName(), is("ES512")); - } - - @Test - public void shouldCreateNoneAlgorithm() throws Exception { - Algorithm algorithm = Algorithm.none(); - - assertThat(algorithm, is(notNullValue())); - assertThat(algorithm, is(instanceOf(NoneAlgorithm.class))); - assertThat(algorithm.getDescription(), is("none")); - assertThat(algorithm.getName(), is("none")); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/ECDSAAlgorithmTest.java b/lib/src/test/java/com/auth0/jwt/algorithms/ECDSAAlgorithmTest.java deleted file mode 100644 index ef3f917..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/ECDSAAlgorithmTest.java +++ /dev/null @@ -1,1282 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.hamcrest.Matchers; -import org.hamcrest.collection.IsIn; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.interfaces.ECKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.util.Arrays; - -import static com.auth0.jwt.PemUtils.readPrivateKeyFromFile; -import static com.auth0.jwt.PemUtils.readPublicKeyFromFile; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@SuppressWarnings("deprecation") -public class ECDSAAlgorithmTest { - - - private static final String PRIVATE_KEY_FILE_256 = "src/test/resources/ec256-key-private.pem"; - private static final String PUBLIC_KEY_FILE_256 = "src/test/resources/ec256-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_256 = "src/test/resources/ec256-key-public-invalid.pem"; - - private static final String PRIVATE_KEY_FILE_384 = "src/test/resources/ec384-key-private.pem"; - private static final String PUBLIC_KEY_FILE_384 = "src/test/resources/ec384-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_384 = "src/test/resources/ec384-key-public-invalid.pem"; - - private static final String PRIVATE_KEY_FILE_512 = "src/test/resources/ec512-key-private.pem"; - private static final String PUBLIC_KEY_FILE_512 = "src/test/resources/ec512-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_512 = "src/test/resources/ec512-key-public-invalid.pem"; - - @Rule - public ExpectedException exception = ExpectedException.none(); - - //JOSE Signatures obtained using Node 'jwa' lib: https://github.com/brianloveswords/node-jwa - //DER Signatures obtained from source JOSE signature using 'ecdsa-sig-formatter' lib: https://github.com/Brightspace/node-ecdsa-sig-formatter - - //These tests use the default preferred SecurityProvider to handle ECDSA algorithms - - // Verify - - @Test - public void shouldPassECDSA256VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - Algorithm algorithm = Algorithm.ECDSA256(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA256VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.MEYCIQDiJWTf5jS/hFPj/0hpCWn7x1n/h+xPMjKWCs9MMusS9AIhAMcFPJVLe2A9uvb8hl8sRO2IpGoKDRpDmyH14ixNPAHW"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - Algorithm algorithm = Algorithm.ECDSA256(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA256VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA256VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.MEYCIQDiJWTf5jS/hFPj/0hpCWn7x1n/h+xPMjKWCs9MMusS9AIhAMcFPJVLe2A9uvb8hl8sRO2IpGoKDRpDmyH14ixNPAHW"; - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA256VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.D_oU4CB0ZEsxHOjcWnmS3ZJvlTzm6WcGFx-HASxnvcB2Xu2WjI-axqXH9xKq45aPBDs330JpRhJmqBSc2K8MXQ"; - Algorithm algorithm = Algorithm.ECDSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.D_oU4CB0ZEsxHOjcWnmS3ZJvlTzm6WcGFx-HASxnvcB2Xu2WjI-axqXH9xKq45aPBDs330JpRhJmqBSc2K8MXQ"; - Algorithm algorithm = Algorithm.ECDSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.W9qfN1b80B9hnMo49WL8THrOsf1vEjOhapeFemPMGySzxTcgfyudS5esgeBTO908X5SLdAr5jMwPUPBs9b6nNg"; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.W9qfN1b80B9hnMo49WL8THrOsf1vEjOhapeFemPMGySzxTcgfyudS5esgeBTO908X5SLdAr5jMwPUPBs9b6nNg"; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - byte[] bytes = new byte[63]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - - byte[] bytes = new byte[64]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - - byte[] bytes = new byte[64]; - bytes[0] = 0x30; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.50UU5VKNdF1wfykY8jQBKpvuHZoe6IZBJm5NvoB8bR-hnRg6ti-CHbmvoRtlLfnHfwITa_8cJMy6TenMC2g63GQHytc8rYoXqbwtS4R0Ko_AXbLFUmfxnGnMC6v4MS_z"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - Algorithm algorithm = Algorithm.ECDSA384(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA384VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.MGUCMQDnRRTlUo10XXB/KRjyNAEqm+4dmh7ohkEmbk2+gHxtH6GdGDq2L4Idua+hG2Ut+ccCMH8CE2v/HCTMuk3pzAtoOtxkB8rXPK2KF6m8LUuEdCqPwF2yxVJn8ZxpzAur+DEv8w=="; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - Algorithm algorithm = Algorithm.ECDSA384(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.50UU5VKNdF1wfykY8jQBKpvuHZoe6IZBJm5NvoB8bR-hnRg6ti-CHbmvoRtlLfnHfwITa_8cJMy6TenMC2g63GQHytc8rYoXqbwtS4R0Ko_AXbLFUmfxnGnMC6v4MS_z"; - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA384VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.MGUCMQDnRRTlUo10XXB/KRjyNAEqm+4dmh7ohkEmbk2+gHxtH6GdGDq2L4Idua+hG2Ut+ccCMH8CE2v/HCTMuk3pzAtoOtxkB8rXPK2KF6m8LUuEdCqPwF2yxVJn8ZxpzAur+DEv8w=="; - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.9kjGuFTPx3ylfpqL0eY9H7TGmPepjQOBKI8UPoEvby6N7dDLF5HxLohosNxxFymNT7LzpeSgOPAB0wJEwG2Nl2ukgdUOpZOf492wog_i5ZcZmAykd3g1QH7onrzd69GU"; - Algorithm algorithm = Algorithm.ECDSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.9kjGuFTPx3ylfpqL0eY9H7TGmPepjQOBKI8UPoEvby6N7dDLF5HxLohosNxxFymNT7LzpeSgOPAB0wJEwG2Nl2ukgdUOpZOf492wog_i5ZcZmAykd3g1QH7onrzd69GU"; - Algorithm algorithm = Algorithm.ECDSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9._k5h1KyO-NE0R2_HAw0-XEc0bGT5atv29SxHhOGC9JDqUHeUdptfCK_ljQ01nLVt2OQWT2SwGs-TuyHDFmhPmPGFZ9wboxvq_ieopmYqhQilNAu-WF-frioiRz9733fU"; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9._k5h1KyO-NE0R2_HAw0-XEc0bGT5atv29SxHhOGC9JDqUHeUdptfCK_ljQ01nLVt2OQWT2SwGs-TuyHDFmhPmPGFZ9wboxvq_ieopmYqhQilNAu-WF-frioiRz9733fU"; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[95]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[96]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidDERSignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[96]; - new SecureRandom().nextBytes(bytes); - bytes[0] = 0x30; - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AeCJPDIsSHhwRSGZCY6rspi8zekOw0K9qYMNridP1Fu9uhrA1QrG-EUxXlE06yvmh2R7Rz0aE7kxBwrnq8L8aOBCAYAsqhzPeUvyp8fXjjgs0Eto5I0mndE2QHlgcMSFASyjHbU8wD2Rq7ZNzGQ5b2MZfpv030WGUajT-aZYWFUJHVg2"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - Algorithm algorithm = Algorithm.ECDSA512(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA512VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.MIGIAkIB4Ik8MixIeHBFIZkJjquymLzN6Q7DQr2pgw2uJ0/UW726GsDVCsb4RTFeUTTrK+aHZHtHPRoTuTEHCuerwvxo4EICQgGALKocz3lL8qfH1444LNBLaOSNJp3RNkB5YHDEhQEsox21PMA9kau2TcxkOW9jGX6b9N9FhlGo0/mmWFhVCR1YNg=="; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - Algorithm algorithm = Algorithm.ECDSA512(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AeCJPDIsSHhwRSGZCY6rspi8zekOw0K9qYMNridP1Fu9uhrA1QrG-EUxXlE06yvmh2R7Rz0aE7kxBwrnq8L8aOBCAYAsqhzPeUvyp8fXjjgs0Eto5I0mndE2QHlgcMSFASyjHbU8wD2Rq7ZNzGQ5b2MZfpv030WGUajT-aZYWFUJHVg2"; - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowECDSA512VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.MIGIAkIB4Ik8MixIeHBFIZkJjquymLzN6Q7DQr2pgw2uJ0/UW726GsDVCsb4RTFeUTTrK+aHZHtHPRoTuTEHCuerwvxo4EICQgGALKocz3lL8qfH1444LNBLaOSNJp3RNkB5YHDEhQEsox21PMA9kau2TcxkOW9jGX6b9N9FhlGo0/mmWFhVCR1YNg=="; - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.AGxEwbsYa2bQ7Y7DAcTQnVD8PmLSlhJ20jg2OfdyPnqdXI8SgBaG6lGciq3_pofFhs1HEoFoJ33Jcluha24oMHIvAfwu8qbv_Wq3L2eI9Q0L0p6ul8Pd_BS8adRa2PgLc36xXGcRc7ID5YH-CYaQfsTp5YIaF0Po3h0QyCoQ6ZiYQkqm"; - Algorithm algorithm = Algorithm.ECDSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.AGxEwbsYa2bQ7Y7DAcTQnVD8PmLSlhJ20jg2OfdyPnqdXI8SgBaG6lGciq3_pofFhs1HEoFoJ33Jcluha24oMHIvAfwu8qbv_Wq3L2eI9Q0L0p6ul8Pd_BS8adRa2PgLc36xXGcRc7ID5YH-CYaQfsTp5YIaF0Po3h0QyCoQ6ZiYQkqm"; - Algorithm algorithm = Algorithm.ECDSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AZgdopFFsN0amCSs2kOucXdpylD31DEm5ChK1PG0_gq5Mf47MrvVph8zHSVuvcrXzcE1U3VxeCg89mYW1H33Y-8iAF0QFkdfTUQIWKNObH543WNMYYssv3OtOj0znPv8atDbaF8DMYAtcT1qdmaSJRhx-egRE9HGZkinPh9CfLLLt58X"; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AZgdopFFsN0amCSs2kOucXdpylD31DEm5ChK1PG0_gq5Mf47MrvVph8zHSVuvcrXzcE1U3VxeCg89mYW1H33Y-8iAF0QFkdfTUQIWKNObH543WNMYYssv3OtOj0znPv8atDbaF8DMYAtcT1qdmaSJRhx-egRE9HGZkinPh9CfLLLt58X"; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[131]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[132]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidDERSignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[132]; - new SecureRandom().nextBytes(bytes); - bytes[0] = 0x30; - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - byte[] bytes = new byte[256]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - - ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(SignatureException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - //Sign - private static final String ES256Header = "eyJhbGciOiJFUzI1NiJ9"; - private static final String ES384Header = "eyJhbGciOiJFUzM4NCJ9"; - private static final String ES512Header = "eyJhbGciOiJFUzUxMiJ9"; - private static final String auth0IssPayload = "eyJpc3MiOiJhdXRoMCJ9"; - - @Test - public void shouldDoECDSA256Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA256((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC")); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA256SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA256SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA256(provider); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA256SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA256(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA256SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoECDSA384Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA384((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC")); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA384SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA384SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA384(provider); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA384SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA384(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA384SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoECDSA512Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA512((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC")); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA512SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - - @Test - public void shouldDoECDSA512SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA512(provider); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA512SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA512(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA512SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(NoSuchAlgorithmException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(InvalidKeyException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(SignatureException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(SignatureException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception { - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); - - assertThat(algorithm.getSigningKeyId(), is(nullValue())); - } - - @Test - public void shouldReturnSigningKeyIdFromProvider() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("keyId"); - Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); - - assertThat(algorithm.getSigningKeyId(), is("keyId")); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfDoesNotStartWithCorrectSequenceByte() throws Exception { - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String content256 = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - byte[] signature = algorithm256.sign(content256.getBytes()); - signature[0] = (byte) 0x02; - algorithm256.DERToJOSE(signature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - int received = (int) derSignature[1]; - received--; - derSignature[1] = (byte) received; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfRNumberDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - derSignature[3] = (byte) 34; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfSNumberDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - derSignature[4 + 32 + 1] = (byte) 34; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnJOSESignatureConversionIfDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] joseSignature = new byte[32 * 2 - 1]; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid JOSE signature format."); - - algorithm256.JOSEToDER(joseSignature); - } - - @Test - public void shouldSignAndVerifyWithECDSA256() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String content256 = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm256.sign(content256.getBytes()); - String signature256 = Base64.encodeBase64URLSafeString((signature)); - - String token = content256 + "." + signature256; - JWT jwt = JWT.require(algorithm256).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm256.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldSignAndVerifyWithECDSA384() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - String content384 = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm384.sign(content384.getBytes()); - String signature384 = Base64.encodeBase64URLSafeString((signature)); - - String token = content384 + "." + signature384; - JWT jwt = JWT.require(algorithm384).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm384.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldSignAndVerifyWithECDSA512() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - String content512 = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm512.sign(content512.getBytes()); - String signature512 = Base64.encodeBase64URLSafeString((signature)); - - String token = content512 + "." + signature512; - JWT jwt = JWT.require(algorithm512).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm512.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldDecodeECDSA256JOSE() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(32, false, false); - byte[] derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, false, false); - - //With R padding - joseSignature = createJOSESignature(32, true, false); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, true, false); - - //With S padding - joseSignature = createJOSESignature(32, false, true); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, false, true); - - //With both paddings - joseSignature = createJOSESignature(32, true, true); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, true, true); - } - - @Test - public void shouldDecodeECDSA256DER() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(32, false, false); - byte[] joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, false, false); - - //With R padding - derSignature = createDERSignature(32, true, false); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, true, false); - - //With S padding - derSignature = createDERSignature(32, false, true); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, false, true); - - //With both paddings - derSignature = createDERSignature(32, true, true); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, true, true); - } - - @Test - public void shouldDecodeECDSA384JOSE() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(48, false, false); - byte[] derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, false, false); - - //With R padding - joseSignature = createJOSESignature(48, true, false); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, true, false); - - //With S padding - joseSignature = createJOSESignature(48, false, true); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, false, true); - - //With both paddings - joseSignature = createJOSESignature(48, true, true); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, true, true); - } - - @Test - public void shouldDecodeECDSA384DER() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(48, false, false); - byte[] joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, false, false); - - //With R padding - derSignature = createDERSignature(48, true, false); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, true, false); - - //With S padding - derSignature = createDERSignature(48, false, true); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, false, true); - - //With both paddings - derSignature = createDERSignature(48, true, true); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, true, true); - } - - @Test - public void shouldDecodeECDSA512JOSE() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(66, false, false); - byte[] derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, false, false); - - //With R padding - joseSignature = createJOSESignature(66, true, false); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, true, false); - - //With S padding - joseSignature = createJOSESignature(66, false, true); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, false, true); - - //With both paddings - joseSignature = createJOSESignature(66, true, true); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, true, true); - } - - @Test - public void shouldDecodeECDSA512DER() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(66, false, false); - byte[] joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, false, false); - - //With R padding - derSignature = createDERSignature(66, true, false); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, true, false); - - //With S padding - derSignature = createDERSignature(66, false, true); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, false, true); - - //With both paddings - derSignature = createDERSignature(66, true, true); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, true, true); - } - - - //Test Helpers - static void assertValidJOSESignature(byte[] joseSignature, int numberSize, boolean withRPadding, boolean withSPadding) { - Assert.assertThat(joseSignature, is(Matchers.notNullValue())); - Assert.assertThat(numberSize, is(IsIn.oneOf(32, 48, 66))); - - Assert.assertThat(joseSignature.length, is(numberSize * 2)); - - byte[] rCopy = Arrays.copyOfRange(joseSignature, 0, numberSize); - byte[] sCopy = Arrays.copyOfRange(joseSignature, numberSize, numberSize * 2); - - byte[] rNumber = new byte[numberSize]; - byte[] sNumber = new byte[numberSize]; - Arrays.fill(rNumber, (byte) 0x11); - Arrays.fill(sNumber, (byte) 0x22); - if (withRPadding) { - rNumber[0] = (byte) 0; - } - if (withSPadding) { - sNumber[0] = (byte) 0; - } - Assert.assertThat(Arrays.equals(rNumber, rCopy), is(true)); - Assert.assertThat(Arrays.equals(sNumber, sCopy), is(true)); - } - - static byte[] createDERSignature(int numberSize, boolean withRPadding, boolean withSPadding) { - Assert.assertThat(numberSize, is(IsIn.oneOf(32, 48, 66))); - - int rLength = withRPadding ? numberSize - 1 : numberSize; - int sLength = withSPadding ? numberSize - 1 : numberSize; - int totalLength = 2 + (2 + rLength) + (2 + sLength); - - byte[] rNumber = new byte[rLength]; - byte[] sNumber = new byte[sLength]; - Arrays.fill(rNumber, (byte) 0x11); - Arrays.fill(sNumber, (byte) 0x22); - - byte[] derSignature; - int offset = 0; - if (totalLength > 0x7f) { - totalLength++; - derSignature = new byte[totalLength]; - //Start sequence and sign - derSignature[offset++] = (byte) 0x30; - derSignature[offset++] = (byte) 0x81; - } else { - derSignature = new byte[totalLength]; - //Start sequence - derSignature[offset++] = (byte) 0x30; - } - - //Sequence length - derSignature[offset++] = (byte) (totalLength - offset); - - //R number - derSignature[offset++] = (byte) 0x02; - derSignature[offset++] = (byte) rLength; - System.arraycopy(rNumber, 0, derSignature, offset, rLength); - offset += rLength; - - //S number - derSignature[offset++] = (byte) 0x02; - derSignature[offset++] = (byte) sLength; - System.arraycopy(sNumber, 0, derSignature, offset, sLength); - - return derSignature; - } - - static byte[] createJOSESignature(int numberSize, boolean withRPadding, boolean withSPadding) { - Assert.assertThat(numberSize, is(IsIn.oneOf(32, 48, 66))); - - byte[] rNumber = new byte[numberSize]; - byte[] sNumber = new byte[numberSize]; - Arrays.fill(rNumber, (byte) 0x11); - Arrays.fill(sNumber, (byte) 0x22); - if (withRPadding) { - rNumber[0] = (byte) 0; - } - if (withSPadding) { - sNumber[0] = (byte) 0; - } - byte[] joseSignature = new byte[numberSize * 2]; - System.arraycopy(rNumber, 0, joseSignature, 0, numberSize); - System.arraycopy(sNumber, 0, joseSignature, numberSize, numberSize); - return joseSignature; - } - - static void assertValidDERSignature(byte[] derSignature, int numberSize, boolean withRPadding, boolean withSPadding) { - Assert.assertThat(derSignature, is(Matchers.notNullValue())); - Assert.assertThat(numberSize, is(IsIn.oneOf(32, 48, 66))); - - int rLength = withRPadding ? numberSize - 1 : numberSize; - int sLength = withSPadding ? numberSize - 1 : numberSize; - int totalLength = 2 + (2 + rLength) + (2 + sLength); - int offset = 0; - - //Start sequence - Assert.assertThat(derSignature[offset++], is((byte) 0x30)); - if (totalLength > 0x7f) { - //Add sign before sequence length - totalLength++; - Assert.assertThat(derSignature[offset++], is((byte) 0x81)); - } - //Sequence length - Assert.assertThat(derSignature[offset++], is((byte) (totalLength - offset))); - - //R number - Assert.assertThat(derSignature[offset++], is((byte) 0x02)); - Assert.assertThat(derSignature[offset++], is((byte) rLength)); - byte[] rCopy = Arrays.copyOfRange(derSignature, offset, offset + rLength); - offset += rLength; - - //S number - Assert.assertThat(derSignature[offset++], is((byte) 0x02)); - Assert.assertThat(derSignature[offset++], is((byte) sLength)); - byte[] sCopy = Arrays.copyOfRange(derSignature, offset, offset + sLength); - - - byte[] rNumber = new byte[rLength]; - byte[] sNumber = new byte[sLength]; - Arrays.fill(rNumber, (byte) 0x11); - Arrays.fill(sNumber, (byte) 0x22); - Assert.assertThat(Arrays.equals(rNumber, rCopy), is(true)); - Assert.assertThat(Arrays.equals(sNumber, sCopy), is(true)); - Assert.assertThat(derSignature.length, is(totalLength)); - } - - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/ECDSABouncyCastleProviderTests.java b/lib/src/test/java/com/auth0/jwt/algorithms/ECDSABouncyCastleProviderTests.java deleted file mode 100644 index d6a37c7..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/ECDSABouncyCastleProviderTests.java +++ /dev/null @@ -1,1170 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.interfaces.ECKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; - -import static com.auth0.jwt.PemUtils.readPrivateKeyFromFile; -import static com.auth0.jwt.PemUtils.readPublicKeyFromFile; -import static com.auth0.jwt.algorithms.ECDSAAlgorithmTest.*; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ECDSABouncyCastleProviderTests { - - - private static final String PRIVATE_KEY_FILE_256 = "src/test/resources/ec256-key-private.pem"; - private static final String PUBLIC_KEY_FILE_256 = "src/test/resources/ec256-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_256 = "src/test/resources/ec256-key-public-invalid.pem"; - - private static final String PRIVATE_KEY_FILE_384 = "src/test/resources/ec384-key-private.pem"; - private static final String PUBLIC_KEY_FILE_384 = "src/test/resources/ec384-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_384 = "src/test/resources/ec384-key-public-invalid.pem"; - - private static final String PRIVATE_KEY_FILE_512 = "src/test/resources/ec512-key-private.pem"; - private static final String PUBLIC_KEY_FILE_512 = "src/test/resources/ec512-key-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE_512 = "src/test/resources/ec512-key-public-invalid.pem"; - - @Rule - public ExpectedException exception = ExpectedException.none(); - private static final Provider bcProvider = new BouncyCastleProvider(); - - //JOSE Signatures obtained using Node 'jwa' lib: https://github.com/brianloveswords/node-jwa - //DER Signatures obtained from source JOSE signature using 'ecdsa-sig-formatter' lib: https://github.com/Brightspace/node-ecdsa-sig-formatter - - - //These tests add and use the BouncyCastle SecurityProvider to handle ECDSA algorithms - - @BeforeClass - public static void setUp() throws Exception { - //Set BC as the preferred bcProvider - Security.insertProviderAt(bcProvider, 1); - } - - @AfterClass - public static void tearDown() throws Exception { - Security.removeProvider(bcProvider.getName()); - } - - @Test - public void shouldPreferBouncyCastleProvider() throws Exception { - assertThat(Security.getProviders()[0], is(equalTo(bcProvider))); - } - - // Verify - - @Test - public void shouldPassECDSA256VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - Algorithm algorithm = Algorithm.ECDSA256(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA256VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.MEYCIQDiJWTf5jS/hFPj/0hpCWn7x1n/h+xPMjKWCs9MMusS9AIhAMcFPJVLe2A9uvb8hl8sRO2IpGoKDRpDmyH14ixNPAHW"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - Algorithm algorithm = Algorithm.ECDSA256(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA256VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA256VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.MEYCIQDiJWTf5jS/hFPj/0hpCWn7x1n/h+xPMjKWCs9MMusS9AIhAMcFPJVLe2A9uvb8hl8sRO2IpGoKDRpDmyH14ixNPAHW"; - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA256VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.D_oU4CB0ZEsxHOjcWnmS3ZJvlTzm6WcGFx-HASxnvcB2Xu2WjI-axqXH9xKq45aPBDs330JpRhJmqBSc2K8MXQ"; - Algorithm algorithm = Algorithm.ECDSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.D_oU4CB0ZEsxHOjcWnmS3ZJvlTzm6WcGFx-HASxnvcB2Xu2WjI-axqXH9xKq45aPBDs330JpRhJmqBSc2K8MXQ"; - Algorithm algorithm = Algorithm.ECDSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.W9qfN1b80B9hnMo49WL8THrOsf1vEjOhapeFemPMGySzxTcgfyudS5esgeBTO908X5SLdAr5jMwPUPBs9b6nNg"; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.W9qfN1b80B9hnMo49WL8THrOsf1vEjOhapeFemPMGySzxTcgfyudS5esgeBTO908X5SLdAr5jMwPUPBs9b6nNg"; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - byte[] bytes = new byte[63]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - - byte[] bytes = new byte[64]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA256VerificationOnInvalidDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - - byte[] bytes = new byte[64]; - bytes[0] = 0x30; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_256, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.50UU5VKNdF1wfykY8jQBKpvuHZoe6IZBJm5NvoB8bR-hnRg6ti-CHbmvoRtlLfnHfwITa_8cJMy6TenMC2g63GQHytc8rYoXqbwtS4R0Ko_AXbLFUmfxnGnMC6v4MS_z"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - Algorithm algorithm = Algorithm.ECDSA384(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA384VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.MGUCMQDnRRTlUo10XXB/KRjyNAEqm+4dmh7ohkEmbk2+gHxtH6GdGDq2L4Idua+hG2Ut+ccCMH8CE2v/HCTMuk3pzAtoOtxkB8rXPK2KF6m8LUuEdCqPwF2yxVJn8ZxpzAur+DEv8w=="; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - Algorithm algorithm = Algorithm.ECDSA384(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.50UU5VKNdF1wfykY8jQBKpvuHZoe6IZBJm5NvoB8bR-hnRg6ti-CHbmvoRtlLfnHfwITa_8cJMy6TenMC2g63GQHytc8rYoXqbwtS4R0Ko_AXbLFUmfxnGnMC6v4MS_z"; - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA384VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9.MGUCMQDnRRTlUo10XXB/KRjyNAEqm+4dmh7ohkEmbk2+gHxtH6GdGDq2L4Idua+hG2Ut+ccCMH8CE2v/HCTMuk3pzAtoOtxkB8rXPK2KF6m8LUuEdCqPwF2yxVJn8ZxpzAur+DEv8w=="; - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA384VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.9kjGuFTPx3ylfpqL0eY9H7TGmPepjQOBKI8UPoEvby6N7dDLF5HxLohosNxxFymNT7LzpeSgOPAB0wJEwG2Nl2ukgdUOpZOf492wog_i5ZcZmAykd3g1QH7onrzd69GU"; - Algorithm algorithm = Algorithm.ECDSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.9kjGuFTPx3ylfpqL0eY9H7TGmPepjQOBKI8UPoEvby6N7dDLF5HxLohosNxxFymNT7LzpeSgOPAB0wJEwG2Nl2ukgdUOpZOf492wog_i5ZcZmAykd3g1QH7onrzd69GU"; - Algorithm algorithm = Algorithm.ECDSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9._k5h1KyO-NE0R2_HAw0-XEc0bGT5atv29SxHhOGC9JDqUHeUdptfCK_ljQ01nLVt2OQWT2SwGs-TuyHDFmhPmPGFZ9wboxvq_ieopmYqhQilNAu-WF-frioiRz9733fU"; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9._k5h1KyO-NE0R2_HAw0-XEc0bGT5atv29SxHhOGC9JDqUHeUdptfCK_ljQ01nLVt2OQWT2SwGs-TuyHDFmhPmPGFZ9wboxvq_ieopmYqhQilNAu-WF-frioiRz9733fU"; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[95]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[96]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA384VerificationOnInvalidDERSignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[96]; - new SecureRandom().nextBytes(bytes); - bytes[0] = 0x30; - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_384, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithJOSESignature() throws Exception { - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AeCJPDIsSHhwRSGZCY6rspi8zekOw0K9qYMNridP1Fu9uhrA1QrG-EUxXlE06yvmh2R7Rz0aE7kxBwrnq8L8aOBCAYAsqhzPeUvyp8fXjjgs0Eto5I0mndE2QHlgcMSFASyjHbU8wD2Rq7ZNzGQ5b2MZfpv030WGUajT-aZYWFUJHVg2"; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - Algorithm algorithm = Algorithm.ECDSA512(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnECDSA512VerificationWithDERSignature() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.MIGIAkIB4Ik8MixIeHBFIZkJjquymLzN6Q7DQr2pgw2uJ0/UW726GsDVCsb4RTFeUTTrK+aHZHtHPRoTuTEHCuerwvxo4EICQgGALKocz3lL8qfH1444LNBLaOSNJp3RNkB5YHDEhQEsox21PMA9kau2TcxkOW9jGX6b9N9FhlGo0/mmWFhVCR1YNg=="; - ECKey key = (ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - Algorithm algorithm = Algorithm.ECDSA512(key); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithJOSESignatureWithBothKeys() throws Exception { - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AeCJPDIsSHhwRSGZCY6rspi8zekOw0K9qYMNridP1Fu9uhrA1QrG-EUxXlE06yvmh2R7Rz0aE7kxBwrnq8L8aOBCAYAsqhzPeUvyp8fXjjgs0Eto5I0mndE2QHlgcMSFASyjHbU8wD2Rq7ZNzGQ5b2MZfpv030WGUajT-aZYWFUJHVg2"; - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowECDSA512VerificationWithDERSignatureWithBothKeys() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.MIGIAkIB4Ik8MixIeHBFIZkJjquymLzN6Q7DQr2pgw2uJ0/UW726GsDVCsb4RTFeUTTrK+aHZHtHPRoTuTEHCuerwvxo4EICQgGALKocz3lL8qfH1444LNBLaOSNJp3RNkB5YHDEhQEsox21PMA9kau2TcxkOW9jGX6b9N9FhlGo0/mmWFhVCR1YNg=="; - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassECDSA512VerificationWithProvidedPublicKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((ECPublicKey) publicKey); - String token = "eyJhbGciOiJFUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.AGxEwbsYa2bQ7Y7DAcTQnVD8PmLSlhJ20jg2OfdyPnqdXI8SgBaG6lGciq3_pofFhs1HEoFoJ33Jcluha24oMHIvAfwu8qbv_Wq3L2eI9Q0L0p6ul8Pd_BS8adRa2PgLc36xXGcRc7ID5YH-CYaQfsTp5YIaF0Po3h0QyCoQ6ZiYQkqm"; - Algorithm algorithm = Algorithm.ECDSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJFUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.AGxEwbsYa2bQ7Y7DAcTQnVD8PmLSlhJ20jg2OfdyPnqdXI8SgBaG6lGciq3_pofFhs1HEoFoJ33Jcluha24oMHIvAfwu8qbv_Wq3L2eI9Q0L0p6ul8Pd_BS8adRa2PgLc36xXGcRc7ID5YH-CYaQfsTp5YIaF0Po3h0QyCoQ6ZiYQkqm"; - Algorithm algorithm = Algorithm.ECDSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AZgdopFFsN0amCSs2kOucXdpylD31DEm5ChK1PG0_gq5Mf47MrvVph8zHSVuvcrXzcE1U3VxeCg89mYW1H33Y-8iAF0QFkdfTUQIWKNObH543WNMYYssv3OtOj0znPv8atDbaF8DMYAtcT1qdmaSJRhx-egRE9HGZkinPh9CfLLLt58X"; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9.AZgdopFFsN0amCSs2kOucXdpylD31DEm5ChK1PG0_gq5Mf47MrvVph8zHSVuvcrXzcE1U3VxeCg89mYW1H33Y-8iAF0QFkdfTUQIWKNObH543WNMYYssv3OtOj0znPv8atDbaF8DMYAtcT1qdmaSJRhx-egRE9HGZkinPh9CfLLLt58X"; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidJOSESignatureLength() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[131]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidJOSESignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[132]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailECDSA512VerificationOnInvalidDERSignature() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - byte[] bytes = new byte[132]; - new SecureRandom().nextBytes(bytes); - bytes[0] = 0x30; - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE_512, "EC")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(SignatureException.class)); - exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); - - byte[] bytes = new byte[256]; - new SecureRandom().nextBytes(bytes); - String signature = Base64.encodeBase64URLSafeString(bytes); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; - - ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(SignatureException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - String token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - //Sign - private static final String ES256Header = "eyJhbGciOiJFUzI1NiJ9"; - private static final String ES384Header = "eyJhbGciOiJFUzM4NCJ9"; - private static final String ES512Header = "eyJhbGciOiJFUzUxMiJ9"; - private static final String auth0IssPayload = "eyJpc3MiOiJhdXRoMCJ9"; - - @Test - public void shouldDoECDSA256Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA256((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC")); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA256SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA256SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA256(provider); - String jwtContent = String.format("%s.%s", ES256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA256SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA256(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA256SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA256((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoECDSA384Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA384((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC")); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA384SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA384SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA384(provider); - String jwtContent = String.format("%s.%s", ES384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA384SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA384(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA384SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA384((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoECDSA512Signing() throws Exception { - Algorithm algorithmSign = Algorithm.ECDSA512((ECKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - Algorithm algorithmVerify = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC")); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoECDSA512SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - - @Test - public void shouldDoECDSA512SigningWithProvidedPrivateKey() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"); - when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey); - Algorithm algorithm = Algorithm.ECDSA512(provider); - String jwtContent = String.format("%s.%s", ES512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnECDSA512SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.ECDSA512(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnECDSA512SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withECDSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.ECDSA512((ECKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(NoSuchAlgorithmException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(InvalidKeyException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(SignatureException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(SignatureException.class); - - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); - algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception { - ECPublicKey publicKey = mock(ECPublicKey.class); - ECPrivateKey privateKey = mock(ECPrivateKey.class); - ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); - - assertThat(algorithm.getSigningKeyId(), is(nullValue())); - } - - @Test - public void shouldReturnSigningKeyIdFromProvider() throws Exception { - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("keyId"); - Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); - - assertThat(algorithm.getSigningKeyId(), is("keyId")); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfDoesNotStartWithCorrectSequenceByte() throws Exception { - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String content256 = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - byte[] signature = algorithm256.sign(content256.getBytes()); - signature[0] = (byte) 0x02; - algorithm256.DERToJOSE(signature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - int received = (int) derSignature[1]; - received--; - derSignature[1] = (byte) received; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfRNumberDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - derSignature[3] = (byte) 34; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnDERSignatureConversionIfSNumberDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] derSignature = createDERSignature(32, false, false); - derSignature[4 + 32 + 1] = (byte) 34; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid DER signature format."); - - algorithm256.DERToJOSE(derSignature); - } - - @Test - public void shouldThrowOnJOSESignatureConversionIfDoesNotHaveExpectedLength() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - byte[] joseSignature = new byte[32 * 2 - 1]; - exception.expect(SignatureException.class); - exception.expectMessage("Invalid JOSE signature format."); - - algorithm256.JOSEToDER(joseSignature); - } - - @Test - public void shouldSignAndVerifyWithECDSA256() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - String content256 = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm256.sign(content256.getBytes()); - String signature256 = Base64.encodeBase64URLSafeString((signature)); - - String token = content256 + "." + signature256; - JWT jwt = JWT.require(algorithm256).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm256.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldSignAndVerifyWithECDSA384() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - String content384 = "eyJhbGciOiJFUzM4NCJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm384.sign(content384.getBytes()); - String signature384 = Base64.encodeBase64URLSafeString((signature)); - - String token = content384 + "." + signature384; - JWT jwt = JWT.require(algorithm384).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm384.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldSignAndVerifyWithECDSA512() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - String content512 = "eyJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJhdXRoMCJ9"; - - for (int i = 0; i < 10; i++) { - byte[] signature = algorithm512.sign(content512.getBytes()); - String signature512 = Base64.encodeBase64URLSafeString((signature)); - - String token = content512 + "." + signature512; - JWT jwt = JWT.require(algorithm512).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm512.verify(decoded, EncodeType.Base64); - } - } - - @Test - public void shouldDecodeECDSA256JOSE() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(32, false, false); - byte[] derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, false, false); - - //With R padding - joseSignature = createJOSESignature(32, true, false); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, true, false); - - //With S padding - joseSignature = createJOSESignature(32, false, true); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, false, true); - - //With both paddings - joseSignature = createJOSESignature(32, true, true); - derSignature = algorithm256.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 32, true, true); - } - - @Test - public void shouldDecodeECDSA256DER() throws Exception { - ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(32, false, false); - byte[] joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, false, false); - - //With R padding - derSignature = createDERSignature(32, true, false); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, true, false); - - //With S padding - derSignature = createDERSignature(32, false, true); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, false, true); - - //With both paddings - derSignature = createDERSignature(32, true, true); - joseSignature = algorithm256.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 32, true, true); - } - - @Test - public void shouldDecodeECDSA384JOSE() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(48, false, false); - byte[] derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, false, false); - - //With R padding - joseSignature = createJOSESignature(48, true, false); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, true, false); - - //With S padding - joseSignature = createJOSESignature(48, false, true); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, false, true); - - //With both paddings - joseSignature = createJOSESignature(48, true, true); - derSignature = algorithm384.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 48, true, true); - } - - @Test - public void shouldDecodeECDSA384DER() throws Exception { - ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(48, false, false); - byte[] joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, false, false); - - //With R padding - derSignature = createDERSignature(48, true, false); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, true, false); - - //With S padding - derSignature = createDERSignature(48, false, true); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, false, true); - - //With both paddings - derSignature = createDERSignature(48, true, true); - joseSignature = algorithm384.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 48, true, true); - } - - @Test - public void shouldDecodeECDSA512JOSE() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - - //Without padding - byte[] joseSignature = createJOSESignature(66, false, false); - byte[] derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, false, false); - - //With R padding - joseSignature = createJOSESignature(66, true, false); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, true, false); - - //With S padding - joseSignature = createJOSESignature(66, false, true); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, false, true); - - //With both paddings - joseSignature = createJOSESignature(66, true, true); - derSignature = algorithm512.JOSEToDER(joseSignature); - assertValidDERSignature(derSignature, 66, true, true); - } - - @Test - public void shouldDecodeECDSA512DER() throws Exception { - ECDSAAlgorithm algorithm512 = (ECDSAAlgorithm) Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC")); - - //Without padding - byte[] derSignature = createDERSignature(66, false, false); - byte[] joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, false, false); - - //With R padding - derSignature = createDERSignature(66, true, false); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, true, false); - - //With S padding - derSignature = createDERSignature(66, false, true); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, false, true); - - //With both paddings - derSignature = createDERSignature(66, true, true); - joseSignature = algorithm512.DERToJOSE(derSignature); - assertValidJOSESignature(joseSignature, 66, true, true); - } -} diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/HMACAlgorithmTest.java b/lib/src/test/java/com/auth0/jwt/algorithms/HMACAlgorithmTest.java deleted file mode 100644 index 043c8f7..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/HMACAlgorithmTest.java +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class HMACAlgorithmTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - // Verify - - @Test - public void shouldGetStringBytes() throws Exception { - String text = "abcdef123456!@#$%^"; - byte[] expectedBytes = text.getBytes("UTF-8"); - assertTrue(Arrays.equals(expectedBytes, HMACAlgorithm.getSecretBytes(text))); - } - - @Test - public void shouldPassHMAC256Verification() throws Exception { - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M"; - Algorithm algorithmString = Algorithm.HMAC256("secret"); - Algorithm algorithmBytes = Algorithm.HMAC256("secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithmString).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmString.verify(decoded, EncodeType.Base64); - algorithmBytes.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC256VerificationWithInvalidSecretString() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA256"); - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M"; - Algorithm algorithm = Algorithm.HMAC256("not_real_secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC256VerificationWithInvalidSecretBytes() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA256"); - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M"; - Algorithm algorithm = Algorithm.HMAC256("not_real_secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassHMAC384Verification() throws Exception { - String token = "eyJhbGciOiJIUzM4NCIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.uztpK_wUMYJhrRv8SV-1LU4aPnwl-EM1q-wJnqgyb5DHoDteP6lN_gE1xnZJH5vw"; - Algorithm algorithmString = Algorithm.HMAC384("secret"); - Algorithm algorithmBytes = Algorithm.HMAC384("secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithmString).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmString.verify(decoded, EncodeType.Base64); - algorithmBytes.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC384VerificationWithInvalidSecretString() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA384"); - String token = "eyJhbGciOiJIUzM4NCIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.uztpK_wUMYJhrRv8SV-1LU4aPnwl-EM1q-wJnqgyb5DHoDteP6lN_gE1xnZJH5vw"; - Algorithm algorithm = Algorithm.HMAC384("not_real_secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC384VerificationWithInvalidSecretBytes() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA384"); - String token = "eyJhbGciOiJIUzM4NCIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.uztpK_wUMYJhrRv8SV-1LU4aPnwl-EM1q-wJnqgyb5DHoDteP6lN_gE1xnZJH5vw"; - Algorithm algorithm = Algorithm.HMAC384("not_real_secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassHMAC512Verification() throws Exception { - String token = "eyJhbGciOiJIUzUxMiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.VUo2Z9SWDV-XcOc_Hr6Lff3vl7L9e5Vb8ThXpmGDFjHxe3Dr1ZBmUChYF-xVA7cAdX1P_D4ZCUcsv3IefpVaJw"; - Algorithm algorithmString = Algorithm.HMAC512("secret"); - Algorithm algorithmBytes = Algorithm.HMAC512("secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithmString).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmString.verify(decoded, EncodeType.Base64); - algorithmBytes.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC512VerificationWithInvalidSecretString() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA512"); - String token = "eyJhbGciOiJIUzUxMiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.VUo2Z9SWDV-XcOc_Hr6Lff3vl7L9e5Vb8ThXpmGDFjHxe3Dr1ZBmUChYF-xVA7cAdX1P_D4ZCUcsv3IefpVaJw"; - Algorithm algorithm = Algorithm.HMAC512("not_real_secret"); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailHMAC512VerificationWithInvalidSecretBytes() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA512"); - String token = "eyJhbGciOiJIUzUxMiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.VUo2Z9SWDV-XcOc_Hr6Lff3vl7L9e5Vb8ThXpmGDFjHxe3Dr1ZBmUChYF-xVA7cAdX1P_D4ZCUcsv3IefpVaJw"; - Algorithm algorithm = Algorithm.HMAC512("not_real_secret".getBytes(StandardCharsets.UTF_8)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - - @Test - public void shouldThrowOnVerifyWhenTheSecretIsInvalid() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(byte[].class), any(byte[].class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - Algorithm algorithm = new HMACAlgorithm(crypto, "some-alg", "some-algorithm", "secret".getBytes(StandardCharsets.UTF_8)); - String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - // Sign - - private static final String HS256Header = "eyJhbGciOiJIUzI1NiJ9"; - private static final String HS384Header = "eyJhbGciOiJIUzM4NCJ9"; - private static final String HS512Header = "eyJhbGciOiJIUzUxMiJ9"; - private static final String auth0IssPayload = "eyJpc3MiOiJhdXRoMCJ9"; - - @Test - public void shouldDoHMAC256SigningWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret".getBytes(StandardCharsets.UTF_8)); - - String jwtContent = String.format("%s.%s", HS256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "s69x7Mmu4JqwmdxiK6sesALO7tcedbFsKEEITUxw9ho"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoHMAC384SigningWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC384("secret".getBytes(StandardCharsets.UTF_8)); - - String jwtContent = String.format("%s.%s", HS384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "4-y2Gxz_foN0jAOFimmBPF7DWxf4AsjM20zxNkHg8Zah5Q64G42P9GfjmUp4Hldt"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoHMAC512SigningWithBytes() throws Exception { - Algorithm algorithm = Algorithm.HMAC512("secret".getBytes(StandardCharsets.UTF_8)); - - String jwtContent = String.format("%s.%s", HS512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "OXWyxmf-VcVo8viOiTFfLaEy6mrQqLEos5R82Xsx8mtFxQadJAQ1aVniIWN8qT2GNE_pMQPcdzk4x7Cqxsp1dw"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoHMAC256SigningWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - - String jwtContent = String.format("%s.%s", HS256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "s69x7Mmu4JqwmdxiK6sesALO7tcedbFsKEEITUxw9ho"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoHMAC384SigningWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC384("secret"); - - String jwtContent = String.format("%s.%s", HS384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "4-y2Gxz_foN0jAOFimmBPF7DWxf4AsjM20zxNkHg8Zah5Q64G42P9GfjmUp4Hldt"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoHMAC512SigningWithString() throws Exception { - Algorithm algorithm = Algorithm.HMAC512("secret"); - - String jwtContent = String.format("%s.%s", HS512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "OXWyxmf-VcVo8viOiTFfLaEy6mrQqLEos5R82Xsx8mtFxQadJAQ1aVniIWN8qT2GNE_pMQPcdzk4x7Cqxsp1dw"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(NoSuchAlgorithmException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(byte[].class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - Algorithm algorithm = new HMACAlgorithm(crypto, "some-alg", "some-algorithm", "secret".getBytes(StandardCharsets.UTF_8)); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldThrowOnSignWhenTheSecretIsInvalid() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(InvalidKeyException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(byte[].class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - Algorithm algorithm = new HMACAlgorithm(crypto, "some-alg", "some-algorithm", "secret".getBytes(StandardCharsets.UTF_8)); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldReturnNullSigningKeyId() throws Exception { - assertThat(Algorithm.HMAC256("secret").getSigningKeyId(), is(nullValue())); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/NoneAlgorithmTest.java b/lib/src/test/java/com/auth0/jwt/algorithms/NoneAlgorithmTest.java deleted file mode 100644 index aea4415..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/NoneAlgorithmTest.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.jwts.JWT; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -public class NoneAlgorithmTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void shouldPassNoneVerification() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = "eyJhbGciOiJub25lIiwiY3R5IjoiSldUIn0.eyJpc3MiOiJhdXRoMCJ9."; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailNoneVerificationWhenTokenHasTwoParts() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The token was expected to have 3 parts, but got 2."); - String token = "eyJhbGciOiJub25lIiwiY3R5IjoiSldUIn0.eyJpc3MiOiJhdXRoMCJ9"; - Algorithm algorithm = Algorithm.none(); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailNoneVerificationWhenSignatureIsPresent() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: none"); - String token = "eyJhbGciOiJub25lIiwiY3R5IjoiSldUIn0.eyJpc3MiOiJhdXRoMCJ9.Ox-WRXRaGAuWt2KfPvWiGcCrPqZtbp_4OnQzZXaTfss"; - Algorithm algorithm = Algorithm.none(); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldReturnNullSigningKeyId() throws Exception { - assertThat(Algorithm.none().getSigningKeyId(), is(nullValue())); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/algorithms/RSAAlgorithmTest.java b/lib/src/test/java/com/auth0/jwt/algorithms/RSAAlgorithmTest.java deleted file mode 100644 index 869074a..0000000 --- a/lib/src/test/java/com/auth0/jwt/algorithms/RSAAlgorithmTest.java +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.algorithms; - -import com.auth0.jwt.creators.EncodeType; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.exceptions.SignatureGenerationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.RSAKeyProvider; -import com.auth0.jwt.jwts.JWT; -import org.apache.commons.codec.binary.Base64; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.interfaces.RSAKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; - -import static com.auth0.jwt.PemUtils.readPrivateKeyFromFile; -import static com.auth0.jwt.PemUtils.readPublicKeyFromFile; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@SuppressWarnings("deprecation") -public class RSAAlgorithmTest { - - private static final String PRIVATE_KEY_FILE = "src/test/resources/rsa-private.pem"; - private static final String PUBLIC_KEY_FILE = "src/test/resources/rsa-public.pem"; - private static final String INVALID_PUBLIC_KEY_FILE = "src/test/resources/rsa-public_invalid.pem"; - - @Rule - public ExpectedException exception = ExpectedException.none(); - - //Verify - - @Test - public void shouldPassRSA256Verification() throws Exception { - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA256VerificationWithBothKeys() throws Exception { - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA256VerificationWithProvidedPublicKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((RSAPublicKey) publicKey); - String token = "eyJhbGciOiJSUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.jXrbue3xJmnzWH9kU-uGeCTtgbQEKbch8uHd4Z52t86ncNyepfusl_bsyLJIcxMwK7odRzKiSE9efV9JaRSEDODDBdMeCzODFx82uBM7e46T1NLVSmjYIM7Hcfh81ZeTIk-hITvgtL6hvTdeJWOCZAB0bs18qSVW5SvursRUhY38xnhuNI6HOHCtqp7etxWAu6670L53I3GtXsmi6bXIzv_0v1xZcAFg4HTvXxfhfj3oCqkSs2nC27mHxBmQtmZKWmXk5HzVUyPRwTUWx5wHPT_hCsGer-CMCAyGsmOg466y1KDqf7ogpMYojfVZGWBsyA39LO1oWZ4Ryomkn8t5Vg"; - Algorithm algorithm = Algorithm.RSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA256VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJSUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.jXrbue3xJmnzWH9kU-uGeCTtgbQEKbch8uHd4Z52t86ncNyepfusl_bsyLJIcxMwK7odRzKiSE9efV9JaRSEDODDBdMeCzODFx82uBM7e46T1NLVSmjYIM7Hcfh81ZeTIk-hITvgtL6hvTdeJWOCZAB0bs18qSVW5SvursRUhY38xnhuNI6HOHCtqp7etxWAu6670L53I3GtXsmi6bXIzv_0v1xZcAFg4HTvXxfhfj3oCqkSs2nC27mHxBmQtmZKWmXk5HzVUyPRwTUWx5wHPT_hCsGer-CMCAyGsmOg466y1KDqf7ogpMYojfVZGWBsyA39LO1oWZ4Ryomkn8t5Vg"; - Algorithm algorithm = Algorithm.RSA256(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA256VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA"); - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA256VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - Algorithm algorithm = Algorithm.RSA256((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA384Verification() throws Exception { - String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; - Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA384VerificationWithBothKeys() throws Exception { - String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; - Algorithm algorithm = Algorithm.RSA384((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA384VerificationWithProvidedPublicKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((RSAPublicKey) publicKey); - String token = "eyJhbGciOiJSUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.ITNTVCT7ercumZKHV4-BXGkJwwa7fyF3CnSfEvm09fDFSkaseDxNo_75WLDmK9WM8RMHTPvkpHcTKm4guYEbC_la7RzFIKpU72bppzQojggSmWWXt_6zq50QP2t5HFMebote1zxhp8ccEdSCX5pyY6J2sm9kJ__HKK32KxIVCTjVCz-bFBS60oG35aYEySdKsxuUdWbD5FQ9I16Ony2x0EPvmlL3GPiAPmgjSFp3LtcBIbCDaoonM7iuDRGIQiDN_n2FKKb1Bt4_38uWPtTkwRpNalt6l53Y3JDdzGI5fMrMo3RQnQlAJxUJKD0eL6dRAA645IVIIXucHwuhgGGIVw"; - Algorithm algorithm = Algorithm.RSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA384VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJSUzM4NCIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.ITNTVCT7ercumZKHV4-BXGkJwwa7fyF3CnSfEvm09fDFSkaseDxNo_75WLDmK9WM8RMHTPvkpHcTKm4guYEbC_la7RzFIKpU72bppzQojggSmWWXt_6zq50QP2t5HFMebote1zxhp8ccEdSCX5pyY6J2sm9kJ__HKK32KxIVCTjVCz-bFBS60oG35aYEySdKsxuUdWbD5FQ9I16Ony2x0EPvmlL3GPiAPmgjSFp3LtcBIbCDaoonM7iuDRGIQiDN_n2FKKb1Bt4_38uWPtTkwRpNalt6l53Y3JDdzGI5fMrMo3RQnQlAJxUJKD0eL6dRAA645IVIIXucHwuhgGGIVw"; - Algorithm algorithm = Algorithm.RSA384(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA384VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withRSA"); - String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; - Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA384VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; - Algorithm algorithm = Algorithm.RSA384((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA512Verification() throws Exception { - String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; - Algorithm algorithm = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA512VerificationWithBothKeys() throws Exception { - String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; - Algorithm algorithm = Algorithm.RSA512((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldPassRSA512VerificationWithProvidedPublicKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPublicKeyById("my-key-id")).thenReturn((RSAPublicKey) publicKey); - String token = "eyJhbGciOiJSUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.GpHv85Q8tAU_6hNWsmO0GEpO1qz9lmK3NKeAcemysz9MGo4FXWn8xbD8NjCfzZ8EWphm65M0NArKSjpKHO5-gcNsQxLBVfSED1vzcoaZH_Vy5Rp1M76dGH7JghB_66KrpfyMxer_yRJb-KXesNvIroDGilLQF2ENG-IfLF5nBKlDiVHmPaqr3pm1q20fNLhegkSRca4BJ5VdIlT6kOqE_ykVyCBqzD_oXp3LKO_ARnxoeB9SegIW1fy_3tuxSTKYsCZiOfiyVEXXblAuY3pSLZnGvgeBRnfvmWXDWhP0vVUFtYJBF09eULvvUMVqWcrjUG9gDzzzT7veiY_fHd_x8g"; - Algorithm algorithm = Algorithm.RSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA512VerificationWhenProvidedPublicKeyIsNull() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPublicKeyById("my-key-id")).thenReturn(null); - String token = "eyJhbGciOiJSUzUxMiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJhdXRoMCJ9.GpHv85Q8tAU_6hNWsmO0GEpO1qz9lmK3NKeAcemysz9MGo4FXWn8xbD8NjCfzZ8EWphm65M0NArKSjpKHO5-gcNsQxLBVfSED1vzcoaZH_Vy5Rp1M76dGH7JghB_66KrpfyMxer_yRJb-KXesNvIroDGilLQF2ENG-IfLF5nBKlDiVHmPaqr3pm1q20fNLhegkSRca4BJ5VdIlT6kOqE_ykVyCBqzD_oXp3LKO_ARnxoeB9SegIW1fy_3tuxSTKYsCZiOfiyVEXXblAuY3pSLZnGvgeBRnfvmWXDWhP0vVUFtYJBF09eULvvUMVqWcrjUG9gDzzzT7veiY_fHd_x8g"; - Algorithm algorithm = Algorithm.RSA512(provider); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA512VerificationWithInvalidPublicKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withRSA"); - String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; - Algorithm algorithm = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailRSA512VerificationWhenUsingPrivateKey() throws Exception { - exception.expect(SignatureVerificationException.class); - exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA512withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Public Key is null."))); - String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; - Algorithm algorithm = Algorithm.RSA512((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowWhenMacAlgorithmDoesNotExists() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowWhenThePublicKeyIsInvalid() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldThrowWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(AlgorithmMismatchException.class); - exception.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(byte[].class), any(byte[].class))) - .thenThrow(SignatureException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - - //Sign - private static final String RS256Header = "eyJhbGciOiJSUzI1NiJ9"; - private static final String RS384Header = "eyJhbGciOiJSUzM4NCJ9"; - private static final String RS512Header = "eyJhbGciOiJSUzUxMiJ9"; - private static final String auth0IssPayload = "eyJpc3MiOiJhdXRoMCJ9"; - - @Test - public void shouldDoRSA256Signing() throws Exception { - Algorithm algorithmSign = Algorithm.RSA256((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - Algorithm algorithmVerify = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "ZB-Tr0vLtnf8I9fhSdSjU6HZei5xLYZQ6nZqM5O6Va0W9PgAqgRT7ShI9CjeYulRXPHvVmSl5EQuYuXdBzM0-H_3p_Nsl6tSMy4EyX2kkhEm6T0HhvarTh8CG0PCjn5p6FP5ZxWwhLcmRN70ItP6Z5MMO4CcJh1JrNxR4Fi4xQgt-CK2aVDMFXd-Br5yQiLVx1CX83w28OD9wssW3Rdltl5e66vCef0Ql6Q5I5e5F0nqGYT989a9fkNgLIx2F8k_az5x07BY59FV2SZg59nSiY7TZNjP8ot11Ew7HKRfPXOdh9eKRUVdhcxzqDePhyzKabU8TG5FP0SiWH5qVPfAgw"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA256SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "ZB-Tr0vLtnf8I9fhSdSjU6HZei5xLYZQ6nZqM5O6Va0W9PgAqgRT7ShI9CjeYulRXPHvVmSl5EQuYuXdBzM0-H_3p_Nsl6tSMy4EyX2kkhEm6T0HhvarTh8CG0PCjn5p6FP5ZxWwhLcmRN70ItP6Z5MMO4CcJh1JrNxR4Fi4xQgt-CK2aVDMFXd-Br5yQiLVx1CX83w28OD9wssW3Rdltl5e66vCef0Ql6Q5I5e5F0nqGYT989a9fkNgLIx2F8k_az5x07BY59FV2SZg59nSiY7TZNjP8ot11Ew7HKRfPXOdh9eKRUVdhcxzqDePhyzKabU8TG5FP0SiWH5qVPfAgw"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA256SigningWithProvidedPrivateKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPrivateKey()).thenReturn((RSAPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((RSAPublicKey) publicKey); - Algorithm algorithm = Algorithm.RSA256(provider); - String jwtContent = String.format("%s.%s", RS256Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnRSA256SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.RSA256(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnRSA256SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA256withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoRSA384Signing() throws Exception { - Algorithm algorithmSign = Algorithm.RSA384((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - Algorithm algorithmVerify = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "Jx1PaTBnjd_U56MNjifFcY7w9ImDbseg0y8Ijr2pSiA1_wzQb_wy9undaWfzR5YqdIAXvjS8AGuZUAzIoTG4KMgOgdVyYDz3l2jzj6wI-lgqfR5hTy1w1ruMUQ4_wobpdxAiJ4fEbg8Mi_GljOiCO-P1HilxKnpiOJZidR8MQGwTInsf71tOUkK4x5UsdmUueuZbaU-CL5kPnRfXmJj9CcdxZbD9oMlbo23dwkP5BNMrS2LwGGzc9C_-ypxrBIOVilG3WZxcSmuG86LjcZbnL6LBEfph5NmKBgQav147uipb_7umBEr1m2dYiB_9u606n3bcoo3rnsYYK_Xfi1GAEQ"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA384SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.RSA384((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "Jx1PaTBnjd_U56MNjifFcY7w9ImDbseg0y8Ijr2pSiA1_wzQb_wy9undaWfzR5YqdIAXvjS8AGuZUAzIoTG4KMgOgdVyYDz3l2jzj6wI-lgqfR5hTy1w1ruMUQ4_wobpdxAiJ4fEbg8Mi_GljOiCO-P1HilxKnpiOJZidR8MQGwTInsf71tOUkK4x5UsdmUueuZbaU-CL5kPnRfXmJj9CcdxZbD9oMlbo23dwkP5BNMrS2LwGGzc9C_-ypxrBIOVilG3WZxcSmuG86LjcZbnL6LBEfph5NmKBgQav147uipb_7umBEr1m2dYiB_9u606n3bcoo3rnsYYK_Xfi1GAEQ"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA384SigningWithProvidedPrivateKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPrivateKey()).thenReturn((RSAPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((RSAPublicKey) publicKey); - Algorithm algorithm = Algorithm.RSA384(provider); - String jwtContent = String.format("%s.%s", RS384Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnRSA384SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.RSA384(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnRSA384SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA384withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldDoRSA512Signing() throws Exception { - Algorithm algorithmSign = Algorithm.RSA512((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - Algorithm algorithmVerify = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithmSign.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "THIPVYzNZ1Yo_dm0k1UELqV0txs3SzyMopCyHcLXOOdgYXF4MlGvBqu0CFvgSga72Sp5LpuC1Oesj40v_QDsp2GTGDeWnvvcv_eo-b0LPSpmT2h1Ibrmu-z70u2rKf28pkN-AJiMFqi8sit2kMIp1bwIVOovPvMTQKGFmova4Xwb3G526y_PeLlflW1h69hQTIVcI67ACEkAC-byjDnnYIklA-B4GWcggEoFwQRTdRjAUpifA6HOlvnBbZZlUd6KXwEydxVS-eh1odwPjB2_sfbyy5HnLsvNdaniiZQwX7QbwLNT4F72LctYdHHM1QCrID6bgfgYp9Ij9CRX__XDEA"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithmVerify.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA512SigningWithBothKeys() throws Exception { - Algorithm algorithm = Algorithm.RSA512((RSAPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"), (RSAPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); - - String jwtContent = String.format("%s.%s", RS512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - String expectedSignature = "THIPVYzNZ1Yo_dm0k1UELqV0txs3SzyMopCyHcLXOOdgYXF4MlGvBqu0CFvgSga72Sp5LpuC1Oesj40v_QDsp2GTGDeWnvvcv_eo-b0LPSpmT2h1Ibrmu-z70u2rKf28pkN-AJiMFqi8sit2kMIp1bwIVOovPvMTQKGFmova4Xwb3G526y_PeLlflW1h69hQTIVcI67ACEkAC-byjDnnYIklA-B4GWcggEoFwQRTdRjAUpifA6HOlvnBbZZlUd6KXwEydxVS-eh1odwPjB2_sfbyy5HnLsvNdaniiZQwX7QbwLNT4F72LctYdHHM1QCrID6bgfgYp9Ij9CRX__XDEA"; - - assertThat(signatureBytes, is(notNullValue())); - assertThat(jwtSignature, is(expectedSignature)); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldDoRSA512SigningWithProvidedPrivateKey() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA"); - PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA"); - when(provider.getPrivateKey()).thenReturn((RSAPrivateKey) privateKey); - when(provider.getPublicKeyById(null)).thenReturn((RSAPublicKey) publicKey); - Algorithm algorithm = Algorithm.RSA512(provider); - String jwtContent = String.format("%s.%s", RS512Header, auth0IssPayload); - byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); - byte[] signatureBytes = algorithm.sign(contentBytes); - String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); - String token = String.format("%s.%s", jwtContent, jwtSignature); - - assertThat(signatureBytes, is(notNullValue())); - JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); - DecodedJWT decoded = jwt.decode(token); - algorithm.verify(decoded, EncodeType.Base64); - } - - @Test - public void shouldFailOnRSA512SigningWhenProvidedPrivateKeyIsNull() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKey()).thenReturn(null); - Algorithm algorithm = Algorithm.RSA512(provider); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldFailOnRSA512SigningWhenUsingPublicKey() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: SHA512withRSA"); - exception.expectCause(isA(IllegalStateException.class)); - exception.expectCause(hasMessage(is("The given Private Key is null."))); - - Algorithm algorithm = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); - algorithm.sign(new byte[0]); - } - - @Test - public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(NoSuchAlgorithmException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(NoSuchAlgorithmException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - algorithm.sign(RS256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(InvalidKeyException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(InvalidKeyException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - algorithm.sign(RS256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception { - exception.expect(SignatureGenerationException.class); - exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); - exception.expectCause(isA(SignatureException.class)); - - CryptoHelper crypto = mock(CryptoHelper.class); - when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class))) - .thenThrow(SignatureException.class); - - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm(crypto, "some-alg", "some-algorithm", provider); - algorithm.sign(RS256Header.getBytes(StandardCharsets.UTF_8)); - } - - @Test - public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception { - RSAPublicKey publicKey = mock(RSAPublicKey.class); - RSAPrivateKey privateKey = mock(RSAPrivateKey.class); - RSAKeyProvider provider = RSAAlgorithm.providerForKeys(publicKey, privateKey); - Algorithm algorithm = new RSAAlgorithm("some-alg", "some-algorithm", provider); - - assertThat(algorithm.getSigningKeyId(), is(nullValue())); - } - - @Test - public void shouldReturnSigningKeyIdFromProvider() throws Exception { - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("keyId"); - Algorithm algorithm = new RSAAlgorithm("some-alg", "some-algorithm", provider); - - assertThat(algorithm.getSigningKeyId(), is("keyId")); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/AccessJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/AccessJwtCreatorTest.java deleted file mode 100644 index b9e7087..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/AccessJwtCreatorTest.java +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.JWT; -import com.auth0.jwt.jwts.AccessJWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.text.SimpleDateFormat; -import java.util.*; - -public class AccessJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - - - @Test - public void testAccessJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase16Encoding(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase32Encoding(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testAccessJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testAccessJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testAccessJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testAccessJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .setIsNoneAlgorithmAllowed(true) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 9.99) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999L) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", true) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testAccessJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = AccessJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(expDate) - .withIat(iat) - .sign(algorithm); - Verification verification = AccessJWT.require(algorithm); - JWT verifier = verification.createVerifierForAccess(asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - private static void verifyClaims(Map claims, Date exp) { - assertTrue(claims.get(PublicClaims.ISSUER).asList(String.class).get(0).equals("issuer")); - assertTrue(claims.get(PublicClaims.SUBJECT).asList(String.class).get(0).equals("subject")); - assertTrue(claims.get(PublicClaims.AUDIENCE).asString().equals("audience")); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/ExtendedJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/ExtendedJwtCreatorTest.java deleted file mode 100644 index 445f0b0..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/ExtendedJwtCreatorTest.java +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.creators.GoogleJwtCreatorTest.*; -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.GoogleVerification; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.AccessJWT; -import com.auth0.jwt.jwts.ExtendedJWT; -import com.auth0.jwt.jwts.JWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - -public class ExtendedJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - private static final Date nbf = iat; - - @Test - public void testExtendedJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .signBase16Encoding(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .signBase32Encoding(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorInvalidPicture() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'picture' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture("invalid") - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorInvalidEmail() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'email' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail("invalid") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorInvalidName() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'name' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) //this must be called first since ExtendedJwtCreator.build() returns an instance of ExtendedJwtCreator - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName("invalid") - .sign(algorithm); - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .setIsNoneAlgorithmAllowed(true) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 999) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 999L) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 9.99) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", true) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testExtendedJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ExtendedJwtCreator.build() - .withNbf(nbf) - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(expDate) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - - GoogleVerification verification = ExtendedJWT.require(algorithm); - JWT verifier = verification.createVerifierForExtended(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } -} diff --git a/lib/src/test/java/com/auth0/jwt/creators/FbJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/FbJwtCreatorTest.java deleted file mode 100644 index b6cb74e..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/FbJwtCreatorTest.java +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.FbJwtCreator; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.FbJWT; -import com.auth0.jwt.jwts.JWT; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.text.SimpleDateFormat; -import java.util.*; - -public class FbJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - private static final String USER_ID = "userId"; - private static final String APP_ID = "appId"; - - @Test - public void testFbJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .signBase16Encoding(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .signBase32Encoding(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorInvalidUserId() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'userId' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId("invalid") - .withAppId(APP_ID) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testFbJwtCreatorInvalidAppId() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'appId' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId("invalid") - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testFbJwtCreatorUserIdNotProvided() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Standard claim: UserId has not been set"); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withAppId(APP_ID) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testFbJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testFbJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testFbJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", 999) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", 999L) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", 9.99) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", true) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testFbJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(exp) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - @Test - public void testFbJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = FbJwtCreator.build() - .withExp(expDate) - .withIat(iat) - .withUserId(USER_ID) - .withAppId(APP_ID) - .setIsNoneAlgorithmAllowed(true) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - Verification verification = FbJWT.require(algorithm); - JWT verifier = verification.createVerifierForFb(USER_ID, APP_ID).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - - private static void verifyClaims(Map claims) { - assertTrue(claims.get(USER_ID).asString().equals(USER_ID)); - assertTrue(claims.get(APP_ID).asString().equals(APP_ID)); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/GoogleJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/GoogleJwtCreatorTest.java deleted file mode 100644 index ceba3d9..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/GoogleJwtCreatorTest.java +++ /dev/null @@ -1,555 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.GoogleJwtCreator; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.GoogleVerification; -import com.auth0.jwt.jwts.GoogleJWT; -import com.auth0.jwt.jwts.JWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - - -import java.text.SimpleDateFormat; -import java.util.*; - -public class GoogleJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - public static final String PICTURE = "picture"; - public static final String EMAIL = "email"; - public static final String NAME = "name"; - - - @Test - public void testGoogleJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .signBase16Encoding(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .signBase32Encoding(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorWhenCertainRequiredClaimIsntProvided() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Standard claim: Picture has not been set"); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .setIsNoneAlgorithmAllowed(true) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(true) - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - - Algorithm algorithm = Algorithm.none(); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(true) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorInvalidPicture() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'picture' value doesn't match the required one."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture("invalid") - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorInvalidEmail() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'email' value doesn't match the required one."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail("invalid") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorInvalidName() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'name' value doesn't match the required one."); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName("invalid") - .sign(algorithm); - - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimString() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimBoolean() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", true) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimInteger() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 999) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimLong() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 999L) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimDouble() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", 9.99) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorNonStandardClaimDate() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .withName(NAME) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testGoogleJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(expDate) - .withIat(iat) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testGoogleJwtCreatorTokenCantBeUsedBefore() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Token can't be used before Mon Oct 29 00:00:00 PDT 2018."); - - String myDate = "2018/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date iatDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = GoogleJwtCreator.build() - .withPicture(PICTURE) - .withEmail(EMAIL) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iatDate) - .withName(NAME) - .sign(algorithm); - GoogleVerification verification = GoogleJWT.require(algorithm); - JWT verifier = verification.createVerifierForGoogle(PICTURE, EMAIL, asList("issuer"), asList("audience"), - NAME, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testCreateVerifierForExtended() throws Exception{ - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("you shouldn't be calling this method"); - GoogleVerification verification = GoogleJWT.require(Algorithm.HMAC256("secret")); - verification.createVerifierForExtended(null, null, null, null, null, 1L, 1L, 1L); - } - - protected static void verifyClaims(Map claims, Date exp) { - assertTrue(claims.get(PICTURE).asString().equals(PICTURE)); - assertTrue(claims.get(EMAIL).asString().equals(EMAIL)); - assertTrue(claims.get(PublicClaims.ISSUER).asList(String.class).get(0).equals("issuer")); - assertTrue(claims.get(PublicClaims.SUBJECT).asList(String.class).get(0).equals("subject")); - assertTrue(claims.get(PublicClaims.AUDIENCE).asString().equals("audience")); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - assertTrue(claims.get(NAME).asString().equals(NAME)); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/ImplicitJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/ImplicitJwtCreatorTest.java deleted file mode 100644 index bb7a332..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/ImplicitJwtCreatorTest.java +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.TimeUtil; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.ImplicitJWT; -import com.auth0.jwt.jwts.JWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.util.*; - -public class ImplicitJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date iat = generateRandomIatDateInPast(); - - - @Test - public void testImplicitJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .signBase16Encoding(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .signBase32Encoding(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorIssuerNotProvided() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Standard claim: Issuer has not been set"); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .setIsNoneAlgorithmAllowed(false) - .withIat(iat) - .sign(algorithm); - - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testImplicitJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testImplicitJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .setIsNoneAlgorithmAllowed(true) - .withIat(iat) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", 999) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", 999L) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", 9.99) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", true) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - @Test - public void testImplicitJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .withNonStandardClaim("nonStandardClaim", new Date()) - .sign(algorithm); - Verification verification = ImplicitJWT.require(algorithm); - JWT verifier = verification.createVerifierForImplicit(asList("issuer"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims); - } - - private static void verifyClaims(Map claims) { - assertTrue(claims.get(PublicClaims.ISSUER).asList(String.class).get(0).equals("issuer")); - assertTrue(claims.get(PublicClaims.SUBJECT).asList(String.class).get(0).equals("subject")); - assertTrue(claims.get(PublicClaims.AUDIENCE).asString().equals("audience")); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/JWTCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/JWTCreatorTest.java deleted file mode 100644 index 7404e67..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/JWTCreatorTest.java +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import com.auth0.jwt.JsonMatcher; -import com.auth0.jwt.PemUtils; -import com.auth0.jwt.TokenUtils; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.JWTCreator; -import com.auth0.jwt.interfaces.ECDSAKeyProvider; -import com.auth0.jwt.interfaces.RSAKeyProvider; -import org.apache.commons.codec.binary.Base64; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.nio.charset.StandardCharsets; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.RSAPrivateKey; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class JWTCreatorTest { - - private static final String PRIVATE_KEY_FILE_RSA = "src/test/resources/rsa-private.pem"; - private static final String PRIVATE_KEY_FILE_EC_256 = "src/test/resources/ec256-key-private.pem"; - - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void shouldThrowWhenRequestingSignWithoutAlgorithm() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Algorithm cannot be null"); - JWTCreator.init() - .sign(null); - } - - @SuppressWarnings("Convert2Diamond") - @Test - public void shouldAddHeaderClaim() throws Exception { - Map header = new HashMap(); - header.put("asd", 123); - String signed = JWTCreator.init() - .withHeader(header) - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("asd", 123)); - } - - @Test - public void shouldAddKeyId() throws Exception { - String signed = JWTCreator.init() - .withKeyId("56a8bd44da435300010000015f5ed") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("kid", "56a8bd44da435300010000015f5ed")); - } - - @Test - public void shouldAddKeyIdIfAvailableFromRSAAlgorithms() throws Exception { - RSAPrivateKey privateKey = (RSAPrivateKey) PemUtils.readPrivateKeyFromFile(PRIVATE_KEY_FILE_RSA, "RSA"); - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("my-key-id"); - when(provider.getPrivateKey()).thenReturn(privateKey); - - String signed = JWTCreator.init() - .sign(Algorithm.RSA256(provider)); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("kid", "my-key-id")); - } - - @Test - public void shouldNotOverwriteKeyIdIfAddedFromRSAAlgorithms() throws Exception { - RSAPrivateKey privateKey = (RSAPrivateKey) PemUtils.readPrivateKeyFromFile(PRIVATE_KEY_FILE_RSA, "RSA"); - RSAKeyProvider provider = mock(RSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("my-key-id"); - when(provider.getPrivateKey()).thenReturn(privateKey); - - String signed = JWTCreator.init() - .withKeyId("real-key-id") - .sign(Algorithm.RSA256(provider)); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("kid", "my-key-id")); - } - - @Test - public void shouldAddKeyIdIfAvailableFromECDSAAlgorithms() throws Exception { - ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile(PRIVATE_KEY_FILE_EC_256, "EC"); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("my-key-id"); - when(provider.getPrivateKey()).thenReturn(privateKey); - - String signed = JWTCreator.init() - .sign(Algorithm.ECDSA256(provider)); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("kid", "my-key-id")); - } - - @Test - public void shouldNotOverwriteKeyIdIfAddedFromECDSAAlgorithms() throws Exception { - ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile(PRIVATE_KEY_FILE_EC_256, "EC"); - ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); - when(provider.getPrivateKeyId()).thenReturn("my-key-id"); - when(provider.getPrivateKey()).thenReturn(privateKey); - - String signed = JWTCreator.init() - .withKeyId("real-key-id") - .sign(Algorithm.ECDSA256(provider)); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("kid", "my-key-id")); - } - - @Test - public void shouldAddIssuer() throws Exception { - String signed = JWTCreator.init() - .withIssuer("auth0") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJpc3MiOlsiYXV0aDAiXX0")); - } - - @Test - public void shouldAddSubject() throws Exception { - String signed = JWTCreator.init() - .withSubject("1234567890") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJzdWIiOlsiMTIzNDU2Nzg5MCJdfQ")); - } - - @Test - public void shouldAddAudience() throws Exception { - String signed = JWTCreator.init() - .withAudience("Mark") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJhdWQiOiJNYXJrIn0")); - - - String signedArr = JWTCreator.init() - .withAudience("Mark", "David") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signedArr, is(notNullValue())); - assertThat(TokenUtils.splitToken(signedArr)[1], is("eyJhdWQiOlsiTWFyayIsIkRhdmlkIl19")); - } - - @Test - public void shouldAddExpiresAt() throws Exception { - String signed = JWTCreator.init() - .withExpiresAt(new Date(1477592000)) - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJleHAiOjE0Nzc1OTJ9")); - } - - @Test - public void shouldAddNotBefore() throws Exception { - String signed = JWTCreator.init() - .withNotBefore(new Date(1477592000)) - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJuYmYiOjE0Nzc1OTJ9")); - } - - @Test - public void shouldAddIssuedAt() throws Exception { - String signed = JWTCreator.init() - .withIssuedAt(new Date(1477592000)) - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJpYXQiOjE0Nzc1OTJ9")); - } - - @Test - public void shouldAddJWTId() throws Exception { - String signed = JWTCreator.init() - .withJWTId("jwt_id_123") - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("eyJqdGkiOiJqd3RfaWRfMTIzIn0")); - } - - @Test - public void shouldRemoveClaimWhenPassingNull() throws Exception { - String signed = JWTCreator.init() - .withIssuer("iss") - .withIssuer(null) - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[1], is("e30")); - } - - @Test - public void shouldSetCorrectAlgorithmInTheHeader() throws Exception { - String signed = JWTCreator.init() - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("alg", "HS256")); - } - - @Test - public void shouldSetCorrectTypeInTheHeader() throws Exception { - String signed = JWTCreator.init() - .sign(Algorithm.HMAC256("secret")); - - assertThat(signed, is(notNullValue())); - String[] parts = signed.split("\\."); - String headerJson = new String(Base64.decodeBase64(parts[0]), StandardCharsets.UTF_8); - assertThat(headerJson, JsonMatcher.hasEntry("typ", "JWT")); - } - - @Test - public void shouldSetEmptySignatureIfAlgorithmIsNone() throws Exception { - String signed = JWTCreator.init() - .sign(Algorithm.none()); - assertThat(signed, is(notNullValue())); - assertThat(TokenUtils.splitToken(signed)[2], is("")); - } - - @Test - public void shouldThrowOnNullCustomClaimName() throws Exception { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("The Custom Claim's name can't be null."); - JWTCreator.init() - .withNonStandardClaim(null, "value"); - } - - @Test - public void shouldAcceptCustomClaimOfTypeString() throws Exception { - String jwt = JWTCreator.init() - .withNonStandardClaim("name", "value") - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjoidmFsdWUifQ")); - } - - @Test - public void shouldAcceptCustomClaimOfTypeInteger() throws Exception { - String jwt = JWTCreator.init() - .withNonStandardClaim("name", 123) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjoxMjN9")); - } - - @Test - public void shouldAcceptCustomClaimOfTypeLong() throws Exception { - String jwt = JWTCreator.init() - .withNonStandardClaim("name", Long.MAX_VALUE) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjo5MjIzMzcyMDM2ODU0Nzc1ODA3fQ")); - } - - @Test - public void shouldAcceptCustomClaimOfTypeDouble() throws Exception { - String jwt = JWTCreator.init() - .withNonStandardClaim("name", 23.45) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjoyMy40NX0")); - } - - @Test - public void shouldAcceptCustomClaimOfTypeBoolean() throws Exception { - String jwt = JWTCreator.init() - .withNonStandardClaim("name", true) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjp0cnVlfQ")); - } - - @Test - public void shouldAcceptCustomClaimOfTypeDate() throws Exception { - Date date = new Date(1478891521000L); - String jwt = JWTCreator.init() - .withNonStandardClaim("name", date) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjoxNDc4ODkxNTIxfQ")); - } - - @Test - public void shouldAcceptCustomArrayClaimOfTypeString() throws Exception { - String jwt = JWTCreator.init() - .withArrayClaim("name", new String[]{"text", "123", "true"}) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjpbInRleHQiLCIxMjMiLCJ0cnVlIl19")); - } - - @Test - public void shouldAcceptCustomArrayClaimOfTypeInteger() throws Exception { - String jwt = JWTCreator.init() - .withArrayClaim("name", new Integer[]{1, 2, 3}) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjpbMSwyLDNdfQ")); - } - - @Test - public void shouldAcceptCustomArrayClaimOfTypeLong() throws Exception { - String jwt = JWTCreator.init() - .withArrayClaim("name", new Long[]{1L, 2L, 3L}) - .sign(Algorithm.HMAC256("secret")); - - assertThat(jwt, is(notNullValue())); - String[] parts = jwt.split("\\."); - assertThat(parts[1], is("eyJuYW1lIjpbMSwyLDNdfQ")); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/RiscJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/RiscJwtCreatorTest.java deleted file mode 100644 index 31a03ef..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/RiscJwtCreatorTest.java +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.JWT; -import com.auth0.jwt.jwts.RiscJWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.text.SimpleDateFormat; -import java.util.*; - -public class RiscJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - private static final Date nbf = iat; - private static final String jti = "jti"; - - @Test - public void testRiscJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase16Encoding(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase32Encoding(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorJtiNotProvidedButRequired() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Jti has not been set"); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorExpNotProvidedButNotRequired() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Jti has not been set"); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, -1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testRiscJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testRiscJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testRiscJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testRiscJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withNbf(nbf) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(true) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testRiscJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 9.99) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999L) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", true) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testRiscJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = RiscJwtCreator.build() - .withJWTId(jti) - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(expDate) - .withIat(iat) - .sign(algorithm); - Verification verification = RiscJWT.require(algorithm); - JWT verifier = verification.createVerifierForRisc(jti, asList("issuer"), asList("audience"), 1, 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - private static void verifyClaims(Map claims, Date exp) { - assertTrue(claims.get(PublicClaims.ISSUER).asList(String.class).get(0).equals("issuer")); - assertTrue(claims.get(PublicClaims.SUBJECT).asList(String.class).get(0).equals("subject")); - assertTrue(claims.get(PublicClaims.AUDIENCE).asString().equals("audience")); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - assertTrue(claims.get(PublicClaims.JWT_ID).asString().equals(jti)); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/creators/ScopedJwtCreatorTest.java b/lib/src/test/java/com/auth0/jwt/creators/ScopedJwtCreatorTest.java deleted file mode 100644 index 5ebb397..0000000 --- a/lib/src/test/java/com/auth0/jwt/creators/ScopedJwtCreatorTest.java +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.creators; - -import static com.auth0.jwt.TimeUtil.generateRandomExpDateInFuture; -import static com.auth0.jwt.TimeUtil.generateRandomIatDateInPast; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.ScopedJwtCreator; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.TokenExpiredException; -import com.auth0.jwt.impl.PublicClaims; -import com.auth0.jwt.interfaces.Claim; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.JWT; -import com.auth0.jwt.jwts.ScopedJWT; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.text.SimpleDateFormat; -import java.util.*; - -public class ScopedJwtCreatorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - private static final Date exp = generateRandomExpDateInFuture(); - private static final Date iat = generateRandomIatDateInPast(); - - - @Test - public void testScopedJwtCreatorAllStandardClaimsMustBeRequired() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorBase16Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase16Encoding(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode16Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorBase32Encoding() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .signBase32Encoding(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode32Bytes(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorInvalidScope() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'scope' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("invalid") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testScopedJwtCreatorInvalidIssuer() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'iss' value doesn't match the required one."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("invalid") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testScopedJwtCreatorInvalidAudience() throws Exception { - thrown.expect(InvalidClaimException.class); - thrown.expectMessage("The Claim 'aud' value doesn't contain the required audience."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("invalid") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testScopedJwtCreatorScopeNotProvided() throws Exception { - thrown.expect(Exception.class); - thrown.expectMessage("Standard claim: Scope has not been set"); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNoneAlgorithmNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .setIsNoneAlgorithmAllowed(false) - .sign(algorithm); - - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testScopedJwtCreatorNoneAlgorithmNotSpecifiedButStillNotAllowed() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("None algorithm isn't allowed"); - - Algorithm algorithm = Algorithm.none(); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - - @Test - public void testScopedJwtCreatorNoneAlgorithmAllowed() throws Exception { - Algorithm algorithm = Algorithm.none(); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .setIsNoneAlgorithmAllowed(true) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorArrayClaim() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withArrayClaim("arrayKey", "arrayValue1", "arrayValue2") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimStringValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", "nonStandardClaimValue") - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimIntegerValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimDoubleValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 9.99) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimLongValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", 999L) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimBooleanValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", true) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorNonStandardClaimDateValue() throws Exception { - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(exp) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, exp); - } - - @Test - public void testScopedJwtCreatorExpTimeHasPassed() throws Exception { - thrown.expect(TokenExpiredException.class); - thrown.expectMessage("The Token has expired on Wed Oct 29 00:00:00 PDT 2014."); - - String myDate = "2014/10/29"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); - Date date = sdf.parse(myDate); - long expLong = date.getTime(); - Date expDate = new Date(expLong); - - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ScopedJwtCreator.build() - .withScope("scope") - .withIssuer("issuer") - .withSubject("subject") - .withAudience("audience") - .withNonStandardClaim("nonStandardClaim", new Date()) - .withExp(expDate) - .withIat(iat) - .sign(algorithm); - Verification verification = ScopedJWT.require(algorithm); - JWT verifier = verification.createVerifierForScoped("scope", asList("issuer"), asList("audience"), 1, 1).build(); - DecodedJWT jwt = verifier.decode(token); - Map claims = jwt.getClaims(); - verifyClaims(claims, expDate); - } - - private static void verifyClaims(Map claims, Date exp) { - assertTrue(claims.get(PublicClaims.ISSUER).asList(String.class).get(0).equals("issuer")); - assertTrue(claims.get(PublicClaims.SUBJECT).asList(String.class).get(0).equals("subject")); - assertTrue(claims.get(PublicClaims.AUDIENCE).asString().equals("audience")); - assertTrue(claims.get(PublicClaims.EXPIRES_AT).asDate().toString().equals(exp.toString())); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/BasicHeaderTest.java b/lib/src/test/java/com/auth0/jwt/impl/BasicHeaderTest.java deleted file mode 100644 index bd2c59c..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/BasicHeaderTest.java +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.TextNode; -import org.hamcrest.collection.IsMapContaining; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -public class BasicHeaderTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @SuppressWarnings("Convert2Diamond") - @Test - public void shouldHaveUnmodifiableTreeWhenInstantiatedWithNonNullTree() throws Exception { - exception.expect(UnsupportedOperationException.class); - BasicHeader header = new BasicHeader(null, null, null, null, new HashMap()); - header.getTree().put("something", null); - } - - @Test - public void shouldHaveUnmodifiableTreeWhenInstantiatedWithNullTree() throws Exception { - exception.expect(UnsupportedOperationException.class); - BasicHeader header = new BasicHeader(null, null, null, null, null); - header.getTree().put("something", null); - } - - @Test - public void shouldHaveTree() throws Exception { - HashMap map = new HashMap<>(); - JsonNode node = NullNode.getInstance(); - map.put("key", node); - BasicHeader header = new BasicHeader(null, null, null, null, map); - - assertThat(header.getTree(), is(notNullValue())); - assertThat(header.getTree(), is(IsMapContaining.hasEntry("key", node))); - } - - @Test - public void shouldGetAlgorithm() throws Exception { - BasicHeader header = new BasicHeader("HS256", null, null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getAlgorithm(), is(notNullValue())); - assertThat(header.getAlgorithm(), is("HS256")); - } - - @Test - public void shouldGetNullAlgorithmIfMissing() throws Exception { - BasicHeader header = new BasicHeader(null, null, null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getAlgorithm(), is(nullValue())); - } - - @Test - public void shouldGetType() throws Exception { - BasicHeader header = new BasicHeader(null, "jwt", null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getType(), is(notNullValue())); - assertThat(header.getType(), is("jwt")); - } - - @Test - public void shouldGetNullTypeIfMissing() throws Exception { - BasicHeader header = new BasicHeader(null, null, null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getType(), is(nullValue())); - } - - @Test - public void shouldGetContentType() throws Exception { - BasicHeader header = new BasicHeader(null, null, "content", null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getContentType(), is(notNullValue())); - assertThat(header.getContentType(), is("content")); - } - - @Test - public void shouldGetNullContentTypeIfMissing() throws Exception { - BasicHeader header = new BasicHeader(null, null, null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getContentType(), is(nullValue())); - } - - @Test - public void shouldGetKeyId() throws Exception { - BasicHeader header = new BasicHeader(null, null, null, "key", null); - - assertThat(header, is(notNullValue())); - assertThat(header.getKeyId(), is(notNullValue())); - assertThat(header.getKeyId(), is("key")); - } - - @Test - public void shouldGetNullKeyIdIfMissing() throws Exception { - BasicHeader header = new BasicHeader(null, null, null, null, null); - - assertThat(header, is(notNullValue())); - assertThat(header.getKeyId(), is(nullValue())); - } - - @Test - public void shouldGetExtraClaim() throws Exception { - Map tree = new HashMap<>(); - tree.put("extraClaim", new TextNode("extraValue")); - BasicHeader header = new BasicHeader(null, null, null, null, tree); - - assertThat(header, is(notNullValue())); - assertThat(header.getHeaderClaim("extraClaim"), is(instanceOf(JsonNodeClaim.class))); - assertThat(header.getHeaderClaim("extraClaim").asString(), is("extraValue")); - } - - @Test - public void shouldGetNotNullExtraClaimIfMissing() throws Exception { - Map tree = new HashMap<>(); - BasicHeader header = new BasicHeader(null, null, null, null, tree); - - assertThat(header, is(notNullValue())); - assertThat(header.getHeaderClaim("missing"), is(notNullValue())); - assertThat(header.getHeaderClaim("missing"), is(instanceOf(NullClaim.class))); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/ClaimsHolderTest.java b/lib/src/test/java/com/auth0/jwt/impl/ClaimsHolderTest.java deleted file mode 100644 index fbdae57..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/ClaimsHolderTest.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import org.hamcrest.collection.IsMapContaining; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; - -public class ClaimsHolderTest { - - @SuppressWarnings("RedundantCast") - @Test - public void shouldGetClaims() throws Exception { - HashMap claims = new HashMap<>(); - claims.put("iss", "auth0"); - ClaimsHolder holder = new ClaimsHolder(claims); - assertThat(holder, is(notNullValue())); - assertThat(holder.getClaims(), is(notNullValue())); - assertThat(holder.getClaims(), is(instanceOf(Map.class))); - assertThat(holder.getClaims(), is(IsMapContaining.hasEntry("iss", (Object) "auth0"))); - } - - @Test - public void shouldGetNotNullClaims() throws Exception { - ClaimsHolder holder = new ClaimsHolder(null); - assertThat(holder, is(notNullValue())); - assertThat(holder.getClaims(), is(notNullValue())); - assertThat(holder.getClaims(), is(instanceOf(Map.class))); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/HeaderDeserializerTest.java b/lib/src/test/java/com/auth0/jwt/impl/HeaderDeserializerTest.java deleted file mode 100644 index 63c72a7..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/HeaderDeserializerTest.java +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Header; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.TextNode; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.StringReader; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class HeaderDeserializerTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - private HeaderDeserializer deserializer; - - - @Before - public void setUp() throws Exception { - deserializer = new HeaderDeserializer(); - } - - @Test - public void shouldThrowOnNullTree() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("Parsing the Header's JSON resulted on a Null map"); - - JsonDeserializer deserializer = new HeaderDeserializer(); - JsonParser parser = mock(JsonParser.class); - ObjectCodec codec = mock(ObjectCodec.class); - DeserializationContext context = mock(DeserializationContext.class); - - when(codec.readValue(eq(parser), any(TypeReference.class))).thenReturn(null); - when(parser.getCodec()).thenReturn(codec); - - deserializer.deserialize(parser, context); - } - - - @Test - public void shouldNotRemoveKnownPublicClaimsFromTree() throws Exception { - String headerJSON = "{\n" + - " \"alg\": \"HS256\",\n" + - " \"typ\": \"jws\",\n" + - " \"cty\": \"content\",\n" + - " \"kid\": \"key\",\n" + - " \"roles\": \"admin\"\n" + - "}"; - StringReader reader = new StringReader(headerJSON); - JsonParser jsonParser = new JsonFactory().createParser(reader); - ObjectMapper mapper = new ObjectMapper(); - jsonParser.setCodec(mapper); - - Header header = deserializer.deserialize(jsonParser, mapper.getDeserializationContext()); - - assertThat(header, is(notNullValue())); - assertThat(header.getAlgorithm(), is("HS256")); - assertThat(header.getType(), is("jws")); - assertThat(header.getContentType(), is("content")); - assertThat(header.getKeyId(), is("key")); - - assertThat(header.getHeaderClaim("roles").asString(), is("admin")); - assertThat(header.getHeaderClaim("alg").asString(), is("HS256")); - assertThat(header.getHeaderClaim("typ").asString(), is("jws")); - assertThat(header.getHeaderClaim("cty").asString(), is("content")); - assertThat(header.getHeaderClaim("kid").asString(), is("key")); - } - - @Test - public void shouldGetNullStringWhenParsingNullNode() throws Exception { - Map tree = new HashMap<>(); - NullNode node = NullNode.getInstance(); - tree.put("key", node); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(nullValue())); - } - - @Test - public void shouldGetNullStringWhenParsingNull() throws Exception { - Map tree = new HashMap<>(); - tree.put("key", null); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(nullValue())); - } - - @Test - public void shouldGetStringWhenParsingTextNode() throws Exception { - Map tree = new HashMap<>(); - TextNode node = new TextNode("something here"); - tree.put("key", node); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(notNullValue())); - assertThat(text, is("something here")); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/JWTParserTest.java b/lib/src/test/java/com/auth0/jwt/impl/JWTParserTest.java deleted file mode 100644 index a19f3ee..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/JWTParserTest.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Header; -import com.auth0.jwt.interfaces.Payload; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static com.auth0.jwt.impl.JWTParser.getDefaultObjectMapper; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class JWTParserTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - private JWTParser parser; - - @Before - public void setUp() throws Exception { - parser = new JWTParser(); - } - - @Test - public void shouldGetDefaultObjectMapper() throws Exception { - ObjectMapper mapper = getDefaultObjectMapper(); - assertThat(mapper, is(notNullValue())); - assertThat(mapper, is(instanceOf(ObjectMapper.class))); - assertThat(mapper.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS), is(false)); - } - - @Test - public void shouldAddDeserializers() throws Exception { - ObjectMapper mapper = mock(ObjectMapper.class); - new JWTParser(mapper); - verify(mapper).registerModule(any(Module.class)); - } - - @Test - public void shouldParsePayload() throws Exception { - ObjectMapper mapper = mock(ObjectMapper.class); - JWTParser parser = new JWTParser(mapper); - parser.parsePayload("{}"); - - verify(mapper).readValue("{}", Payload.class); - } - - @Test - public void shouldThrowOnInvalidPayload() throws Exception { - String jsonPayload = "{{"; - exception.expect(JWTDecodeException.class); - exception.expectMessage(String.format("The string '%s' doesn't have a valid JSON format.", jsonPayload)); - Payload payload = parser.parsePayload(jsonPayload); - assertThat(payload, is(nullValue())); - } - - @Test - public void shouldParseHeader() throws Exception { - ObjectMapper mapper = mock(ObjectMapper.class); - JWTParser parser = new JWTParser(mapper); - parser.parseHeader("{}"); - - verify(mapper).readValue("{}", Header.class); - } - - @Test - public void shouldThrowOnInvalidHeader() throws Exception { - String jsonHeader = "}}"; - exception.expect(JWTDecodeException.class); - exception.expectMessage(String.format("The string '%s' doesn't have a valid JSON format.", jsonHeader)); - Header header = parser.parseHeader(jsonHeader); - assertThat(header, is(nullValue())); - } - - @Test - public void shouldConvertFromValidJSON() throws Exception { - String json = "\r\n { \r\n } \r\n"; - Object object = parser.convertFromJSON(json, Object.class); - assertThat(object, is(notNullValue())); - } - - @Test - public void shouldThrowWhenConvertingIfNullJson() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The string 'null' doesn't have a valid JSON format."); - String json = null; - Object object = parser.convertFromJSON(json, Object.class); - assertThat(object, is(nullValue())); - } - - @Test - public void shouldThrowWhenConvertingFromInvalidJson() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("The string '}{' doesn't have a valid JSON format."); - String json = "}{"; - Object object = parser.convertFromJSON(json, Object.class); - assertThat(object, is(nullValue())); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/JsonNodeClaimTest.java b/lib/src/test/java/com/auth0/jwt/impl/JsonNodeClaimTest.java deleted file mode 100644 index 2e755d6..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/JsonNodeClaimTest.java +++ /dev/null @@ -1,444 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.UserPojo; -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Claim; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.MissingNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.hamcrest.collection.IsMapContaining; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentMatchers; - -import java.io.IOException; -import java.util.*; - -import static com.auth0.jwt.impl.JWTParser.getDefaultObjectMapper; -import static com.auth0.jwt.impl.JsonNodeClaim.claimFromNode; -import static org.hamcrest.Matchers.*; -import static org.hamcrest.core.IsNull.notNullValue; -import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; - -public class JsonNodeClaimTest { - - private ObjectMapper mapper; - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Before - public void setUp() throws Exception { - mapper = getDefaultObjectMapper(); - } - - @Test - public void shouldGetBooleanValue() throws Exception { - JsonNode value = mapper.valueToTree(true); - Claim claim = claimFromNode(value); - - assertThat(claim.asBoolean(), is(notNullValue())); - assertThat(claim.asBoolean(), is(true)); - } - - @Test - public void shouldGetNullBooleanIfNotBooleanValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asBoolean(), is(nullValue())); - JsonNode stringValue = mapper.valueToTree("boolean"); - assertThat(claimFromNode(stringValue).asBoolean(), is(nullValue())); - } - - @Test - public void shouldGetIntValue() throws Exception { - JsonNode value = mapper.valueToTree(123); - Claim claim = claimFromNode(value); - - assertThat(claim.asInt(), is(notNullValue())); - assertThat(claim.asInt(), is(123)); - } - - @Test - public void shouldGetNullIntIfNotIntValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asInt(), is(nullValue())); - JsonNode stringValue = mapper.valueToTree("123"); - assertThat(claimFromNode(stringValue).asInt(), is(nullValue())); - } - - @Test - public void shouldGetLongValue() throws Exception { - JsonNode value = mapper.valueToTree(Long.MAX_VALUE); - Claim claim = claimFromNode(value); - - assertThat(claim.asLong(), is(notNullValue())); - assertThat(claim.asLong(), is(Long.MAX_VALUE)); - } - - @Test - public void shouldGetNullLongIfNotIntValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asLong(), is(nullValue())); - JsonNode stringValue = mapper.valueToTree("" + Long.MAX_VALUE); - assertThat(claimFromNode(stringValue).asLong(), is(nullValue())); - } - - @Test - public void shouldGetDoubleValue() throws Exception { - JsonNode value = mapper.valueToTree(1.5); - Claim claim = claimFromNode(value); - - assertThat(claim.asDouble(), is(notNullValue())); - assertThat(claim.asDouble(), is(1.5)); - } - - @Test - public void shouldGetNullDoubleIfNotDoubleValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asDouble(), is(nullValue())); - JsonNode stringValue = mapper.valueToTree("123.23"); - assertThat(claimFromNode(stringValue).asDouble(), is(nullValue())); - } - - @Test - public void shouldGetDateValue() throws Exception { - JsonNode value = mapper.valueToTree(1476824844L); - Claim claim = claimFromNode(value); - - assertThat(claim.asDate(), is(notNullValue())); - assertThat(claim.asDate(), is(new Date(1476824844L * 1000))); - } - - @Test - public void shouldGetNullDateIfNotDateValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asDate(), is(nullValue())); - JsonNode stringValue = mapper.valueToTree("1476824844"); - assertThat(claimFromNode(stringValue).asDate(), is(nullValue())); - } - - @Test - public void shouldGetStringValue() throws Exception { - JsonNode value = mapper.valueToTree("string"); - Claim claim = claimFromNode(value); - - assertThat(claim.asString(), is(notNullValue())); - assertThat(claim.asString(), is("string")); - } - - @Test - public void shouldGetNullStringIfNotStringValue() throws Exception { - JsonNode objectValue = mapper.valueToTree(new Object()); - assertThat(claimFromNode(objectValue).asString(), is(nullValue())); - JsonNode intValue = mapper.valueToTree(12345); - assertThat(claimFromNode(intValue).asString(), is(nullValue())); - } - - @Test - public void shouldGetArrayValueOfCustomClass() throws Exception { - JsonNode value = mapper.valueToTree(new UserPojo[]{new UserPojo("George", 1), new UserPojo("Mark", 2)}); - Claim claim = claimFromNode(value); - - assertThat(claim.asArray(UserPojo.class), is(notNullValue())); - assertThat(claim.asArray(UserPojo.class), is(arrayContaining(new UserPojo("George", 1), new UserPojo("Mark", 2)))); - } - - @Test - public void shouldGetArrayValue() throws Exception { - JsonNode value = mapper.valueToTree(new String[]{"string1", "string2"}); - Claim claim = claimFromNode(value); - - assertThat(claim.asArray(String.class), is(notNullValue())); - assertThat(claim.asArray(String.class), is(arrayContaining("string1", "string2"))); - } - - @Test - public void shouldGetNullArrayIfNullValue() throws Exception { - JsonNode value = mapper.valueToTree(null); - Claim claim = claimFromNode(value); - - assertThat(claim.asArray(String.class), is(nullValue())); - } - - @Test - public void shouldGetNullArrayIfNonArrayValue() throws Exception { - JsonNode value = mapper.valueToTree(1); - Claim claim = claimFromNode(value); - - assertThat(claim.asArray(String.class), is(nullValue())); - } - - @Test - public void shouldThrowIfArrayClassMismatch() throws Exception { - JsonNode value = mapper.valueToTree(new String[]{"keys", "values"}); - Claim claim = claimFromNode(value); - - exception.expect(JWTDecodeException.class); - claim.asArray(UserPojo.class); - } - - @Test - public void shouldGetListValueOfCustomClass() throws Exception { - JsonNode value = mapper.valueToTree(Arrays.asList(new UserPojo("George", 1), new UserPojo("Mark", 2))); - Claim claim = claimFromNode(value); - - assertThat(claim.asList(UserPojo.class), is(notNullValue())); - assertThat(claim.asList(UserPojo.class), is(hasItems(new UserPojo("George", 1), new UserPojo("Mark", 2)))); - } - - @Test - public void shouldGetListValue() throws Exception { - JsonNode value = mapper.valueToTree(Arrays.asList("string1", "string2")); - Claim claim = claimFromNode(value); - - assertThat(claim.asList(String.class), is(notNullValue())); - assertThat(claim.asList(String.class), is(hasItems("string1", "string2"))); - } - - @Test - public void shouldGetNullListIfNullValue() throws Exception { - JsonNode value = mapper.valueToTree(null); - Claim claim = claimFromNode(value); - - assertThat(claim.asList(String.class), is(nullValue())); - } - - @Test - public void shouldGetNullListIfNonArrayValue() throws Exception { - JsonNode value = mapper.valueToTree(1); - Claim claim = claimFromNode(value); - - assertThat(claim.asList(String.class), is(nullValue())); - } - - @Test - public void shouldThrowIfListClassMismatch() throws Exception { - JsonNode value = mapper.valueToTree(new String[]{"keys", "values"}); - Claim claim = claimFromNode(value); - - exception.expect(JWTDecodeException.class); - claim.asList(UserPojo.class); - } - - @Test - public void shouldGetNullMapIfNullValue() throws Exception { - JsonNode value = mapper.valueToTree(null); - Claim claim = claimFromNode(value); - - assertThat(claim.asMap(), is(nullValue())); - } - - @Test - public void shouldGetNullMapIfNonArrayValue() throws Exception { - JsonNode value = mapper.valueToTree(1); - Claim claim = claimFromNode(value); - - assertThat(claim.asMap(), is(nullValue())); - } - - @Test - public void shouldGetMapValue() throws Exception { - Map map = new HashMap<>(); - map.put("text", "extraValue"); - map.put("number", 12); - map.put("boolean", true); - map.put("object", Collections.singletonMap("something", "else")); - - JsonNode value = mapper.valueToTree(map); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - Map backMap = claim.asMap(); - assertThat(backMap, is(notNullValue())); - assertThat(backMap, hasEntry("text", (Object) "extraValue")); - assertThat(backMap, hasEntry("number", (Object) 12)); - assertThat(backMap, hasEntry("boolean", (Object) true)); - assertThat(backMap, hasKey("object")); - assertThat((Map) backMap.get("object"), IsMapContaining.hasEntry("something", (Object) "else")); - } - - @Test - public void shouldThrowIfAnExtraordinaryExceptionHappensWhenParsingAsGenericMap() throws Exception { - JsonNode value = mock(ObjectNode.class); - when(value.getNodeType()).thenReturn(JsonNodeType.OBJECT); - - JsonNodeClaim claim = (JsonNodeClaim) claimFromNode(value); - JsonNodeClaim spiedClaim = spy(claim); - ObjectMapper mockedMapper = mock(ObjectMapper.class); - when(spiedClaim.getObjectMapper()).thenReturn(mockedMapper); - JsonParser mockedParser = mock(JsonParser.class); - when(mockedMapper.treeAsTokens(value)).thenReturn(mockedParser); - when(mockedParser.readValueAs(ArgumentMatchers.any(TypeReference.class))).thenThrow(IOException.class); - - exception.expect(JWTDecodeException.class); - spiedClaim.asMap(); - } - - @Test - public void shouldGetCustomClassValue() throws Exception { - JsonNode value = mapper.valueToTree(new UserPojo("john", 123)); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim.as(UserPojo.class).getName(), is("john")); - assertThat(claim.as(UserPojo.class).getId(), is(123)); - } - - @Test - public void shouldThrowIfCustomClassMismatch() throws Exception { - JsonNode value = mapper.valueToTree(new UserPojo("john", 123)); - Claim claim = claimFromNode(value); - - exception.expect(JWTDecodeException.class); - claim.as(String.class); - } - - @SuppressWarnings({"unchecked", "RedundantCast"}) - @Test - public void shouldGetAsMapValue() throws Exception { - JsonNode value = mapper.valueToTree(Collections.singletonMap("key", new UserPojo("john", 123))); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - Map map = claim.as(Map.class); - assertThat(((Map) map.get("key")), hasEntry("name", (Object) "john")); - assertThat(((Map) map.get("key")), hasEntry("id", (Object) 123)); - } - - @Test - public void shouldReturnBaseClaimWhenParsingMissingNode() throws Exception { - JsonNode value = MissingNode.getInstance(); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(NullClaim.class))); - assertThat(claim.isNull(), is(true)); - } - - @Test - public void shouldReturnBaseClaimWhenParsingNullNode() throws Exception { - JsonNode value = NullNode.getInstance(); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(NullClaim.class))); - assertThat(claim.isNull(), is(true)); - } - - @Test - public void shouldReturnBaseClaimWhenParsingNullValue() throws Exception { - JsonNode value = mapper.valueToTree(null); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(NullClaim.class))); - assertThat(claim.isNull(), is(true)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingObject() throws Exception { - JsonNode value = mapper.valueToTree(new Object()); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingArray() throws Exception { - JsonNode value = mapper.valueToTree(new String[]{}); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingList() throws Exception { - JsonNode value = mapper.valueToTree(new ArrayList()); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingStringValue() throws Exception { - JsonNode value = mapper.valueToTree(""); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingIntValue() throws Exception { - JsonNode value = mapper.valueToTree(Integer.MAX_VALUE); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingDoubleValue() throws Exception { - JsonNode value = mapper.valueToTree(Double.MAX_VALUE); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingDateValue() throws Exception { - JsonNode value = mapper.valueToTree(new Date()); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } - - @Test - public void shouldReturnNonNullClaimWhenParsingBooleanValue() throws Exception { - JsonNode value = mapper.valueToTree(Boolean.TRUE); - Claim claim = claimFromNode(value); - - assertThat(claim, is(notNullValue())); - assertThat(claim, is(instanceOf(JsonNodeClaim.class))); - assertThat(claim.isNull(), is(false)); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/NullClaimTest.java b/lib/src/test/java/com/auth0/jwt/impl/NullClaimTest.java deleted file mode 100644 index c7557a7..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/NullClaimTest.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -public class NullClaimTest { - private NullClaim claim; - - @Before - public void setUp() throws Exception { - claim = new NullClaim(); - } - - @Test - public void shouldBeNull() throws Exception { - assertThat(claim.isNull(), is(true)); - } - - @Test - public void shouldGetAsBoolean() throws Exception { - assertThat(claim.asBoolean(), is(nullValue())); - } - - @Test - public void shouldGetAsInt() throws Exception { - assertThat(claim.asInt(), is(nullValue())); - } - - @Test - public void shouldGetAsLong() throws Exception { - assertThat(claim.asLong(), is(nullValue())); - } - - @Test - public void shouldGetAsDouble() throws Exception { - assertThat(claim.asDouble(), is(nullValue())); - } - - @Test - public void shouldGetAsString() throws Exception { - assertThat(claim.asString(), is(nullValue())); - } - - @Test - public void shouldGetAsDate() throws Exception { - assertThat(claim.asDate(), is(nullValue())); - } - - @Test - public void shouldGetAsArray() throws Exception { - assertThat(claim.asArray(Object.class), is(nullValue())); - } - - @Test - public void shouldGetAsList() throws Exception { - assertThat(claim.asList(Object.class), is(nullValue())); - } - - @Test - public void shouldGetAsMap() throws Exception { - assertThat(claim.asMap(), is(nullValue())); - } - - @Test - public void shouldGetAsCustomClass() throws Exception { - assertThat(claim.as(Object.class), is(nullValue())); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java b/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java deleted file mode 100644 index 2a2d3d2..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.Payload; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.*; -import org.hamcrest.collection.IsCollectionWithSize; -import org.hamcrest.collection.IsEmptyCollection; -import org.hamcrest.core.IsCollectionContaining; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.StringReader; -import java.util.*; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class PayloadDeserializerTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - private PayloadDeserializer deserializer; - - @Before - public void setUp() throws Exception { - deserializer = new PayloadDeserializer(); - } - - @Test - public void shouldThrowOnNullTree() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("Parsing the Payload's JSON resulted on a Null map"); - - JsonParser parser = mock(JsonParser.class); - ObjectCodec codec = mock(ObjectCodec.class); - DeserializationContext context = mock(DeserializationContext.class); - - when(codec.readValue(eq(parser), any(TypeReference.class))).thenReturn(null); - when(parser.getCodec()).thenReturn(codec); - - deserializer.deserialize(parser, context); - } - - @Test - public void shouldThrowWhenParsingArrayWithObjectValue() throws Exception { - exception.expect(JWTDecodeException.class); - exception.expectMessage("Couldn't map the Claim's array contents to String"); - - ObjectMapper mapper = new ObjectMapper(); - JsonNode jsonNode = mapper.readTree("{\"some\" : \"random\", \"properties\" : \"inside\"}"); - Map tree = new HashMap<>(); - List subNodes = new ArrayList<>(); - subNodes.add(jsonNode); - ArrayNode arrNode = new ArrayNode(JsonNodeFactory.instance, subNodes); - tree.put("key", arrNode); - - deserializer.getStringOrArray(tree, "key"); - } - - @Test - public void shouldNotRemoveKnownPublicClaimsFromTree() throws Exception { - String payloadJSON = "{\n" + - " \"iss\": \"auth0\",\n" + - " \"sub\": \"emails\",\n" + - " \"aud\": \"users\",\n" + - " \"iat\": 10101010,\n" + - " \"exp\": 11111111,\n" + - " \"nbf\": 10101011,\n" + - " \"jti\": \"idid\",\n" + - " \"roles\":\"admin\" \n" + - "}"; - StringReader reader = new StringReader(payloadJSON); - JsonParser jsonParser = new JsonFactory().createParser(reader); - ObjectMapper mapper = new ObjectMapper(); - jsonParser.setCodec(mapper); - - Payload payload = deserializer.deserialize(jsonParser, mapper.getDeserializationContext()); - - assertThat(payload, is(notNullValue())); - assertTrue(payload.getIssuer().contains("auth0")); - assertTrue(payload.getSubject().contains("emails")); - assertThat(payload.getAudience(), is(IsCollectionContaining.hasItem("users"))); - assertThat(payload.getIssuedAt().getTime(), is(10101010L * 1000)); - assertThat(payload.getExpiresAt().getTime(), is(11111111L * 1000)); - assertThat(payload.getNotBefore().getTime(), is(10101011L * 1000)); - assertThat(payload.getId(), is("idid")); - - assertThat(payload.getClaim("roles").asString(), is("admin")); - assertThat(payload.getClaim("iss").asString(), is("auth0")); - assertThat(payload.getClaim("sub").asString(), is("emails")); - assertThat(payload.getClaim("aud").asString(), is("users")); - assertThat(payload.getClaim("iat").asDouble(), is(10101010D)); - assertThat(payload.getClaim("exp").asDouble(), is(11111111D)); - assertThat(payload.getClaim("nbf").asDouble(), is(10101011D)); - assertThat(payload.getClaim("jti").asString(), is("idid")); - } - - @Test - public void shouldGetStringArrayWhenParsingArrayNode() throws Exception { - Map tree = new HashMap<>(); - List subNodes = new ArrayList<>(); - TextNode textNode1 = new TextNode("one"); - TextNode textNode2 = new TextNode("two"); - subNodes.add(textNode1); - subNodes.add(textNode2); - ArrayNode arrNode = new ArrayNode(JsonNodeFactory.instance, subNodes); - tree.put("key", arrNode); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(notNullValue())); - assertThat(values, is(IsCollectionWithSize.hasSize(2))); - assertThat(values, is(IsCollectionContaining.hasItems("one", "two"))); - } - - @Test - public void shouldGetStringArrayWhenParsingTextNode() throws Exception { - Map tree = new HashMap<>(); - TextNode textNode = new TextNode("something"); - tree.put("key", textNode); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(notNullValue())); - assertThat(values, is(IsCollectionWithSize.hasSize(1))); - assertThat(values, is(IsCollectionContaining.hasItems("something"))); - } - - @Test - public void shouldGetEmptyStringArrayWhenParsingEmptyTextNode() throws Exception { - Map tree = new HashMap<>(); - TextNode textNode = new TextNode(""); - tree.put("key", textNode); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(notNullValue())); - assertThat(values, is(IsEmptyCollection.empty())); - } - - @Test - public void shouldGetNullArrayWhenParsingNullNode() throws Exception { - Map tree = new HashMap<>(); - NullNode node = NullNode.getInstance(); - tree.put("key", node); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(nullValue())); - } - - @Test - public void shouldGetNullArrayWhenParsingNullNodeValue() throws Exception { - Map tree = new HashMap<>(); - tree.put("key", null); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(nullValue())); - } - - @Test - public void shouldGetNullArrayWhenParsingNonArrayOrTextNode() throws Exception { - Map tree = new HashMap<>(); - IntNode node = new IntNode(456789); - tree.put("key", node); - - List values = deserializer.getStringOrArray(tree, "key"); - assertThat(values, is(nullValue())); - } - - - @Test - public void shouldGetNullDateWhenParsingNullNode() throws Exception { - Map tree = new HashMap<>(); - NullNode node = NullNode.getInstance(); - tree.put("key", node); - - Date date = deserializer.getDateFromSeconds(tree, "key"); - assertThat(date, is(nullValue())); - } - - @Test - public void shouldGetNullDateWhenParsingNull() throws Exception { - Map tree = new HashMap<>(); - tree.put("key", null); - - Date date = deserializer.getDateFromSeconds(tree, "key"); - assertThat(date, is(nullValue())); - } - - @Test - public void shouldGetNullDateWhenParsingNonNumericNode() throws Exception { - Map tree = new HashMap<>(); - TextNode node = new TextNode("123456789"); - tree.put("key", node); - - Date date = deserializer.getDateFromSeconds(tree, "key"); - assertThat(date, is(nullValue())); - } - - @Test - public void shouldGetDateWhenParsingNumericNode() throws Exception { - Map tree = new HashMap<>(); - long seconds = 1478627949 / 1000; - LongNode node = new LongNode(seconds); - tree.put("key", node); - - Date date = deserializer.getDateFromSeconds(tree, "key"); - assertThat(date, is(notNullValue())); - assertThat(date.getTime(), is(seconds * 1000)); - } - - @Test - public void shouldGetLargeDateWhenParsingNumericNode() throws Exception { - Map tree = new HashMap<>(); - long seconds = Integer.MAX_VALUE + 10000L; - LongNode node = new LongNode(seconds); - tree.put("key", node); - - Date date = deserializer.getDateFromSeconds(tree, "key"); - assertThat(date, is(notNullValue())); - assertThat(date.getTime(), is(seconds * 1000)); - assertThat(date.getTime(), is(2147493647L * 1000)); - } - - @Test - public void shouldGetNullStringWhenParsingNullNode() throws Exception { - Map tree = new HashMap<>(); - NullNode node = NullNode.getInstance(); - tree.put("key", node); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(nullValue())); - } - - @Test - public void shouldGetNullStringWhenParsingNull() throws Exception { - Map tree = new HashMap<>(); - tree.put("key", null); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(nullValue())); - } - - @Test - public void shouldGetStringWhenParsingTextNode() throws Exception { - Map tree = new HashMap<>(); - TextNode node = new TextNode("something here"); - tree.put("key", node); - - String text = deserializer.getString(tree, "key"); - assertThat(text, is(notNullValue())); - assertThat(text, is("something here")); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/PayloadImplTest.java b/lib/src/test/java/com/auth0/jwt/impl/PayloadImplTest.java deleted file mode 100644 index b81fc3f..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/PayloadImplTest.java +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.interfaces.Claim; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.TextNode; -import org.hamcrest.collection.IsCollectionWithSize; -import org.hamcrest.core.IsCollectionContaining; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; - -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -public class PayloadImplTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - private PayloadImpl payload; - private Date expiresAt; - private Date notBefore; - private Date issuedAt; - - @Before - public void setUp() throws Exception { - expiresAt = Mockito.mock(Date.class); - notBefore = Mockito.mock(Date.class); - issuedAt = Mockito.mock(Date.class); - Map tree = new HashMap<>(); - tree.put("extraClaim", new TextNode("extraValue")); - payload = new PayloadImpl(Collections.singletonList("issuer"), Collections.singletonList("subject"), Collections.singletonList("audience"), expiresAt, notBefore, issuedAt, "jwtId", tree); - } - - @SuppressWarnings("Convert2Diamond") - @Test - public void shouldHaveUnmodifiableTree() throws Exception { - exception.expect(UnsupportedOperationException.class); - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, new HashMap()); - payload.getTree().put("something", null); - } - - @Test - public void shouldGetIssuer() throws Exception { - assertThat(payload, is(notNullValue())); - assertTrue(payload.getIssuer().contains("issuer")); - } - - @Test - public void shouldGetNullIssuerIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getIssuer(), is(nullValue())); - } - - @Test - public void shouldGetSubject() throws Exception { - assertThat(payload, is(notNullValue())); - assertTrue(payload.getSubject().contains("subject")); - } - - @Test - public void shouldGetNullSubjectIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getSubject(), is(nullValue())); - } - - @Test - public void shouldGetAudience() throws Exception { - assertThat(payload, is(notNullValue())); - - assertThat(payload.getAudience(), is(IsCollectionWithSize.hasSize(1))); - assertThat(payload.getAudience(), is(IsCollectionContaining.hasItems("audience"))); - } - - @Test - public void shouldGetNullAudienceIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getAudience(), is(nullValue())); - } - - @Test - public void shouldGetExpiresAt() throws Exception { - assertThat(payload, is(notNullValue())); - assertThat(payload.getExpiresAt(), is(expiresAt)); - } - - @Test - public void shouldGetNullExpiresAtIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getExpiresAt(), is(nullValue())); - } - - @Test - public void shouldGetNotBefore() throws Exception { - assertThat(payload, is(notNullValue())); - assertThat(payload.getNotBefore(), is(notBefore)); - } - - @Test - public void shouldGetNullNotBeforeIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getNotBefore(), is(nullValue())); - } - - @Test - public void shouldGetIssuedAt() throws Exception { - assertThat(payload, is(notNullValue())); - assertThat(payload.getIssuedAt(), is(issuedAt)); - } - - @Test - public void shouldGetNullIssuedAtIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getIssuedAt(), is(nullValue())); - } - - @Test - public void shouldGetJWTId() throws Exception { - assertThat(payload, is(notNullValue())); - assertThat(payload.getId(), is("jwtId")); - } - - @Test - public void shouldGetNullJWTIdIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getId(), is(nullValue())); - } - - @Test - public void shouldGetExtraClaim() throws Exception { - assertThat(payload, is(notNullValue())); - assertThat(payload.getClaim("extraClaim"), is(instanceOf(JsonNodeClaim.class))); - assertThat(payload.getClaim("extraClaim").asString(), is("extraValue")); - } - - @Test - public void shouldGetNotNullExtraClaimIfMissing() throws Exception { - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, null); - assertThat(payload, is(notNullValue())); - assertThat(payload.getClaim("missing"), is(notNullValue())); - assertThat(payload.getClaim("missing"), is(instanceOf(NullClaim.class))); - } - - @Test - public void shouldGetClaims() throws Exception { - Map tree = new HashMap<>(); - tree.put("extraClaim", new TextNode("extraValue")); - tree.put("sub", new TextNode("auth0")); - PayloadImpl payload = new PayloadImpl(null, null, null, null, null, null, null, tree); - assertThat(payload, is(notNullValue())); - Map claims = payload.getClaims(); - assertThat(claims, is(notNullValue())); - - assertThat(claims.get("extraClaim"), is(notNullValue())); - assertThat(claims.get("sub"), is(notNullValue())); - } - - @Test - public void shouldNotAllowToModifyClaimsMap() throws Exception { - assertThat(payload, is(notNullValue())); - Map claims = payload.getClaims(); - assertThat(claims, is(notNullValue())); - exception.expect(UnsupportedOperationException.class); - claims.put("name", null); - } -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java b/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java deleted file mode 100644 index c7e9873..0000000 --- a/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.impl; - -import com.auth0.jwt.UserPojo; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import org.junit.Before; -import org.junit.Test; - -import java.io.StringWriter; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; - -public class PayloadSerializerTest { - - private StringWriter writer; - private PayloadSerializer serializer; - private JsonGenerator jsonGenerator; - private SerializerProvider serializerProvider; - - @Before - public void setUp() throws Exception { - writer = new StringWriter(); - serializer = new PayloadSerializer(); - jsonGenerator = new JsonFactory().createGenerator(writer); - ObjectMapper mapper = new ObjectMapper(); - jsonGenerator.setCodec(mapper); - serializerProvider = mapper.getSerializerProvider(); - } - - @SuppressWarnings("Convert2Diamond") - @Test - public void shouldSerializeEmptyMap() throws Exception { - ClaimsHolder holder = new ClaimsHolder(new HashMap()); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{}"))); - } - - @Test - public void shouldSerializeStringAudienceAsString() throws Exception { - ClaimsHolder holder = holderFor("aud", "auth0"); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"aud\":\"auth0\"}"))); - } - - @Test - public void shouldSerializeSingleItemAudienceAsArray() throws Exception { - ClaimsHolder holder = holderFor("aud", new String[]{"auth0"}); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"aud\":\"auth0\"}"))); - } - - @Test - public void shouldSerializeMultipleItemsAudienceAsArray() throws Exception { - ClaimsHolder holder = holderFor("aud", new String[]{"auth0", "auth10"}); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"aud\":[\"auth0\",\"auth10\"]}"))); - } - - @Test - public void shouldSkipSerializationOnEmptyAudience() throws Exception { - ClaimsHolder holder = holderFor("aud", new String[0]); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{}"))); - } - - @Test - public void shouldSerializeNotBeforeDateInSeconds() throws Exception { - ClaimsHolder holder = holderFor("nbf", new Date(1478874000)); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"nbf\":1478874}"))); - } - - @Test - public void shouldSerializeIssuedAtDateInSeconds() throws Exception { - ClaimsHolder holder = holderFor("iat", new Date(1478874000)); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"iat\":1478874}"))); - } - - @Test - public void shouldSerializeExpiresAtDateInSeconds() throws Exception { - ClaimsHolder holder = holderFor("exp", new Date(1478874000)); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"exp\":1478874}"))); - } - - @Test - public void shouldSerializeCustomDateInSeconds() throws Exception { - ClaimsHolder holder = holderFor("birthdate", new Date(1478874000)); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"birthdate\":1478874}"))); - } - - @Test - public void shouldSerializeDatesUsingLong() throws Exception { - long secs = Integer.MAX_VALUE + 10000L; - Date date = new Date(secs * 1000L); - Map claims = new HashMap(); - claims.put("iat", date); - claims.put("nbf", date); - claims.put("exp", date); - claims.put("ctm", date); - ClaimsHolder holder = new ClaimsHolder(claims); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - String json = writer.toString(); - assertThat(json, containsString("\"iat\":2147493647")); - assertThat(json, containsString("\"nbf\":2147493647")); - assertThat(json, containsString("\"exp\":2147493647")); - assertThat(json, containsString("\"ctm\":2147493647")); - } - - @Test - public void shouldSerializeStrings() throws Exception { - ClaimsHolder holder = holderFor("name", "Auth0 Inc"); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"name\":\"Auth0 Inc\"}"))); - } - - @Test - public void shouldSerializeIntegers() throws Exception { - ClaimsHolder holder = holderFor("number", 12345); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"number\":12345}"))); - } - - @Test - public void shouldSerializeDoubles() throws Exception { - ClaimsHolder holder = holderFor("fraction", 23.45); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"fraction\":23.45}"))); - } - - @Test - public void shouldSerializeBooleans() throws Exception { - ClaimsHolder holder = holderFor("pro", true); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"pro\":true}"))); - } - - @Test - public void shouldSerializeNulls() throws Exception { - ClaimsHolder holder = holderFor("id", null); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"id\":null}"))); - } - - @Test - public void shouldSerializeCustomArrayOfObject() throws Exception { - UserPojo user1 = new UserPojo("Michael", 1); - UserPojo user2 = new UserPojo("Lucas", 2); - ClaimsHolder holder = holderFor("users", new UserPojo[]{user1, user2}); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"users\":[{\"name\":\"Michael\",\"id\":1},{\"name\":\"Lucas\",\"id\":2}]}"))); - } - - @Test - public void shouldSerializeCustomListOfObject() throws Exception { - UserPojo user1 = new UserPojo("Michael", 1); - UserPojo user2 = new UserPojo("Lucas", 2); - ClaimsHolder holder = holderFor("users", Arrays.asList(user1, user2)); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"users\":[{\"name\":\"Michael\",\"id\":1},{\"name\":\"Lucas\",\"id\":2}]}"))); - } - - @Test - public void shouldSerializeCustomObject() throws Exception { - UserPojo user = new UserPojo("Michael", 1); - ClaimsHolder holder = holderFor("users", user); - serializer.serialize(holder, jsonGenerator, serializerProvider); - jsonGenerator.flush(); - - assertThat(writer.toString(), is(equalTo("{\"users\":{\"name\":\"Michael\",\"id\":1}}"))); - } - - @SuppressWarnings("Convert2Diamond") - private ClaimsHolder holderFor(String key, Object value) { - Map map = new HashMap(); - map.put(key, value); - return new ClaimsHolder(map); - } - -} \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/jwt/verification/VerificationAndAssertionTest.java b/lib/src/test/java/com/auth0/jwt/verification/VerificationAndAssertionTest.java deleted file mode 100644 index cd611cd..0000000 --- a/lib/src/test/java/com/auth0/jwt/verification/VerificationAndAssertionTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2017 The Authors of 'JWTS for Java' -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package com.auth0.jwt.verification; - -import com.auth0.jwt.TimeUtil; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.creators.ImplicitJwtCreator; -import com.auth0.jwt.exceptions.AlgorithmMismatchException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.auth0.jwt.interfaces.Verification; -import com.auth0.jwt.jwts.ImplicitJWT; -import com.auth0.jwt.jwts.JWT; -import com.auth0.jwt.verification.VerificationAndAssertion; -import static java.util.Arrays.asList; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class VerificationAndAssertionTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void testAssertPositiveWithNegativeNumber() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Leeway value can't be negative."); - - VerificationAndAssertion.assertPositive(-1); - } - - @Test - public void testAssertNullWithNullString() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("The Custom Claim's name can't be null."); - - VerificationAndAssertion.assertNonNull(null); - } - - @Test - public void testVerifyAlgorithmWithMismatchingAlgorithms() throws Exception { - thrown.expect(AlgorithmMismatchException.class); - thrown.expectMessage("The provided Algorithm doesn't match the one defined in the JWT's Header."); - Algorithm algorithm = Algorithm.HMAC256("secret"); - String token = ImplicitJwtCreator.build() - .withIssuer("accounts.fake.com") - .withSubject("subject") - .withAudience("audience") - .withIat(TimeUtil.generateRandomIatDateInPast()) - .sign(algorithm); - Verification verification = ImplicitJWT.require(Algorithm.none()); - JWT verifier = verification.createVerifierForImplicit(asList("accounts.fake.com"), asList("audience"), 1).build(); - DecodedJWT jwt = verifier.decode(token); - } - -} diff --git a/lib/src/test/resources/ec256-key-pair.pem b/lib/src/test/resources/ec256-key-pair.pem deleted file mode 100644 index 63e8673..0000000 --- a/lib/src/test/resources/ec256-key-pair.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIDxiRgJuF9X7wbgtc0qTv+CM8ej13zTGoimkuUVJBahBoAoGCCqGSM49 -AwEHoUQDQgAEQgb5npLHd0Bk61bNnjK632uwmBfrF7I8hoPgaOZjyhh+BrPDO6CL -6D/aW/yPObXXm7SpZogmRwGROcOA3yUleg== ------END EC PRIVATE KEY----- diff --git a/lib/src/test/resources/ec256-key-private.pem b/lib/src/test/resources/ec256-key-private.pem deleted file mode 100644 index 756361a..0000000 --- a/lib/src/test/resources/ec256-key-private.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPGJGAm4X1fvBuC1z -SpO/4Izx6PXfNMaiKaS5RUkFqEGhRANCAARCBvmeksd3QGTrVs2eMrrfa7CYF+sX -sjyGg+Bo5mPKGH4Gs8M7oIvoP9pb/I85tdebtKlmiCZHAZE5w4DfJSV6 ------END PRIVATE KEY----- diff --git a/lib/src/test/resources/ec256-key-public-invalid.pem b/lib/src/test/resources/ec256-key-public-invalid.pem deleted file mode 100644 index 8e4f6a9..0000000 --- a/lib/src/test/resources/ec256-key-public-invalid.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjT -CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/ec256-key-public.pem b/lib/src/test/resources/ec256-key-public.pem deleted file mode 100644 index 34401f7..0000000 --- a/lib/src/test/resources/ec256-key-public.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQgb5npLHd0Bk61bNnjK632uwmBfr -F7I8hoPgaOZjyhh+BrPDO6CL6D/aW/yPObXXm7SpZogmRwGROcOA3yUleg== ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/ec384-key-pair.pem b/lib/src/test/resources/ec384-key-pair.pem deleted file mode 100644 index 8c12408..0000000 --- a/lib/src/test/resources/ec384-key-pair.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDCVWQsOJHjKD0I4cXOYJm4G8i5c7IMhFbxFq57OUlrTVmND43dvvNW1 -oQ6i6NiXEQWgBwYFK4EEACKhZANiAASezSGlAu4wAaJe4676mQM0F/5slI+Ekdpt -RJdfsQP9mNxe7RdzHgcSw7j/Wxa45nlnFnFrPPL4viJKOBRxMB1jjVA9my9PixxJ -GoB22qDQwFbP8ldmEp6abwdBsXNaePM= ------END EC PRIVATE KEY----- diff --git a/lib/src/test/resources/ec384-key-private.pem b/lib/src/test/resources/ec384-key-private.pem deleted file mode 100644 index 9482bfa..0000000 --- a/lib/src/test/resources/ec384-key-private.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCVWQsOJHjKD0I4cXOY -Jm4G8i5c7IMhFbxFq57OUlrTVmND43dvvNW1oQ6i6NiXEQWhZANiAASezSGlAu4w -AaJe4676mQM0F/5slI+EkdptRJdfsQP9mNxe7RdzHgcSw7j/Wxa45nlnFnFrPPL4 -viJKOBRxMB1jjVA9my9PixxJGoB22qDQwFbP8ldmEp6abwdBsXNaePM= ------END PRIVATE KEY----- diff --git a/lib/src/test/resources/ec384-key-public-invalid.pem b/lib/src/test/resources/ec384-key-public-invalid.pem deleted file mode 100644 index 1f4b685..0000000 --- a/lib/src/test/resources/ec384-key-public-invalid.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJ0tamPyAJVUhDO1DlceSYCdA9WKVX6nO -K4VYetXvqmMKdyVkaoA4Gl02KoVLujiSSSAE6oK/Hf7x2fagaE9LgJdJxg07Ip+T -C6cgFi2HHDeXG7djB5Zl1TKA9/w/8iW5 ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/ec384-key-public.pem b/lib/src/test/resources/ec384-key-public.pem deleted file mode 100644 index 511596e..0000000 --- a/lib/src/test/resources/ec384-key-public.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEns0hpQLuMAGiXuOu+pkDNBf+bJSPhJHa -bUSXX7ED/ZjcXu0Xcx4HEsO4/1sWuOZ5ZxZxazzy+L4iSjgUcTAdY41QPZsvT4sc -SRqAdtqg0MBWz/JXZhKemm8HQbFzWnjz ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/ec512-key-pair.pem b/lib/src/test/resources/ec512-key-pair.pem deleted file mode 100644 index 1428daa..0000000 --- a/lib/src/test/resources/ec512-key-pair.pem +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MIHbAgEBBEHzl1DpZSQJ8YhCbN/uvo5SOu0BjDDX9Gub6zsBW6B2TxRzb5sBeQaW -VscDUZha4Xr1HEWpVtua9+nEQU/9Aq9Pl6AHBgUrgQQAI6GBiQOBhgAEAJhvCa6S -89ePqlLO6MRV9KQqHvdAITDAf/WRDcvCmfrrNuov+j4gQXO12ohIukPCHM9rYms8 -Eqciz3gaxVTxZD4CAA8i2k9H6ew9iSh1qXa1kLxiyzMBqmAmmg4u/SroD6OleG56 -SwZVbWx+KIINB6r/PQVciGX8FjwgR/mbLHotVZYD ------END EC PRIVATE KEY----- diff --git a/lib/src/test/resources/ec512-key-private.pem b/lib/src/test/resources/ec512-key-private.pem deleted file mode 100644 index bde9098..0000000 --- a/lib/src/test/resources/ec512-key-private.pem +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIHtAgEAMBAGByqGSM49AgEGBSuBBAAjBIHVMIHSAgEBBEHzl1DpZSQJ8YhCbN/u -vo5SOu0BjDDX9Gub6zsBW6B2TxRzb5sBeQaWVscDUZha4Xr1HEWpVtua9+nEQU/9 -Aq9Pl6GBiQOBhgAEAJhvCa6S89ePqlLO6MRV9KQqHvdAITDAf/WRDcvCmfrrNuov -+j4gQXO12ohIukPCHM9rYms8Eqciz3gaxVTxZD4CAA8i2k9H6ew9iSh1qXa1kLxi -yzMBqmAmmg4u/SroD6OleG56SwZVbWx+KIINB6r/PQVciGX8FjwgR/mbLHotVZYD ------END PRIVATE KEY----- diff --git a/lib/src/test/resources/ec512-key-public-invalid.pem b/lib/src/test/resources/ec512-key-public-invalid.pem deleted file mode 100644 index f976d7f..0000000 --- a/lib/src/test/resources/ec512-key-public-invalid.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgtBWt9rVtdQPdeoChvCXnXHvkg/F -41AAubIVd+3yTvLFmxuHuaor9CHl7FlT3532mUG+GG0EEw5UuYkFrg/ABBgAfuVf -wO1u0V0wJPkmpxcnZoojFaAOKcsBvUvDulbBh0HhAyd+nlfZquvV43uwFVpn2Cjb -Lx+/AT1PE6Muqy4JkGU= ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/ec512-key-public.pem b/lib/src/test/resources/ec512-key-public.pem deleted file mode 100644 index 360209a..0000000 --- a/lib/src/test/resources/ec512-key-public.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAmG8JrpLz14+qUs7oxFX0pCoe90Ah -MMB/9ZENy8KZ+us26i/6PiBBc7XaiEi6Q8Icz2tiazwSpyLPeBrFVPFkPgIADyLa -T0fp7D2JKHWpdrWQvGLLMwGqYCaaDi79KugPo6V4bnpLBlVtbH4ogg0Hqv89BVyI -ZfwWPCBH+Zssei1VlgM= ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/rsa-private.pem b/lib/src/test/resources/rsa-private.pem deleted file mode 100644 index e451968..0000000 --- a/lib/src/test/resources/rsa-private.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ -tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB -XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k -ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL -DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ -mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K -3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN -tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36 -ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj -NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4 -ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO -u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U -6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui -wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us -rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv -TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp -PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ -FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz -FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG -m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC -PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq -PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE -kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe -RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb -vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX -rK0/Ikt5ybqUzKCMJZg2VKGTxg== ------END PRIVATE KEY----- \ No newline at end of file diff --git a/lib/src/test/resources/rsa-public.pem b/lib/src/test/resources/rsa-public.pem deleted file mode 100644 index e8d6288..0000000 --- a/lib/src/test/resources/rsa-public.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4 -yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9 -83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs -WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT -69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8 -AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0 -YwIDAQAB ------END PUBLIC KEY----- diff --git a/lib/src/test/resources/rsa-public_invalid.pem b/lib/src/test/resources/rsa-public_invalid.pem deleted file mode 100644 index eab17cf..0000000 --- a/lib/src/test/resources/rsa-public_invalid.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK -5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa -vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0 -FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC -VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M -r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s -YwIDAQAB ------END PUBLIC KEY----- diff --git a/local.properties b/local.properties deleted file mode 100644 index 93e073d..0000000 --- a/local.properties +++ /dev/null @@ -1,12 +0,0 @@ -## This file is automatically generated by Android Studio. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Fri Dec 02 18:18:12 ART 2016 -ndk.dir=/Users/hernan/Development/Android.SDK/ndk-bundle -sdk.dir=/Users/hernan/Development/Android.SDK diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b1c69ea --- /dev/null +++ b/pom.xml @@ -0,0 +1,158 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 9 + + + com.auth0 + java-jwt + 2.3.1-SNAPSHOT + + Java JWT + Java implementation of JSON Web Token developed against draft-ietf-oauth-json-web-token-08. + + http://www.jwt.io + + + 1.7 + 1.7 + com.auth0.jwt.internal + + + + + The MIT License + http://www.opensource.org/licenses/mit-license.php + repo + + + + + https://github.com/auth0/java-jwt + scm:git:git@github.com:auth0/java-jwt.git + scm:git:git@github.com:auth0/java-jwt.git + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.0.1 + + + + org.bouncycastle + bcprov-jdk15on + 1.52 + + + + commons-codec + commons-codec + 1.10 + + + + org.apache.commons + commons-lang3 + 3.4 + + + + + + junit + junit + 4.12 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.source.version} + ${java.target.version} + UTF-8 + + + + org.jacoco + jacoco-maven-plugin + 0.7.7.201606060606 + + + + prepare-agent + + + + report + test + + report + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + false + true + + + com.fasterxml.jackson + ${repackage.base}.com.fasterxml.jackson + + + org.apache.commons.codec + ${repackage.base}.org.apache.commons.codec + + + org.apache.commons.io + ${repackage.base}.org.apache.commons.io + + + org.apache.commons.lang3 + ${repackage.base}.org.apache.commons.lang3 + + + org.bouncycastle + ${repackage.base}.org.bouncycastle + + + + + + + + + diff --git a/scripts/bintray.gradle b/scripts/bintray.gradle deleted file mode 100644 index ba86812..0000000 --- a/scripts/bintray.gradle +++ /dev/null @@ -1,55 +0,0 @@ -def credentials = new Bintray(project); - -if (credentials.valid()) { - apply plugin: 'com.jfrog.bintray' - bintray { - user = credentials.user - key = credentials.key - publications = ['mavenJava'] - dryRun = project.version.endsWith("-SNAPSHOT") - publish = false - pkg { - repo = 'java' - name = 'java-jwt' - desc = 'Java implementation of JSON Web Token (JWT) ' - websiteUrl = 'https://github.com/auth0/java-jwt' - vcsUrl = 'scm:git@github.com:auth0/java-jwt.git' - licenses = ["MIT"] - userOrg = 'auth0' - publish = false - version { - gpg { - sign = true - passphrase = credentials.passphrasse - } - vcsTag = project.version - name = project.version - released = new Date() - } - } - } -} - -class Bintray { - String user - String key - String passphrasse - - Bintray(project) { - this.user = Bintray.value(project, 'BINTRAY_USER', 'bintray.user') - this.key = Bintray.value(project, 'BINTRAY_KEY', 'bintray.key') - this.passphrasse = Bintray.value(project, 'BINTRAY_PASSPHRASE', 'bintray.gpg.password') - } - - def valid() { - return this.user != null && this.key != null && this.passphrasse != null; - } - - private static def value(Project project, String env, String property) { - def value = System.getenv(env) - if (project.hasProperty(property)) { - value = project.getProperty(property); - } - return value - } -} \ No newline at end of file diff --git a/scripts/maven.gradle b/scripts/maven.gradle deleted file mode 100644 index a541b00..0000000 --- a/scripts/maven.gradle +++ /dev/null @@ -1,105 +0,0 @@ -apply plugin: Auth0OSS - -class Auth0OSS implements Plugin { - - void apply(Project target) { - target.extensions.create("auth0", Auth0Extension, target) - target.configure(target) { - apply plugin: 'maven-publish' - - target.task("sourcesJar", type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - target.task("javadocJar", type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.getDestinationDir() - } - - artifacts { - archives sourcesJar, javadocJar - } - - publishing { - publications { - mavenJava(MavenPublication) { - from components.java - artifact sourcesJar - artifact javadocJar - groupId project.group - artifactId project.name - version project.version - } - } - } - - publishing.publications.all { - pom.withXml { - - def lib = project.extensions.auth0 - def root = asNode() - - root.appendNode('packaging', 'jar') - root.appendNode('name', lib.name) - root.appendNode('description', lib.description) - root.appendNode('url', lib.url) - - def developersNode = root.appendNode('developers') - project.extensions.auth0.developers.each { - def node = developersNode.appendNode('developer') - node.appendNode('id', it.id) - node.appendNode('name', it.name) - node.appendNode('email', it.email) - } - - def dependenciesNode = root.appendNode('dependencies') - - configurations.compile.allDependencies.each { - def dependencyNode = dependenciesNode.appendNode('dependency') - dependencyNode.appendNode('groupId', it.group) - dependencyNode.appendNode('artifactId', it.name) - dependencyNode.appendNode('version', it.version) - } - - def licenceNode = root.appendNode('licenses').appendNode('license') - licenceNode.appendNode('name', 'The MIT License (MIT)') - licenceNode.appendNode('url', "https://raw.githubusercontent.com/auth0/${lib.repo}/master/LICENSE") - licenceNode.appendNode('distribution', 'repo') - - def scmNode = root.appendNode('scm') - scmNode.appendNode('connection', "scm:git@github.com:auth0/${lib.repo}.git") - scmNode.appendNode('developerConnection', "scm:git@github.com:auth0/${lib.repo}.git") - scmNode.appendNode('url', "https://github.com/auth0/${lib.repo}") - } - } - } - } -} - -class Auth0Extension { - String name - String repo - String description - String url - List developers = [] - - private Project project - - Auth0Extension(project) { - this.project = project - } - - void developer(Closure developerClosure) { - def developer = project.configure(new Developer(), developerClosure) - developers.add(developer) - } -} - -class Developer { - String id - String name - String email -} - - - diff --git a/scripts/release.gradle b/scripts/release.gradle deleted file mode 100644 index da74e9b..0000000 --- a/scripts/release.gradle +++ /dev/null @@ -1,170 +0,0 @@ -import java.text.SimpleDateFormat - -apply plugin: ReleasePlugin - -class Semver { - String version - def snapshot - - def getStringVersion() { - return snapshot ? "$version-SNAPSHOT" : version - } - - def nextPatch() { - def parts = version.split("\\.") - def patch = Integer.parseInt(parts[2]) + 1 - return "${parts[0]}.${parts[1]}.${patch}" - } - - def nextMinor() { - def parts = version.split("\\.") - def minor = Integer.parseInt(parts[1]) + 1 - return "${parts[0]}.${minor}.0" - } - -} - -class ChangeLogTask extends DefaultTask { - - def current - def next - - @TaskAction - def update() { - def repository = project.auth0.repo - def file = new File('CHANGELOG.md') - def output = new File('CHANGELOG.md.release') - output.newWriter().withWriter { writer -> - - file.eachLine { line, number -> - if (number == 0 && !line.startsWith('# Change Log')) { - throw new GradleException('Change Log file is not properly formatted') - } - - writer.println(line) - - if (number == 0 || number > 1) { - return - } - - def formatter = new SimpleDateFormat('yyyy-MM-dd') - writer.println() - writer.println("## [${next}](https://github.com/auth0/${repository}/tree/${next}) (${formatter.format(new Date())})") - writer.println("[Full Changelog](https://github.com/auth0/${repository}/compare/${current}...${next})") - def command = ["curl", "https://webtask.it.auth0.com/api/run/wt-hernan-auth0_com-0/oss-changelog.js?webtask_no_cache=1&repo=${repository}&milestone=${next}", "-f", "-s", "-H", "Accept: text/markdown"] - def content = command.execute() - content.consumeProcessOutputStream(writer) - if (content.waitFor() != 0) { - throw new GradleException("Failed to request changelog for version ${next}") - } - } - } - file.delete() - output.renameTo('CHANGELOG.md') - } -} - -class ReleaseTask extends DefaultTask { - - def tagName - - @TaskAction - def perform() { - def path = project.getRootProject().getProjectDir().path - project.exec { - commandLine 'git', 'add', 'README.md' - workingDir path - } - project.exec { - commandLine 'git', 'add', 'CHANGELOG.md' - workingDir path - } - project.exec { - commandLine 'git', 'commit', '-m', "Release ${tagName}" - workingDir path - } - project.exec { - commandLine 'git', 'tag', "${tagName}" - workingDir path - } - } -} - -class ReadmeTask extends DefaultTask { - - def current - def next - - final filename = 'README.md' - - @TaskAction - def update() { - def file = new File(filename) - def gradleUpdated = "compile '${project.group}:${project.name}:${next}'" - def oldSingleQuote = "compile '${project.group}:${project.name}:${current}'" - def oldDoubleQuote = "compile \"${project.group}:${project.name}:${current}\"" - def mavenUpdated = "${next}" - def mavenOld = "${current}" - def contents = file.getText('UTF-8') - contents = contents.replace(oldSingleQuote, gradleUpdated).replace(oldDoubleQuote, gradleUpdated).replace(mavenOld, mavenUpdated) - file.write(contents, 'UTF-8') - } - -} - -class ReleasePlugin implements Plugin { - void apply(Project target) { - def semver = current() - target.version = semver.stringVersion - def version = semver.version - def nextMinor = semver.nextMinor() - def nextPatch = semver.nextPatch() - target.task('changelogMinor', type: ChangeLogTask) { - current = version - next = nextMinor - } - target.task('changelogPatch', type: ChangeLogTask) { - current = version - next = nextPatch - } - target.task('readmeMinor', type: ReadmeTask, dependsOn: 'changelogMinor') { - current = version - next = nextMinor - } - target.task('readmePatch', type: ReadmeTask, dependsOn: 'changelogPatch') { - current = version - next = nextPatch - } - target.task('releaseMinor', type: ReleaseTask, dependsOn: 'readmeMinor') { - tagName = nextMinor - } - target.task('releasePatch', type: ReleaseTask, dependsOn: 'readmePatch') { - tagName = nextPatch - } - } - - static def current() { - def current = describeGit(false) - def snapshot = current == null - if (snapshot) { - current = describeGit(snapshot, '0.0.1') - } - return new Semver(snapshot: snapshot, version: current) - } - - static def describeGit(boolean snapshot, String defaultValue = null) { - def command = ['git', 'describe', '--tags', (snapshot ? '--abbrev=0' : '--exact-match')].execute() - def stdout = new ByteArrayOutputStream() - def errout = new ByteArrayOutputStream() - command.consumeProcessOutput(stdout, errout) - if (command.waitFor() != 0) { - Logging.getLogger(ReleasePlugin.class).debug(errout.toString()) - return defaultValue - } - if (stdout.toByteArray().length > 0) { - return stdout.toString().replace('\n', "") - } - - return defaultValue - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index ce7f0a6..0000000 --- a/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':java-jwt' -project(':java-jwt').projectDir = new File(rootProject.projectDir, '/lib') \ No newline at end of file diff --git a/src/main/java/com/auth0/jwt/Algorithm.java b/src/main/java/com/auth0/jwt/Algorithm.java new file mode 100644 index 0000000..b3009a7 --- /dev/null +++ b/src/main/java/com/auth0/jwt/Algorithm.java @@ -0,0 +1,33 @@ +package com.auth0.jwt; + +import org.apache.commons.lang3.Validate; + +/** + * Supported Library Algorithms + * + * https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator + */ +public enum Algorithm { + + HS256("HmacSHA256"), HS384("HmacSHA384"), HS512("HmacSHA512"), RS256("SHA256withRSA"), RS384("SHA384withRSA"), RS512("SHA512withRSA"); + + private Algorithm(final String value) { + this.value = value; + } + + private String value; + + public String getValue() { + return value; + } + + public static Algorithm findByName(final String name) throws JWTAlgorithmException { + Validate.notNull(name); + try { + return Algorithm.valueOf(name); + } catch (IllegalArgumentException e) { + throw new JWTAlgorithmException("Unsupported algorithm: " + name); + } + } + +} diff --git a/src/main/java/com/auth0/jwt/JWTAlgorithmException.java b/src/main/java/com/auth0/jwt/JWTAlgorithmException.java new file mode 100644 index 0000000..fec47b3 --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTAlgorithmException.java @@ -0,0 +1,20 @@ +package com.auth0.jwt; + +/** + * Represents Exception related to Algorithm - for example JWT header algorithm is unsupported / missing + */ +public class JWTAlgorithmException extends JWTVerifyException { + + + public JWTAlgorithmException() {} + + public JWTAlgorithmException(final String message, final Throwable cause) { + super(message, cause); + } + + public JWTAlgorithmException(final String message) { + super(message); + } + +} + diff --git a/src/main/java/com/auth0/jwt/JWTAudienceException.java b/src/main/java/com/auth0/jwt/JWTAudienceException.java new file mode 100644 index 0000000..622d73b --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTAudienceException.java @@ -0,0 +1,36 @@ +package com.auth0.jwt; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.commons.lang3.Validate; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents Exception related to Audience - for example illegal audience on JWT Verification + */ +public class JWTAudienceException extends JWTVerifyException { + + private JsonNode audienceNode; + + public JWTAudienceException(final JsonNode audienceNode) { + this.audienceNode = audienceNode; + } + + public JWTAudienceException(final String message, final JsonNode audienceNode) { + super(message); + this.audienceNode = audienceNode; + } + + public List getAudience() { + final ArrayList audience = new ArrayList<>(); + if (audienceNode.isArray()) { + for (final JsonNode jsonNode : audienceNode) { + audience.add(jsonNode.textValue()); + } + } else if (audienceNode.isTextual()) { + audience.add(audienceNode.textValue()); + } + return audience; + } +} diff --git a/src/main/java/com/auth0/jwt/JWTExpiredException.java b/src/main/java/com/auth0/jwt/JWTExpiredException.java new file mode 100644 index 0000000..41086ee --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTExpiredException.java @@ -0,0 +1,23 @@ +package com.auth0.jwt; + + +/** + * Represents Exception related to Expiration - for example JWT token has expired + */ +public class JWTExpiredException extends JWTVerifyException { + + private long expiration; + + public JWTExpiredException(final long expiration) { + this.expiration = expiration; + } + + public JWTExpiredException(final String message, final long expiration) { + super(message); + this.expiration = expiration; + } + + public long getExpiration() { + return expiration; + }; +} diff --git a/src/main/java/com/auth0/jwt/JWTIssuerException.java b/src/main/java/com/auth0/jwt/JWTIssuerException.java new file mode 100644 index 0000000..13463dd --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTIssuerException.java @@ -0,0 +1,22 @@ +package com.auth0.jwt; + +/** + * Represents Exception related to Issuer - for example issuer mismatch / missing upon verification + */ +public class JWTIssuerException extends JWTVerifyException { + + private final String issuer; + + public JWTIssuerException(final String issuer) { + this.issuer = issuer; + } + + public JWTIssuerException(final String message, final String issuer) { + super(message); + this.issuer = issuer; + } + + public String getIssuer() { + return issuer; + } +} diff --git a/src/main/java/com/auth0/jwt/JWTSigner.java b/src/main/java/com/auth0/jwt/JWTSigner.java new file mode 100644 index 0000000..828128a --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTSigner.java @@ -0,0 +1,362 @@ +package com.auth0.jwt; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.*; +import java.util.*; + +/** + * Handles JWT Sign Operation + * + * Default algorithm when none provided is HMAC SHA-256 ("HS256") + * + * See associated library test cases for clear examples on usage + * + */ +public class JWTSigner { + + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + + private byte[] secret; + private PrivateKey privateKey; + + // Default algorithm HMAC SHA-256 ("HS256") + protected final static Algorithm DEFAULT_ALGORITHM = Algorithm.HS256; + + public JWTSigner(final String secret) { + this(secret.getBytes()); + } + + public JWTSigner(final byte[] secret) { + Validate.notNull(secret); + this.secret = secret; + } + + public JWTSigner(final PrivateKey privateKey) { + this.privateKey = privateKey; + } + + /** + * Generate a JSON Web Token. + * + * @param claims A map of the JWT claims that form the payload. Registered claims + * must be of appropriate Java datatype as following: + *
    + *
  • iss, sub: String + *
  • exp, nbf, iat, jti: numeric, eg. Long + *
  • aud: String, or Collection<String> + *
+ * All claims with a null value are left out the JWT. + * Any claims set automatically as specified in + * the "options" parameter override claims in this map. + * @param options Allow choosing the signing algorithm, and automatic setting of some registered claims. + */ + public String sign(final Map claims, final Options options) { + Validate.notNull(claims); + final Algorithm algorithm = (options != null && options.algorithm != null) ? options.algorithm : DEFAULT_ALGORITHM; + final List segments = new ArrayList<>(); + try { + segments.add(encodedHeader(algorithm)); + segments.add(encodedPayload(claims, options)); + segments.add(encodedSignature(join(segments, "."), algorithm)); + return join(segments, "."); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Generate a JSON Web Token using the default algorithm HMAC SHA-256 ("HS256") + * and no claims automatically set. + */ + public String sign(final Map claims) { + Validate.notNull(claims); + return sign(claims, null); + } + + /** + * Generate the header part of a JSON web token. + */ + private String encodedHeader(final Algorithm algorithm) throws UnsupportedEncodingException { + Validate.notNull(algorithm); + // create the header + final ObjectNode header = JsonNodeFactory.instance.objectNode(); + header.put("typ", "JWT"); + header.put("alg", algorithm.name()); + return base64UrlEncode(header.toString().getBytes("UTF-8")); + } + + /** + * Generate the JSON web token payload string from the claims. + * + * @param options + */ + private String encodedPayload(final Map _claims, final Options options) throws IOException { + final Map claims = new HashMap<>(_claims); + enforceStringOrURI(claims, "iss"); + enforceStringOrURI(claims, "sub"); + enforceStringOrURICollection(claims, "aud"); + enforceIntDate(claims, "exp"); + enforceIntDate(claims, "nbf"); + enforceIntDate(claims, "iat"); + enforceString(claims, "jti"); + if (options != null) { + processPayloadOptions(claims, options); + } + final String payload = new ObjectMapper().writeValueAsString(claims); + return base64UrlEncode(payload.getBytes("UTF-8")); + } + + private void processPayloadOptions(final Map claims, final Options options) { + Validate.notNull(claims); + Validate.notNull(options); + final long now = System.currentTimeMillis() / 1000l; + if (options.expirySeconds != null) + claims.put("exp", now + options.expirySeconds); + if (options.notValidBeforeLeeway != null) + claims.put("nbf", now - options.notValidBeforeLeeway); + if (options.isIssuedAt()) + claims.put("iat", now); + if (options.isJwtId()) + claims.put("jti", UUID.randomUUID().toString()); + } + + // consider cleanup + private void enforceIntDate(final Map claims, final String claimName) { + Validate.notNull(claims); + Validate.notNull(claimName); + final Object value = handleNullValue(claims, claimName); + if (value == null) + return; + if (!(value instanceof Number)) { + throw new IllegalStateException(String.format("Claim '%s' is invalid: must be an instance of Number", claimName)); + } + final long longValue = ((Number) value).longValue(); + if (longValue < 0) + throw new IllegalStateException(String.format("Claim '%s' is invalid: must be non-negative", claimName)); + claims.put(claimName, longValue); + } + + // consider cleanup + private void enforceStringOrURICollection(final Map claims, final String claimName) { + final Object values = handleNullValue(claims, claimName); + if (values == null) + return; + if (values instanceof Collection) { + @SuppressWarnings({"unchecked"}) + final Iterator iterator = ((Collection) values).iterator(); + while (iterator.hasNext()) { + Object value = iterator.next(); + String error = checkStringOrURI(value); + if (error != null) + throw new IllegalStateException(String.format("Claim 'aud' element is invalid: %s", error)); + } + } else { + enforceStringOrURI(claims, "aud"); + } + } + + // consider cleanup + private void enforceStringOrURI(final Map claims, final String claimName) { + final Object value = handleNullValue(claims, claimName); + if (value == null) + return; + final String error = checkStringOrURI(value); + if (error != null) + throw new IllegalStateException(String.format("Claim '%s' is invalid: %s", claimName, error)); + } + + // consider cleanup + private void enforceString(final Map claims, final String claimName) { + final Object value = handleNullValue(claims, claimName); + if (value == null) + return; + if (!(value instanceof String)) + throw new IllegalStateException(String.format("Claim '%s' is invalid: not a string", claimName)); + } + + // consider cleanup + private Object handleNullValue(final Map claims, final String claimName) { + if (!claims.containsKey(claimName)) + return null; + final Object value = claims.get(claimName); + if (value == null) { + claims.remove(claimName); + return null; + } + return value; + } + + // consider cleanup + private String checkStringOrURI(final Object value) { + if (!(value instanceof String)) + return "not a string"; + final String stringOrUri = (String) value; + if (!stringOrUri.contains(":")) + return null; + try { + new URI(stringOrUri); + } catch (URISyntaxException e) { + return "not a valid URI"; + } + return null; + } + + /** + * Sign the header and payload + */ + private String encodedSignature(final String signingInput, final Algorithm algorithm) throws NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, SignatureException, JWTAlgorithmException { + Validate.notNull(signingInput); + Validate.notNull(algorithm); + switch (algorithm) { + case HS256: + case HS384: + case HS512: + return base64UrlEncode(signHmac(algorithm, signingInput, secret)); + case RS256: + case RS384: + case RS512: + return base64UrlEncode(signRs(algorithm, signingInput, privateKey)); + default: + throw new JWTAlgorithmException("Unsupported signing method"); + } + } + + /** + * Safe URL encode a byte array to a String + */ + private String base64UrlEncode(final byte[] str) { + Validate.notNull(str); + return new String(Base64.encodeBase64URLSafe(str)); + } + + /** + * Sign an input string using HMAC and return the encrypted bytes + */ + private static byte[] signHmac(final Algorithm algorithm, final String msg, final byte[] secret) throws NoSuchAlgorithmException, InvalidKeyException { + Validate.notNull(algorithm); + Validate.notNull(msg); + Validate.notNull(secret); + final Mac mac = Mac.getInstance(algorithm.getValue()); + mac.init(new SecretKeySpec(secret, algorithm.getValue())); + return mac.doFinal(msg.getBytes()); + } + + /** + * Sign an input string using RSA and return the encrypted bytes + */ + private static byte[] signRs(final Algorithm algorithm, final String msg, final PrivateKey privateKey) throws NoSuchProviderException, + NoSuchAlgorithmException, InvalidKeyException, SignatureException { + Validate.notNull(algorithm); + Validate.notNull(msg); + Validate.notNull(privateKey); + final byte[] messageBytes = msg.getBytes(); + final Signature signature = Signature.getInstance(algorithm.getValue(), "BC"); + signature.initSign(privateKey); + signature.update(messageBytes); + return signature.sign(); + } + + private String join(final List input, final String separator) { + Validate.notNull(input); + Validate.notNull(separator); + return StringUtils.join(input.iterator(), separator); + } + + /** + * An option object for JWT signing operation. Allow choosing the algorithm, and/or specifying + * claims to be automatically set. + */ + public static class Options { + + private Algorithm algorithm; + private Integer expirySeconds; + private Integer notValidBeforeLeeway; + private boolean issuedAt; + private boolean jwtId; + + public Algorithm getAlgorithm() { + return algorithm; + } + + /** + * Algorithm to sign JWT with. + */ + public Options setAlgorithm(final Algorithm algorithm) { + this.algorithm = algorithm; + return this; + } + + + public Integer getExpirySeconds() { + return expirySeconds; + } + + /** + * Set JWT claim "exp" to current timestamp plus this value. + * Overrides content of claims in sign(). + */ + public Options setExpirySeconds(final Integer expirySeconds) { + this.expirySeconds = expirySeconds; + return this; + } + + public Integer getNotValidBeforeLeeway() { + return notValidBeforeLeeway; + } + + /** + * Set JWT claim "nbf" to current timestamp minus this value. + * Overrides content of claims in sign(). + */ + public Options setNotValidBeforeLeeway(final Integer notValidBeforeLeeway) { + this.notValidBeforeLeeway = notValidBeforeLeeway; + return this; + } + + public boolean isIssuedAt() { + return issuedAt; + } + + /** + * Set JWT claim "iat" to current timestamp. Defaults to false. + * Overrides content of claims in sign(). + */ + public Options setIssuedAt(final boolean issuedAt) { + this.issuedAt = issuedAt; + return this; + } + + public boolean isJwtId() { + return jwtId; + } + + /** + * Set JWT claim "jti" to a pseudo random unique value (type 4 UUID). Defaults to false. + * Overrides content of claims in sign(). + */ + public Options setJwtId(final boolean jwtId) { + this.jwtId = jwtId; + return this; + } + + } + +} diff --git a/src/main/java/com/auth0/jwt/JWTVerifier.java b/src/main/java/com/auth0/jwt/JWTVerifier.java new file mode 100644 index 0000000..0e0199f --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTVerifier.java @@ -0,0 +1,239 @@ +package com.auth0.jwt; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.Validate; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.*; +import java.util.Map; + +/** + * Handles JWT Verification Operations + * + * Validates claims and signature + * + * See associated library test cases for clear examples on usage + * + */ +public class JWTVerifier { + + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + + private byte[] secret; + private PublicKey publicKey; + private final String audience; + private final String issuer; + private final Base64 decoder = new Base64(true); + + private final ObjectMapper mapper; + + + public JWTVerifier(final String secret, final String audience, final String issuer) { + this(secret.getBytes(Charset.forName("UTF-8")), audience, issuer); + } + + public JWTVerifier(final String secret, final String audience) { + this(secret, audience, null); + } + + public JWTVerifier(final String secret) { + this(secret, null, null); + } + + public JWTVerifier(final byte[] secret, final String audience) { + this(secret, audience, null); + } + + public JWTVerifier(final byte[] secret) { + this(secret, null, null); + } + + public JWTVerifier(final byte[] secret, final String audience, final String issuer) { + if (secret == null || secret.length == 0) { + throw new IllegalArgumentException("Secret cannot be null or empty"); + } + mapper = new ObjectMapper(); + this.secret = secret; + this.audience = audience; + this.issuer = issuer; + } + + public JWTVerifier(final PublicKey publicKey, final String audience, final String issuer) { + Validate.notNull(publicKey); + mapper = new ObjectMapper(); + this.publicKey = publicKey; + this.audience = audience; + this.issuer = issuer; + } + + public JWTVerifier(final PublicKey publicKey, final String audience) { + this(publicKey, audience, null); + } + + public JWTVerifier(final PublicKey publicKey) { + this(publicKey, null, null); + } + + + /** + * Performs JWT validation + * + * @param token token to verify + * @throws SignatureException when signature is invalid + * @throws JWTVerifyException when expiration, issuer or audience are invalid + * @throws JWTAlgorithmException when the algorithm is missing or unsupported + * @throws IllegalStateException when token's structure is invalid or secret / public key does not match algorithm of token + */ + @SuppressWarnings("WeakerAccess") + public Map verify(final String token) throws NoSuchAlgorithmException, InvalidKeyException, IllegalStateException, + IOException, SignatureException, JWTVerifyException { + if (token == null || "".equals(token)) { + throw new IllegalStateException("token not set"); + } + final String[] pieces = token.split("\\."); + if (pieces.length != 3) { + throw new IllegalStateException("Wrong number of segments: " + pieces.length); + } + final JsonNode jwtHeader = decodeAndParse(pieces[0]); + final Algorithm algorithm = getAlgorithm(jwtHeader); + final JsonNode jwtPayload = decodeAndParse(pieces[1]); + verifySignature(pieces, algorithm); + verifyExpiration(jwtPayload); + verifyIssuer(jwtPayload); + verifyAudience(jwtPayload); + return mapper.treeToValue(jwtPayload, Map.class); + } + + void verifySignature(final String[] pieces, final Algorithm algorithm) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException, JWTAlgorithmException, IllegalStateException { + Validate.notNull(pieces); + Validate.notNull(algorithm); + if (pieces.length != 3) { + throw new IllegalStateException("Wrong number of segments: " + pieces.length); + } + switch (algorithm) { + case HS256: + case HS384: + case HS512: + verifyHmac(algorithm, pieces, secret); + return; + case RS256: + case RS384: + case RS512: + verifyRs(algorithm, pieces, publicKey); + return; + default: + throw new JWTAlgorithmException("Unsupported signing method"); + } + } + + private void verifyHmac(final Algorithm algorithm, final String[] pieces, final byte[] secret) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException { + if (secret == null || secret.length == 0) { + throw new IllegalStateException("Secret cannot be null or empty when using algorithm: " + algorithm.getValue()); + } + final Mac hmac = Mac.getInstance(algorithm.getValue()); + hmac.init(new SecretKeySpec(secret, algorithm.getValue())); + final byte[] sig = hmac.doFinal((pieces[0] + "." + pieces[1]).getBytes()); + if (!MessageDigest.isEqual(sig, decoder.decode(pieces[2]))) { + throw new SignatureException("signature verification failed"); + } + } + + private void verifyRs(final Algorithm algorithm, final String[] pieces, final PublicKey publicKey) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, JWTAlgorithmException { + if (publicKey == null) { + throw new IllegalStateException("PublicKey cannot be null when using algorithm: " + algorithm.getValue()); + } + final byte[] decodedSignatureBytes = new Base64(true).decode(pieces[2]); + final byte[] headerPayloadBytes = (pieces[0] + "." + pieces[1]).getBytes(); + final boolean verified = verifySignatureWithPublicKey(this.publicKey, headerPayloadBytes, decodedSignatureBytes, algorithm); + if (!verified) { + throw new SignatureException("signature verification failed"); + } + } + + private boolean verifySignatureWithPublicKey(final PublicKey publicKey, final byte[] messageBytes, final byte[] signatureBytes, final Algorithm algorithm) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, JWTAlgorithmException { + Validate.notNull(publicKey); + Validate.notNull(messageBytes); + Validate.notNull(signatureBytes); + Validate.notNull(algorithm); + try { + final Signature signature = Signature.getInstance(algorithm.getValue(), "BC"); + signature.initVerify(publicKey); + signature.update(messageBytes); + return signature.verify(signatureBytes); + } catch (NoSuchProviderException e) { + throw new JWTAlgorithmException(e.getMessage(), e.getCause()); + } + } + + void verifyExpiration(final JsonNode jwtClaims) throws JWTExpiredException { + Validate.notNull(jwtClaims); + final long expiration = jwtClaims.has("exp") ? jwtClaims.get("exp").asLong(0) : 0; + if (expiration != 0 && System.currentTimeMillis() / 1000L >= expiration) { + throw new JWTExpiredException("jwt expired", expiration); + } + } + + void verifyIssuer(final JsonNode jwtClaims) throws JWTIssuerException { + Validate.notNull(jwtClaims); + + if (this.issuer == null ) { + return; + } + + final String issuerFromToken = jwtClaims.has("iss") ? jwtClaims.get("iss").asText() : null; + + if (issuerFromToken == null || !issuer.equals(issuerFromToken)) { + throw new JWTIssuerException("jwt issuer invalid", issuerFromToken); + } + } + + void verifyAudience(final JsonNode jwtClaims) throws JWTAudienceException { + Validate.notNull(jwtClaims); + if (audience == null) { + return; + } + final JsonNode audNode = jwtClaims.get("aud"); + if (audNode == null) { + throw new JWTAudienceException("jwt audience invalid", null); + } + if (audNode.isArray()) { + for (final JsonNode jsonNode : audNode) { + if (audience.equals(jsonNode.textValue())) { + return; + } + } + } else if (audNode.isTextual()) { + if (audience.equals(audNode.textValue())) { + return; + } + } + throw new JWTAudienceException("jwt audience invalid", audNode); + } + + Algorithm getAlgorithm(final JsonNode jwtHeader) throws JWTAlgorithmException { + Validate.notNull(jwtHeader); + final String algorithmName = jwtHeader.has("alg") ? jwtHeader.get("alg").asText() : null; + if (jwtHeader.get("alg") == null) { + throw new IllegalStateException("algorithm not set"); + } + return Algorithm.findByName(algorithmName); + } + + JsonNode decodeAndParse(final String b64String) throws IOException { + Validate.notNull(b64String); + final String jsonString = new String(decoder.decode(b64String), "UTF-8"); + return mapper.readValue(jsonString, JsonNode.class); + } + +} diff --git a/src/main/java/com/auth0/jwt/JWTVerifyException.java b/src/main/java/com/auth0/jwt/JWTVerifyException.java new file mode 100644 index 0000000..9e18d6b --- /dev/null +++ b/src/main/java/com/auth0/jwt/JWTVerifyException.java @@ -0,0 +1,18 @@ +package com.auth0.jwt; + +/** + * Represents General Exception related to Verification + */ +public class JWTVerifyException extends Exception { + + public JWTVerifyException() {} + + public JWTVerifyException(final String message, final Throwable cause) { + super(message, cause); + } + + public JWTVerifyException(final String message) { + super(message); + } + +} diff --git a/src/main/java/com/auth0/jwt/pem/PemFileReader.java b/src/main/java/com/auth0/jwt/pem/PemFileReader.java new file mode 100644 index 0000000..60eb9f3 --- /dev/null +++ b/src/main/java/com/auth0/jwt/pem/PemFileReader.java @@ -0,0 +1,38 @@ +package com.auth0.jwt.pem; + +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemReader; +import org.bouncycastle.util.io.pem.PemWriter; + +import java.io.*; + +/** + * Can read PEM from disk - depends on BouncyCastle PemReader + */ +class PemFileReader { + + private PemObject pemObject; + + public PemFileReader(final String filename) throws IOException { + final PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream(filename))); + try { + this.pemObject = pemReader.readPemObject(); + } finally { + pemReader.close(); + } + } + + public void write(final String filename) throws IOException { + final PemWriter pemWriter = new PemWriter(new OutputStreamWriter(new FileOutputStream(filename))); + try { + pemWriter.writeObject(this.pemObject); + } finally { + pemWriter.close(); + } + } + + public PemObject getPemObject() { + return pemObject; + } + +} diff --git a/src/main/java/com/auth0/jwt/pem/PemFileWriter.java b/src/main/java/com/auth0/jwt/pem/PemFileWriter.java new file mode 100644 index 0000000..8b23df1 --- /dev/null +++ b/src/main/java/com/auth0/jwt/pem/PemFileWriter.java @@ -0,0 +1,31 @@ +package com.auth0.jwt.pem; + +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.security.Key; + +/** + * Can write PEM to disk - depends on BouncyCastle PemWriter + */ +class PemFileWriter { + + private PemObject pemObject; + + public PemFileWriter(final Key key, final String description) { + this.pemObject = new PemObject(description, key.getEncoded()); + } + + public void write(final String filename) throws IOException { + final PemWriter pemWriter = new PemWriter(new OutputStreamWriter(new FileOutputStream(filename))); + try { + pemWriter.writeObject(this.pemObject); + } finally { + pemWriter.close(); + } + } + +} diff --git a/src/main/java/com/auth0/jwt/pem/PemReader.java b/src/main/java/com/auth0/jwt/pem/PemReader.java new file mode 100644 index 0000000..90ca048 --- /dev/null +++ b/src/main/java/com/auth0/jwt/pem/PemReader.java @@ -0,0 +1,68 @@ +package com.auth0.jwt.pem; + +import org.apache.commons.lang3.Validate; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.security.*; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * Read operations for PEM files + */ +public class PemReader { + + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + + public static PrivateKey readPrivateKey(final String filePath) throws NoSuchProviderException, NoSuchAlgorithmException, IOException, InvalidKeySpecException { + Validate.notNull(filePath); + final KeyFactory factory = KeyFactory.getInstance("RSA", "BC"); + final PrivateKey privateKey = readPrivateKeyFromFile(factory, filePath); + return privateKey; + } + + public static PublicKey readPublicKey(final String filePath) throws NoSuchProviderException, NoSuchAlgorithmException, IOException, InvalidKeySpecException { + Validate.notNull(filePath); + final KeyFactory factory = KeyFactory.getInstance("RSA", "BC"); + final PublicKey publicKey = readPublicKeyFromFile(factory, filePath); + return publicKey; + } + + private static PrivateKey readPrivateKeyFromFile(final KeyFactory factory, final String filename) throws InvalidKeySpecException, IOException { + Validate.notNull(factory); + Validate.notNull(filename); + final PemFileReader pemFileReader = new PemFileReader(filename); + final byte[] content = pemFileReader.getPemObject().getContent(); + final PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content); + return factory.generatePrivate(privKeySpec); + } + + private static PublicKey readPublicKeyFromFile(final KeyFactory factory, final String filename) throws InvalidKeySpecException, IOException { + Validate.notNull(factory); + Validate.notNull(filename); + final File file = new File(filename); + final byte[] data = Files.readAllBytes(file.toPath()); + final X509Certificate cert = X509CertUtils.parse(new String(data)); + if (cert != null) { + java.security.PublicKey publicKey = cert.getPublicKey(); + return publicKey; + } else { + final PemFileReader pemFileReader = new PemFileReader(filename); + final byte[] content = pemFileReader.getPemObject().getContent(); + final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content); + return factory.generatePublic(pubKeySpec); + } + + + } + +} diff --git a/src/main/java/com/auth0/jwt/pem/PemWriter.java b/src/main/java/com/auth0/jwt/pem/PemWriter.java new file mode 100644 index 0000000..55856ce --- /dev/null +++ b/src/main/java/com/auth0/jwt/pem/PemWriter.java @@ -0,0 +1,34 @@ +package com.auth0.jwt.pem; + +import org.apache.commons.lang3.Validate; + +import java.io.IOException; +import java.security.Key; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +/** + * Write operations for PEM files + */ +public class PemWriter { + + public static void writePrivateKey(final RSAPrivateKey privateKey, final String description, final String filename) throws IOException { + Validate.notNull(privateKey); + Validate.notNull(filename); + writePemFile(privateKey, description, filename); + } + + public static void writePublicKey(final RSAPublicKey publicKey, final String description, final String filename) throws IOException { + Validate.notNull(publicKey); + Validate.notNull(filename); + writePemFile(publicKey, description, filename); + } + + public static void writePemFile(final Key key, final String description, final String filename) throws IOException { + Validate.notNull(key); + Validate.notNull(filename); + final PemFileWriter pemFileWriter = new PemFileWriter(key, description); + pemFileWriter.write(filename); + } + +} diff --git a/src/main/java/com/auth0/jwt/pem/X509CertUtils.java b/src/main/java/com/auth0/jwt/pem/X509CertUtils.java new file mode 100644 index 0000000..ef65e47 --- /dev/null +++ b/src/main/java/com/auth0/jwt/pem/X509CertUtils.java @@ -0,0 +1,61 @@ +package com.auth0.jwt.pem; + +import org.apache.commons.codec.binary.Base64; + +import java.io.ByteArrayInputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + + +/** + * X.509 certificate utilities. + */ +public class X509CertUtils { + + private static final String PEM_BEGIN_MARKER = "-----BEGIN CERTIFICATE-----"; + private static final String PEM_END_MARKER = "-----END CERTIFICATE-----"; + + /** + * Parses a DER-encoded X.509 certificate. + */ + public static X509Certificate parse(final byte[] derEncodedCert) { + if (derEncodedCert == null || derEncodedCert.length == 0) { + return null; + } + try { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + final Certificate cert = cf.generateCertificate(new ByteArrayInputStream(derEncodedCert)); + if (!(cert instanceof X509Certificate)) { + return null; + } + return (X509Certificate) cert; + } catch (CertificateException e) { + return null; + } + } + + /** + * Parses a PEM-encoded X.509 certificate. + */ + public static X509Certificate parse(final String pemEncodedCert) { + if (pemEncodedCert == null || pemEncodedCert.isEmpty()) { + return null; + } + final int markerStart = pemEncodedCert.indexOf(PEM_BEGIN_MARKER); + if (markerStart < 0) { + return null; + } + String buf = pemEncodedCert.substring(markerStart + PEM_BEGIN_MARKER.length()); + final int markerEnd = buf.indexOf(PEM_END_MARKER); + if (markerEnd < 0) { + return null; + } + buf = buf.substring(0, markerEnd); + buf = buf.replaceAll("\\s", ""); + return parse(new Base64(true).decodeBase64(buf)); + } + +} + diff --git a/src/test/java/com/auth0/jwt/JWTRoundTripRsa256Test.java b/src/test/java/com/auth0/jwt/JWTRoundTripRsa256Test.java new file mode 100644 index 0000000..722de2a --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTRoundTripRsa256Test.java @@ -0,0 +1,100 @@ +package com.auth0.jwt; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.util.*; + +import static com.auth0.jwt.pem.PemReader.readPrivateKey; +import static com.auth0.jwt.pem.PemReader.readPublicKey; +import static com.auth0.jwt.pem.PemWriter.writePrivateKey; +import static com.auth0.jwt.pem.PemWriter.writePublicKey; +import static junit.framework.TestCase.*; + +/** + * Test that generates KeyPair - writes PEM files (private and public) to disk, + * then reads in those PEM files (private and public) and uses them to Sign a JWT + * and subsequently verify its correctness - hence "RoundTrip" + */ +public class JWTRoundTripRsa256Test { + + private static final int KEY_SIZE = 2048; + + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + + private File privateKeyPem; + private File publicKeyPem; + + @Before + public void createPemFiles() throws NoSuchAlgorithmException, NoSuchProviderException, IOException { + // create key pair + final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC"); + generator.initialize(KEY_SIZE); + final KeyPair keyPair = generator.generateKeyPair(); + // write private key + final RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + privateKeyPem = File.createTempFile("id_rsa", ""); + writePrivateKey(privateKey, "RSA PRIVATE KEY", privateKeyPem.getAbsolutePath()); + // write public key + publicKeyPem = File.createTempFile("id_rsa", ".pub"); + final RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + writePublicKey(publicKey, "RSA PUBLIC KEY", publicKeyPem.getAbsolutePath()); + } + + @Test + public void roundTripCreatingSignedTokenAndVerifyingUsingRs256Algo() throws NoSuchProviderException, NoSuchAlgorithmException, IOException, InvalidKeySpecException, SignatureException, InvalidKeyException, JWTAlgorithmException, JWTVerifyException { + // read pem files + final PrivateKey privateKey = readPrivateKey(privateKeyPem.getAbsolutePath()); + assertNotNull(privateKey); + final PublicKey publicKey = readPublicKey(publicKeyPem.getAbsolutePath()); + assertNotNull(publicKey); + // create and sign a JWT + final String issuer = "https://arcseldon.auth0.com/"; + final String clientId = "xGXMKfEdcOcacZEU7Uq1mgWOtpUxBlL4"; // this is the audience + final String name = "arcseldon"; + final String email = "arcseldon+test@gmail.com"; + final String subject = "auth0|576be978a93121cc48c7487d"; + final List roles = new ArrayList<>(); + roles.add("ROLE_ADMIN"); + final long iat = System.currentTimeMillis() / 1000l; + final long exp = iat + 3600L; + final HashMap claims = new HashMap<>(); + claims.put("name", name); + claims.put("email", email); + claims.put("email_verified", "true"); + claims.put("iss", issuer); + claims.put("roles", roles.toArray(new String[0])); + claims.put("sub", subject); + claims.put("aud", clientId); + claims.put("exp", exp); + claims.put("iat", iat); + final JWTSigner jwtSigner = new JWTSigner(privateKey); + final JWTSigner.Options options = new JWTSigner.Options(); + options.setAlgorithm(Algorithm.RS256); + final String token = jwtSigner.sign(claims, options); + assertNotNull(token); + final JWTVerifier jwtVerifier = new JWTVerifier(publicKey); + final Map verifiedClaims = jwtVerifier.verify(token); + assertEquals(name, verifiedClaims.get("name")); + assertEquals(email, verifiedClaims.get("email")); + assertEquals("true", verifiedClaims.get("email_verified")); + assertTrue(roles.equals((List) verifiedClaims.get("roles"))); + assertEquals(issuer, verifiedClaims.get("iss")); + assertEquals(subject, verifiedClaims.get("sub")); + assertEquals(clientId, verifiedClaims.get("aud")); + assertTrue(exp == (Integer) verifiedClaims.get("exp")); + assertTrue(iat == (Integer) verifiedClaims.get("iat")); + } + +} diff --git a/src/test/java/com/auth0/jwt/JWTRoundTripTest.java b/src/test/java/com/auth0/jwt/JWTRoundTripTest.java new file mode 100644 index 0000000..3fca12a --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTRoundTripTest.java @@ -0,0 +1,162 @@ +package com.auth0.jwt; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Test things that are difficult using signer or verifier alone. In particular, setting + * claims via Options produces output dependent on current time. + * + */ +public class JWTRoundTripTest { + private static final String SECRET; + static { + SECRET = "my secret"; + } + private static JWTSigner signer = new JWTSigner(SECRET); + private static JWTVerifier verifier = new JWTVerifier(SECRET); + + /* + * Roundtrip of different datatypes. + */ + @Test + public void shouldEmpty() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + assertEquals(claims, decoded); + } + + @Test + public void shouldString() throws Exception { + HashMap claims = new HashMap(); + claims.put("foo", "bar"); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + assertEquals(claims, decoded); + } + + @Test + public void shouldShort() throws Exception { + HashMap claims = new HashMap(); + claims.put("foo", (short) -10); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + Number fooValue = (Number) decoded.get("foo"); + decoded.put("foo", fooValue.shortValue()); + assertEquals(claims, decoded); + } + + @Test + public void shouldLong() throws Exception { + HashMap claims = new HashMap(); + claims.put("foo", Long.MAX_VALUE); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + assertEquals(claims, decoded); + } + + @Test + public void shouldObject() throws Exception { + HashMap claims = new HashMap(); + User user = new User(); + user.setUsername("foo"); + user.setPassword("bar"); + claims.put("user", user); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + HashMap expectedUser = new HashMap(); + expectedUser.put("username", "foo"); + expectedUser.put("password", "bar"); + HashMap expected = new HashMap(); + expected.put("user", expectedUser); + assertEquals(expected, decoded); + } + + @Test + public void shouldBoolean() throws Exception { + HashMap claims = new HashMap(); + claims.put("foo", true); + claims.put("bar", false); + String token = signer.sign(claims); + Map decoded = verifier.verify(token); + assertEquals(claims, decoded); + } + + /* + * Setting claims via Options + */ + + @Test + public void shouldOptionsIat() throws Exception { + HashMap claims = new HashMap(); + long before = System.currentTimeMillis(); + String token = signer.sign(claims, new JWTSigner.Options().setIssuedAt(true)); + long after = System.currentTimeMillis(); + Map decoded = verifier.verify(token); + + assertEquals(decoded.size(), 1); + long iat = ((Number) decoded.get("iat")).longValue(); + assertTrue(iat >= before / 1000l); + assertTrue(iat <= after / 1000l); + } + + @Test + public void shouldOptionsTimestamps() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, + new JWTSigner.Options() + .setExpirySeconds(50).setNotValidBeforeLeeway(10).setIssuedAt(true)); + Map decoded = verifier.verify(token); + assertEquals(decoded.size(), 3); + long iat = ((Number) decoded.get("iat")).longValue(); + long exp = ((Number) decoded.get("exp")).longValue(); + long nbf = ((Number) decoded.get("nbf")).longValue(); + assertEquals(exp, iat + 50); + assertEquals(nbf, iat - 10); + } + + @Test + public void shouldOptionsJti() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, + new JWTSigner.Options().setJwtId(true)); + Map decoded = verifier.verify(token); + assertEquals(decoded.size(), 1); + assertEquals(((String) decoded.get("jti")).length(), 36); + } + + + public static class User { + + private String username; + private String password; + + public User() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + } +} + + + diff --git a/src/test/java/com/auth0/jwt/JWTSignerBytesTest.java b/src/test/java/com/auth0/jwt/JWTSignerBytesTest.java new file mode 100644 index 0000000..2d5d06a --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTSignerBytesTest.java @@ -0,0 +1,205 @@ +package com.auth0.jwt; + +import com.auth0.jwt.Algorithm; +import com.auth0.jwt.JWTSigner; +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; + +import static org.junit.Assert.assertEquals; + +/** + * General library JwtSigner unit tests using byte constructor alternative for secret + */ +public class JWTSignerBytesTest { + private static JWTSigner signer = new JWTSigner(new byte[] { 109, 121, 32, 115, 101, 99, 114, 101, 116}); + + @Test + public void shouldSignEmpty() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignEmptyTwoParams() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmb28ifQ.UbvkKJx4ubG9SQYs3Hpe6FJl1ix89jSLw0I9GNTnLgY", token); + } + + @Test + public void shouldSignStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", "http://foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJodHRwOi8vZm9vIn0.EaYoTXJWUNd_1tWfZo4EZoKUP8hVMJm1LHBQNo4Xfwg", token); + } + + @Test + public void shouldSignStringOrURI3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", ""); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIifQ.T2EKheH_WVVwybctic8Sqk89miYVKADW0AeXOicDbz8", token); + } + + @Test + public void shouldSignStringOrURICollection() throws Exception { + HashMap claims = new HashMap(); + LinkedList aud = new LinkedList(); + aud.add("xyz"); + aud.add("ftp://foo"); + claims.put("aud", aud); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsieHl6IiwiZnRwOi8vZm9vIl19.WGpsdOnLJ2k7Rr4WeEuabHO4wNQIhJfPMZot1DrTUgA", token); + } + + @Test + public void shouldSignIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", 123); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEyM30.FzAXEHf0LVQPOyRQFftA1VBAj8RmZGEfwQIPSfg_DUg", token); + } + + @Test + public void bytes_shouldSignIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", 123); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEyM30.FzAXEHf0LVQPOyRQFftA1VBAj8RmZGEfwQIPSfg_DUg", token); + } + + @Test + public void shouldSignIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", 0); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjB9.ChHEHjtyr4qOUMu6KDsa2BjGXtkGurboD5ljr99gVzw", token); + } + + @Test + public void shouldSignIntDate3() throws Exception { + HashMap claims = new HashMap(); + claims.put("iat", Long.MAX_VALUE); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjkyMjMzNzIwMzY4NTQ3NzU4MDd9.7yrsheXoAuqk5hDcbKmT3l6aDNNr7RMnbVe6kVkvv4M", token); + } + + @Test + public void bytes_shouldSignIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", 0); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjB9.ChHEHjtyr4qOUMu6KDsa2BjGXtkGurboD5ljr99gVzw", token); + } + + @Test + public void shouldSignString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJmb28ifQ.CriA-W8LKO4bCxy3e2Nu7kx2MxgcHGyFu_GVLMX3bko", token); + } + + @Test + public void shouldSignNullEqualsMissing() throws Exception { + HashMap claims = new HashMap(); + for (String claimName : Arrays.asList("iss", "sub", "aud", "exp", "nbf", "iat", "jti")) { + claims.put(claimName, null); + } + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", ":"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection1() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection2() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(0)); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(":")); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", -1); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", "100"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", 100); + signer.sign(claims); + } + + @Test + public void shouldOptionsNone() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, new JWTSigner.Options()); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldOptionsAll() throws Exception { + HashMap claims = new HashMap(); + signer.sign(claims, new JWTSigner.Options() + .setExpirySeconds(1000).setNotValidBeforeLeeway(5) + .setIssuedAt(true).setJwtId(true)); + } + + @Test + public void shouldOptionsAlgorithm() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, + new JWTSigner.Options().setAlgorithm(Algorithm.HS512)); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.e30.11MgCe-_uiheyy_kARCwhSZbeq3IkMn40GLQkczQ4Bjn_lkCYfSeqz0HeeYpitksiQ2bW47N0oGKCOYOlmQPyg", token); + } + +} diff --git a/src/test/java/com/auth0/jwt/JWTSignerTest.java b/src/test/java/com/auth0/jwt/JWTSignerTest.java new file mode 100644 index 0000000..099e5c1 --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTSignerTest.java @@ -0,0 +1,188 @@ +package com.auth0.jwt; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; + +import static org.junit.Assert.assertEquals; + + +/** + * General library JwtSigner related unit tests + */ +public class JWTSignerTest { + private static JWTSigner signer = new JWTSigner("my secret"); + + @Test + public void shouldSignEmpty() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignEmptyTwoParams() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmb28ifQ.UbvkKJx4ubG9SQYs3Hpe6FJl1ix89jSLw0I9GNTnLgY", token); + } + + @Test + public void shouldSignStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", "http://foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJodHRwOi8vZm9vIn0.EaYoTXJWUNd_1tWfZo4EZoKUP8hVMJm1LHBQNo4Xfwg", token); + } + + @Test + public void shouldSignStringOrURI3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", ""); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIifQ.T2EKheH_WVVwybctic8Sqk89miYVKADW0AeXOicDbz8", token); + } + + @Test + public void shouldSignStringOrURICollection() throws Exception { + HashMap claims = new HashMap(); + LinkedList aud = new LinkedList(); + aud.add("xyz"); + aud.add("ftp://foo"); + claims.put("aud", aud); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsieHl6IiwiZnRwOi8vZm9vIl19.WGpsdOnLJ2k7Rr4WeEuabHO4wNQIhJfPMZot1DrTUgA", token); + } + + @Test + public void shouldSignIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", 123); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEyM30.FzAXEHf0LVQPOyRQFftA1VBAj8RmZGEfwQIPSfg_DUg", token); + } + + @Test + public void shouldSignIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", 0); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjB9.ChHEHjtyr4qOUMu6KDsa2BjGXtkGurboD5ljr99gVzw", token); + } + + @Test + public void shouldSignIntDate3() throws Exception { + HashMap claims = new HashMap(); + claims.put("iat", Long.MAX_VALUE); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjkyMjMzNzIwMzY4NTQ3NzU4MDd9.7yrsheXoAuqk5hDcbKmT3l6aDNNr7RMnbVe6kVkvv4M", token); + } + + @Test + public void shouldSignString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJmb28ifQ.CriA-W8LKO4bCxy3e2Nu7kx2MxgcHGyFu_GVLMX3bko", token); + } + + @Test + public void shouldSignNullEqualsMissing() throws Exception { + HashMap claims = new HashMap(); + for (String claimName : Arrays.asList("iss", "sub", "aud", "exp", "nbf", "iat", "jti")) { + claims.put(claimName, null); + } + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", ":"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection1() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection2() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(0)); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(":")); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", -1); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", "100"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", 100); + signer.sign(claims); + } + + @Test + public void shouldOptionsNone() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, new JWTSigner.Options()); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldOptionsAll() throws Exception { + HashMap claims = new HashMap(); + signer.sign(claims, new JWTSigner.Options() + .setExpirySeconds(1000).setNotValidBeforeLeeway(5) + .setIssuedAt(true).setJwtId(true)); + } + + @Test + public void shouldOptionsAlgorithm() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, + new JWTSigner.Options().setAlgorithm(Algorithm.HS512)); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.e30.11MgCe-_uiheyy_kARCwhSZbeq3IkMn40GLQkczQ4Bjn_lkCYfSeqz0HeeYpitksiQ2bW47N0oGKCOYOlmQPyg", token); + } + +} diff --git a/src/test/java/com/auth0/jwt/JWTSignerTest_Bytes.java b/src/test/java/com/auth0/jwt/JWTSignerTest_Bytes.java new file mode 100644 index 0000000..93cffda --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTSignerTest_Bytes.java @@ -0,0 +1,200 @@ +package com.auth0.jwt; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; + +import static org.junit.Assert.assertEquals; + +public class JWTSignerTest_Bytes { + private static JWTSigner signer = new JWTSigner(new byte[] { 109, 121, 32, 115, 101, 99, 114, 101, 116}); + + @Test + public void shouldSignEmpty() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignEmptyTwoParams() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldSignStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmb28ifQ.UbvkKJx4ubG9SQYs3Hpe6FJl1ix89jSLw0I9GNTnLgY", token); + } + + @Test + public void shouldSignStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", "http://foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJodHRwOi8vZm9vIn0.EaYoTXJWUNd_1tWfZo4EZoKUP8hVMJm1LHBQNo4Xfwg", token); + } + + @Test + public void shouldSignStringOrURI3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", ""); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIifQ.T2EKheH_WVVwybctic8Sqk89miYVKADW0AeXOicDbz8", token); + } + + @Test + public void shouldSignStringOrURICollection() throws Exception { + HashMap claims = new HashMap(); + LinkedList aud = new LinkedList(); + aud.add("xyz"); + aud.add("ftp://foo"); + claims.put("aud", aud); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsieHl6IiwiZnRwOi8vZm9vIl19.WGpsdOnLJ2k7Rr4WeEuabHO4wNQIhJfPMZot1DrTUgA", token); + } + + @Test + public void shouldSignIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", 123); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEyM30.FzAXEHf0LVQPOyRQFftA1VBAj8RmZGEfwQIPSfg_DUg", token); + } + + @Test + public void bytes_shouldSignIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", 123); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEyM30.FzAXEHf0LVQPOyRQFftA1VBAj8RmZGEfwQIPSfg_DUg", token); + } + + @Test + public void shouldSignIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", 0); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjB9.ChHEHjtyr4qOUMu6KDsa2BjGXtkGurboD5ljr99gVzw", token); + } + + @Test + public void shouldSignIntDate3() throws Exception { + HashMap claims = new HashMap(); + claims.put("iat", Long.MAX_VALUE); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjkyMjMzNzIwMzY4NTQ3NzU4MDd9.7yrsheXoAuqk5hDcbKmT3l6aDNNr7RMnbVe6kVkvv4M", token); + } + + @Test + public void bytes_shouldSignIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", 0); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjB9.ChHEHjtyr4qOUMu6KDsa2BjGXtkGurboD5ljr99gVzw", token); + } + + @Test + public void shouldSignString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", "foo"); + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJmb28ifQ.CriA-W8LKO4bCxy3e2Nu7kx2MxgcHGyFu_GVLMX3bko", token); + } + + @Test + public void shouldSignNullEqualsMissing() throws Exception { + HashMap claims = new HashMap(); + for (String claimName : Arrays.asList("iss", "sub", "aud", "exp", "nbf", "iat", "jti")) { + claims.put(claimName, null); + } + String token = signer.sign(claims); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI1() throws Exception { + HashMap claims = new HashMap(); + claims.put("iss", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURI2() throws Exception { + HashMap claims = new HashMap(); + claims.put("sub", ":"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection1() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", 0); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection2() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(0)); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectStringOrURICollection3() throws Exception { + HashMap claims = new HashMap(); + claims.put("aud", Arrays.asList(":")); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate1() throws Exception { + HashMap claims = new HashMap(); + claims.put("exp", -1); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectIntDate2() throws Exception { + HashMap claims = new HashMap(); + claims.put("nbf", "100"); + signer.sign(claims); + } + + @Test(expected = Exception.class) + public void shouldFailExpectString() throws Exception { + HashMap claims = new HashMap(); + claims.put("jti", 100); + signer.sign(claims); + } + + @Test + public void shouldOptionsNone() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, new JWTSigner.Options()); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.86pkOAQxvnSDd91EThNNpOTbO-hbvxdssnFjQqT04NU", token); + } + + @Test + public void shouldOptionsAll() throws Exception { + HashMap claims = new HashMap(); + signer.sign(claims, new JWTSigner.Options() + .setExpirySeconds(1000).setNotValidBeforeLeeway(5) + .setIssuedAt(true).setJwtId(true)); + } + + @Test + public void shouldOptionsAlgorithm() throws Exception { + HashMap claims = new HashMap(); + String token = signer.sign(claims, + new JWTSigner.Options().setAlgorithm(Algorithm.HS512)); + assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.e30.11MgCe-_uiheyy_kARCwhSZbeq3IkMn40GLQkczQ4Bjn_lkCYfSeqz0HeeYpitksiQ2bW47N0oGKCOYOlmQPyg", token); + } + +} diff --git a/src/test/java/com/auth0/jwt/JWTVerifierRsa256Test.java b/src/test/java/com/auth0/jwt/JWTVerifierRsa256Test.java new file mode 100644 index 0000000..485954c --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTVerifierRsa256Test.java @@ -0,0 +1,106 @@ +package com.auth0.jwt; + +import com.auth0.jwt.pem.X509CertUtils; +import org.apache.commons.codec.binary.Base64; +import org.junit.Test; + +import java.io.File; +import java.nio.file.Files; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; + +import static com.auth0.jwt.pem.PemReader.readPublicKey; +import static junit.framework.TestCase.assertNotNull; + +/** + * RS256 Verification Checks + */ +public class JWTVerifierRsa256Test { + + private final static String RESOURCES_DIR = "src/test/resources/auth0-pem/"; + private final static String MISMATCHED_RESOURCES_DIR = "src/test/resources/test-pem/"; + private final static String PUBLIC_KEY_PEM_FILENAME = "key.pem"; + private final static String MISMATCHED_PUBLIC_KEY_PEM_FILENAME = "test-auth0.pem"; + + + + /** + * Here we pass in a public key that does not correspond to the private key that was used to sign the JWT Token + */ + @Test(expected = SignatureException.class) + public void shouldFailOnInvalidSignature() throws Exception { + final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFVTkVRelZCTXpoRk1FVTNRMFZGTURJNFFqYzROakJDTkRSQ1JFRkNSalkzUWpnMFJEVXlOZyJ9" + + "." + + "eyJyb2xlcyI6WyJST0xFX0FETUlOIl0sInVzZXJfaWQiOiJhdXRoMHw1NzcxMGU5ZDE0MWIwN2YyMmU3NDNhYzciLCJlbWFpbCI6ImFyY3NlbGRvbit0cm5AZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYWppbG9uMS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTc3MTBlOWQxNDFiMDdmMjJlNzQzYWM3IiwiYXVkIjoibm5ld1NobHBHVDFBbkZpY1ExUGlKWXdheENuejE4eUIiLCJleHAiOjE0Njc3MDk5OTMsImlhdCI6MTQ2NzY3Mzk5M30" + + "." + + "gQML78V8H6WN3MSN1QhrFG4AxNTdFChPBQxrnuqPF0iBvf35v_z9oDzTERaPBDWFHzWT17h0ADxpl7tCIo43k0FoFie6RHa5j82iHnOKPhcqM5hArfKDYk3G5gc30lVmFiMm8PX8WKzDExygLqXZVnIzfB-EmcJWW_2fLiFEMpNC8KDTBVAiyds_n5kiGmW6F_QpLt11af3BDy71tg2fuqkyJE6pEHd1HsTHNCFQzWt7GevVB0HouJS099p6GphsH3kIhmAvHp5j267uYv49sndiUaLq7bL6GZnzv8dhzgQlucHvNaIZ6m6m6n4t43cjUxSrO0ZP9Crv9NBDJme0cA"; + final PublicKey publicKey = readPublicKey(MISMATCHED_RESOURCES_DIR + MISMATCHED_PUBLIC_KEY_PEM_FILENAME); + assertNotNull(publicKey); + new JWTVerifier(publicKey, "audience").verifySignature(token.split("\\."), Algorithm.RS256); + } + + /** + * Here we pass in a public key that correctly corresponds to the private key that was used to sign the JWT Token + */ + @Test + public void shouldVerifySignature() throws Exception { + final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFVTkVRelZCTXpoRk1FVTNRMFZGTURJNFFqYzROakJDTkRSQ1JFRkNSalkzUWpnMFJEVXlOZyJ9" + + "." + + "eyJyb2xlcyI6WyJST0xFX0FETUlOIl0sInVzZXJfaWQiOiJhdXRoMHw1NzcxMGU5ZDE0MWIwN2YyMmU3NDNhYzciLCJlbWFpbCI6ImFyY3NlbGRvbit0cm5AZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYWppbG9uMS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTc3MTBlOWQxNDFiMDdmMjJlNzQzYWM3IiwiYXVkIjoibm5ld1NobHBHVDFBbkZpY1ExUGlKWXdheENuejE4eUIiLCJleHAiOjE0Njc3MDk5OTMsImlhdCI6MTQ2NzY3Mzk5M30" + + "." + + "gQML78V8H6WN3MSN1QhrFG4AxNTdFChPBQxrnuqPF0iBvf35v_z9oDzTERaPBDWFHzWT17h0ADxpl7tCIo43k0FoFie6RHa5j82iHnOKPhcqM5hArfKDYk3G5gc30lVmFiMm8PX8WKzDExygLqXZVnIzfB-EmcJWW_2fLiFEMpNC8KDTBVAiyds_n5kiGmW6F_QpLt11af3BDy71tg2fuqkyJE6pEHd1HsTHNCFQzWt7GevVB0HouJS099p6GphsH3kIhmAvHp5j267uYv49sndiUaLq7bL6GZnzv8dhzgQlucHvNaIZ6m6m6n4t43cjUxSrO0ZP9Crv9NBDJme0cA"; + final PublicKey publicKey = readPublicKey(RESOURCES_DIR + PUBLIC_KEY_PEM_FILENAME); + assertNotNull(publicKey); + new JWTVerifier(publicKey, "audience").verifySignature(token.split("\\."), Algorithm.RS256); + } + + /** + * Here we modify the signature on an otherwise legal JWT Token and check verification using the correct Public Key fails + */ + @Test(expected = SignatureException.class) + public void shouldFailOnInvalidJWTTokenSignature() throws Exception { + final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFVTkVRelZCTXpoRk1FVTNRMFZGTURJNFFqYzROakJDTkRSQ1JFRkNSalkzUWpnMFJEVXlOZyJ9" + + "." + + "eyJyb2xlcyI6WyJST0xFX0FETUlOIl0sInVzZXJfaWQiOiJhdXRoMHw1NzcxMGU5ZDE0MWIwN2YyMmU3NDNhYzciLCJlbWFpbCI6ImFyY3NlbGRvbit0cm5AZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYWppbG9uMS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTc3MTBlOWQxNDFiMDdmMjJlNzQzYWM3IiwiYXVkIjoibm5ld1NobHBHVDFBbkZpY1ExUGlKWXdheENuejE4eUIiLCJleHAiOjE0Njc3MDk5OTMsImlhdCI6MTQ2NzY3Mzk5M30" + + "." + + "XXXXX8V8H6WN3MSN1QhrFG4AxNTdFChPBQxrnuqPF0iBvf35v_z9oDzTERaPBDWFHzWT17h0ADxpl7tCIo43k0FoFie6RHa5j82iHnOKPhcqM5hArfKDYk3G5gc30lVmFiMm8PX8WKzDExygLqXZVnIzfB-EmcJWW_2fLiFEMpNC8KDTBVAiyds_n5kiGmW6F_QpLt11af3BDy71tg2fuqkyJE6pEHd1HsTHNCFQzWt7GevVB0HouJS099p6GphsH3kIhmAvHp5j267uYv49sndiUaLq7bL6GZnzv8dhzgQlucHvNaIZ6m6m6n4t43cjUxSrO0ZP9Crv9NBDJme0cA"; + final PublicKey publicKey = readPublicKey(RESOURCES_DIR + PUBLIC_KEY_PEM_FILENAME); + assertNotNull(publicKey); + new JWTVerifier(publicKey, "audience").verifySignature(token.split("\\."), Algorithm.RS256); + } + + /** + * Here we modify the payload section on an otherwise legal JWT Token and check verification using the correct Public Key and + * unaltered JWT signature (which now doesn't match the payload) fails + */ + @Test(expected = SignatureException.class) + public void shouldFailOnInvalidJWTTokenPayload() throws Exception { + final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFVTkVRelZCTXpoRk1FVTNRMFZGTURJNFFqYzROakJDTkRSQ1JFRkNSalkzUWpnMFJEVXlOZyJ9" + + "." + + "XXXXX2xlcyI6WyJST0xFX0FETUlOIl0sInVzZXJfaWQiOiJhdXRoMHw1NzcxMGU5ZDE0MWIwN2YyMmU3NDNhYzciLCJlbWFpbCI6ImFyY3NlbGRvbit0cm5AZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYWppbG9uMS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTc3MTBlOWQxNDFiMDdmMjJlNzQzYWM3IiwiYXVkIjoibm5ld1NobHBHVDFBbkZpY1ExUGlKWXdheENuejE4eUIiLCJleHAiOjE0Njc3MDk5OTMsImlhdCI6MTQ2NzY3Mzk5M30" + + "." + + "gQML78V8H6WN3MSN1QhrFG4AxNTdFChPBQxrnuqPF0iBvf35v_z9oDzTERaPBDWFHzWT17h0ADxpl7tCIo43k0FoFie6RHa5j82iHnOKPhcqM5hArfKDYk3G5gc30lVmFiMm8PX8WKzDExygLqXZVnIzfB-EmcJWW_2fLiFEMpNC8KDTBVAiyds_n5kiGmW6F_QpLt11af3BDy71tg2fuqkyJE6pEHd1HsTHNCFQzWt7GevVB0HouJS099p6GphsH3kIhmAvHp5j267uYv49sndiUaLq7bL6GZnzv8dhzgQlucHvNaIZ6m6m6n4t43cjUxSrO0ZP9Crv9NBDJme0cA"; + final PublicKey publicKey = readPublicKey(RESOURCES_DIR + PUBLIC_KEY_PEM_FILENAME); + assertNotNull(publicKey); + new JWTVerifier(publicKey, "audience").verifySignature(token.split("\\."), Algorithm.RS256); + } + + @Test(expected = IllegalStateException.class) + public void shouldFailWithJwtThaHasTamperedAlgorithm() throws Exception { + final File file = new File(RESOURCES_DIR + PUBLIC_KEY_PEM_FILENAME); + final byte[] data = Files.readAllBytes(file.toPath()); + JWTSigner signer = new JWTSigner(data); + Map claims = new HashMap<>(); + claims.put("sub", "userid"); + JWTSigner.Options options = new JWTSigner.Options(); + options.setAlgorithm(Algorithm.HS256); + String jwt = signer.sign(claims, options); + new JWTVerifier(data).verify(jwt); + final PublicKey publicKey = readPublicKey(RESOURCES_DIR + PUBLIC_KEY_PEM_FILENAME); + new JWTVerifier(publicKey).verify(jwt); + } +} + diff --git a/src/test/java/com/auth0/jwt/JWTVerifierTest.java b/src/test/java/com/auth0/jwt/JWTVerifierTest.java new file mode 100644 index 0000000..e11fd5a --- /dev/null +++ b/src/test/java/com/auth0/jwt/JWTVerifierTest.java @@ -0,0 +1,247 @@ +package com.auth0.jwt; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.security.SignatureException; + +import static org.junit.Assert.assertEquals; + +/** + * General library JWTVerifier related unit tests + */ +public class JWTVerifierTest { + + private static final Base64 decoder = new Base64(true); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void constructorShouldFailOnEmptySecret() { + expectedException.expect(IllegalArgumentException.class); + new JWTVerifier(""); + } + + @Test + public void shouldFailOn1Segments() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().verify("crypto"); + } + + @Test + public void shouldFailOn2Segments() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().verify("much.crypto"); + } + + @Test + public void shouldFailOn4Segments() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().verify("much.crypto.so.token"); + } + + @Test + public void shouldFailOnEmptyStringToken() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().verify(""); + } + + @Test + public void shouldFailOnNullToken() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().verify(null); + } + + @Test + public void shouldFailIfAlgorithmIsNotSetOnToken() throws Exception { + expectedException.expect(IllegalStateException.class); + signatureVerifier().getAlgorithm(JsonNodeFactory.instance.objectNode()); + } + + @Test + public void shouldFailIfAlgorithmIsNotSupported() throws Exception { + expectedException.expect(JWTAlgorithmException.class); + signatureVerifier().getAlgorithm(createSingletonJSONNode("alg", "doge-crypt")); + } + + @Test + public void shouldWorkIfAlgorithmIsSupported() throws Exception { + signatureVerifier().getAlgorithm(createSingletonJSONNode("alg", "HS256")); + } + + @Test + public void shouldFailOnInvalidSignature() throws Exception { + expectedException.expect(SignatureException.class); + final String jws = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9" + + "." + + "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt" + + "cGxlLmNvbS9pc19yb290Ijp0cnVlfQ" + + "." + + "suchsignature_plzvalidate_zomgtokens"; + String secret = "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"; + signatureVerifier(secret).verifySignature(jws.split("\\."), Algorithm.HS256); + } + + @Test + public void shouldVerifySignature() throws Exception { + final String jws = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9" + + "." + + "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt" + + "cGxlLmNvbS9pc19yb290Ijp0cnVlfQ" + + "." + + "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; + byte[] secret = decoder.decode("AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"); + signatureVerifier(secret) + .verifySignature(jws.split("\\."), Algorithm.HS256); + } + + @Test + public void shouldFailWithJwtThaHasTamperedAlgorithm() throws Exception { + expectedException.expect(IllegalStateException.class); + String tamperedAlg = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJqb2UiLCJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.QRsN2SlYJ3EEn7P9dnZGsq9tjyv3giOWzZJzhy67zZs"; + byte[] secret = decoder.decode("AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"); + JWTVerifier verifier = new JWTVerifier(secret); + verifier.verify(tamperedAlg); + } + + @Test + public void shouldFailWhenExpired1SecondAgo() throws Exception { + expectedException.expect(JWTExpiredException.class); + signatureVerifier().verifyExpiration( + createSingletonJSONNode("exp", Long.toString(System.currentTimeMillis() / 1000L - 1L))); + } + + @Test + public void shouldVerifyExpiration() throws Exception { + signatureVerifier().verifyExpiration( + createSingletonJSONNode("exp", Long.toString(System.currentTimeMillis() / 1000L + 50L))); + } + + @Test + public void shouldVerifyIssuer() throws Exception { + issuerVerifier("very issuer") + .verifyIssuer(createSingletonJSONNode("iss", "very issuer")); + } + + @Test + public void shouldFailIssuer() throws Exception { + expectedException.expect(JWTIssuerException.class); + issuerVerifier("very issuer") + .verifyIssuer(createSingletonJSONNode("iss", "wow")); + } + + @Test + public void shouldVerifyIssuerWhenNotFoundInClaimsSet() throws Exception { + expectedException.expect(JWTIssuerException.class); + issuerVerifier("very issuer") + .verifyIssuer(JsonNodeFactory.instance.objectNode()); + } + + @Test + public void shouldVerifyAudience() throws Exception { + audienceVerifier("amaze audience") + .verifyAudience(createSingletonJSONNode("aud", "amaze audience")); + } + + @Test + public void shouldFailAudience() throws Exception { + expectedException.expect(JWTAudienceException.class); + audienceVerifier("amaze audience") + .verifyAudience(createSingletonJSONNode("aud", "wow")); + } + + @Test + public void shouldVerifyAudienceWhenNotFoundInClaimsSet() throws Exception { + expectedException.expect(JWTAudienceException.class); + audienceVerifier("amaze audience") + .verifyAudience(JsonNodeFactory.instance.objectNode()); + } + + @Test + public void shouldVerifyNullAudience() throws Exception { + signatureVerifier() + .verifyAudience(createSingletonJSONNode("aud", "wow")); + } + + @Test + public void shouldVerifyArrayAudience() throws Exception { + audienceVerifier("amaze audience") + .verifyAudience(createSingletonJSONNode("aud", + new ObjectMapper().readValue("[ \"foo\", \"amaze audience\" ]", ArrayNode.class))); + } + + @Test + public void shouldFailArrayAudience() throws Exception { + expectedException.expect(JWTAudienceException.class); + audienceVerifier("amaze audience") + .verifyAudience(createSingletonJSONNode("aud", + new ObjectMapper().readValue("[ \"foo\" ]", ArrayNode.class))); + } + + @Test + public void decodeAndParse() throws Exception { + final Base64 encoder = new Base64(true); + final String encodedJSON = new String(encoder.encode("{\"some\": \"json\", \"number\": 123}".getBytes())); + final JWTVerifier jwtVerifier = new JWTVerifier("secret", "audience"); + + final JsonNode decodedJSON = jwtVerifier.decodeAndParse(encodedJSON); + + assertEquals("json", decodedJSON.get("some").asText()); + assertEquals(null, decodedJSON.get("unexisting_property")); + assertEquals("123", decodedJSON.get("number").asText()); + } + + @Test + public void shouldVerifyAudienceFromToken() throws Exception { + expectedException.expect(JWTAudienceException.class); + JWTVerifier verifier = new JWTVerifier("I.O.U a secret", "samples-api", null); + verifier.verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.wLlz9xDltxqKHQC7BeauPi5Q4KQK4nDjlRqQPvKVLYk"); + } + + @Test + public void shouldVerifyIssuerFromToken() throws Exception { + expectedException.expect(JWTIssuerException.class); + JWTVerifier verifier = new JWTVerifier("I.O.U a secret", null, "samples.auth0.com"); + verifier.verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.wLlz9xDltxqKHQC7BeauPi5Q4KQK4nDjlRqQPvKVLYk"); + } + + private static JWTVerifier signatureVerifier() { + return new JWTVerifier("such secret"); + } + + private static JWTVerifier signatureVerifier(String secret) { + return new JWTVerifier(secret); + } + + private static JWTVerifier signatureVerifier(byte[] secret) { + return new JWTVerifier(secret); + } + + private static JWTVerifier issuerVerifier(String issuer) { + return new JWTVerifier("such secret", null, issuer); + } + + private static JWTVerifier audienceVerifier(String audience) { + return new JWTVerifier("such secret", audience); + } + + private static JsonNode createSingletonJSONNode(String key, String value) { + final ObjectNode jsonNodes = JsonNodeFactory.instance.objectNode(); + jsonNodes.put(key, value); + return jsonNodes; + } + + private static JsonNode createSingletonJSONNode(String key, JsonNode value) { + final ObjectNode jsonNodes = JsonNodeFactory.instance.objectNode(); + jsonNodes.put(key, value); + return jsonNodes; + } +} diff --git a/src/test/resources/auth0-pem/key.pem b/src/test/resources/auth0-pem/key.pem new file mode 100644 index 0000000..ce12c0a --- /dev/null +++ b/src/test/resources/auth0-pem/key.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIJRJ6BX2ejIsNmMA0GCSqGSIb3DQEBBQUAMBwxGjAYBgNV +BAMTEWFqaWxvbjEuYXV0aDAuY29tMB4XDTE2MDYxNDA0MjUxMloXDTMwMDIyMTA0 +MjUxMlowHDEaMBgGA1UEAxMRYWppbG9uMS5hdXRoMC5jb20wggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDWP321jJBlY521B3JqLC7RxFdsIQdDCViav2Z+ +dIOWyN09LxGrAy7pmV8GIHeu5lrmrfzUTfV+MzMyF+9UzRvq79qmMEWfyHBRNCOs +Ig3Sw0DHm3OoyCpdXBAF5F+IclPe2r2Bey7zlXkTUIZ+q4qLuDNKFiONyZdhkBUa +C1TsuplTv7DF2IHwnQpI4MyvRghy8QvxbqMZOj39mBrQYMLCWz2/PXIYRWiu3lxx +WSZS4GJya/2mTZtIatacz1t1W6dLeoS+OuTsPWl4qHsLj14EYPOevaw+8Nzh4eAa +tFRP2VOSm1nqDipuLIRnERSHEF4B6YYiG9EI8E3KrogoeGovAgMBAAGjLzAtMAwG +A1UdEwQFMAMBAf8wHQYDVR0OBBYEFK1l4Why6NUQ8g/7cdIbFtSbBYYjMA0GCSqG +SIb3DQEBBQUAA4IBAQAH+pc6gt5Hyjmqe6GxMRuDqd6/rX8c0EN0XmZ4wDfgbN7l +tN3iQ6i3R5I66GuohfxHFxxCYBnlQcZPFJ4/ZcfgtK42md0dx9Lt1se7E12B32mc +WISWs/dtrKLF6x+kNXJj0j05C0fMBuuxaqmTWJuJZ7LOJG3VS/jLR8t9TIdWexzL +xIDrf8MYjR9D+phLOJmf0ZZMbfxpCb4+txVs+yMAqhhiosXmjluLEIo2X5fejC92 +GVNY+Dm7S1ecWvYwzvx6R8VNqbAZ0QbVU/1dTPff57dfeMlpiXdGf6vc7OLgs8re +Om1fjmXhB9X6G+RYkaReI2VYkfU7ZRIQ/dI9HnYN +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/test/resources/test-pem/test-auth0.key b/src/test/resources/test-pem/test-auth0.key new file mode 100644 index 0000000..663a737 --- /dev/null +++ b/src/test/resources/test-pem/test-auth0.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxmJWY0eJcuV2uBtLnQ4004fuknbODo5xIyRhkYNkls5n9OrB +q4Lok6cjv7G2Q8mxAdlIUmzhTSyuNkrMMKZrPaMsAkNKE/aNpeWuSLXqcMs8T/8g +YCDcEmC5KYEJakNtKb3ZX2FKwT4yHHpsNomLDzJD5DyJKbRpNBm2no7ggIy7TQRJ +2H00mogQIQu8/fUANXVeGPshvLJU8MXEy/eiXkHJIT3DDA4VSr/C/tfP0tGJSNTM +874urc4zej+4INuTuMPtesZS47J0AsPxQuxengS4M76cVt5cH+Iqd1nKe5UqiSKv +LCXacPYg/T/Kdx0tBnwHIjKo/cbzZ+r+XynsCwIDAQABAoIBAFPWWwu5v6x+rJ1B +a8MDre93Eqty6cHdEJL5XQJRtMDGmcg3LYF94SwFBmaMg6pCIjvVx2qN+OjUaQso +sQIeUlPKEV8jcLrfBx2E4xJ3Tow8V1C3UMdPG7Hojler4H633/oz8RkN1Lm1vxep +5PFnTw0tAOQDcTPeulb6RuLbHqU0FEnf/jVOMhtPLcMAwJ3fkAJQ+ljFW2VKCQ83 +d+ci1p+NHY/dbGLSR4lK58mVghcRMO3zhe5scrbECHJMfT6fCb2TXdjaueFUGC6+ +fqUXvDj8HRfUilzTegNq8ZhwgMSw1HeX/PuiczSKc3aHYSsohMBugTErnkW+qF4Z +kE+kxgECgYEA/sm7umcyFuZME+RWYL8Gsp8agH1OGEgsmIiMi1z6RTlTmdR8fN18 +ItzXyW+363VZln/1b5wCaPdLIxgASxybLAaxnKAXfmL7QvyVAaMwxj7N0ogvMQoN +x2VuSGZSam2+LFVIMWHq1C+3fvVnCDLm6oHvIMK/zvEsPBBtz+L6rlECgYEAx1Pr +KogaGHCi1XgsrNv9aFaayRvmhzZbmiigF0iWKAd3KKww94BdyyGSVfMfyL23LAbM +QDCrDNGpYAnpNZo/cL+OcGPYzlPsWDBrJub1HOA/H3WQlP4oEcfdbmJZhIkEwTGF +HaCHynEu4ekiCrWz9+XVNCquTyqnmaVDEzAfEZsCgYA8jQbfUt0Vkh+sboyUq3FV +C/jJZn4jyStICNOV3z/fKbOTkGsRZbW1t1RVHAbSn23uFXTn1GTCO1sQ+QhA0YiT +Gvgk5+sNb0qVbd+fpv/VbWGO0iyc8+24YIOoEyEtB+21LYNdsQ6U5M4wDvQwf6Bf +RQfmekIJVUmU8LaYPDIlMQKBgDSRiT/aTSeM7STnYMDl89sEnCXV2eJnD5mEhVQe +rJs5/M8ZOoDLtfDQlctdJ1DF1/0gfdWgADyNPuI5OuwMFhciLequKoufzoEjo97K +onJPIdamJs9kiCTIVTm7bmhpyns5GCZMJAPb/cVOus+gRCpozuXHK9ltIm5/C0WQ +N2FpAoGBAOss6RN2krieqbn1mG8e2v5mMUd0CJkiJu2y5MnF3dYHXSQ3/ePAh/Yg +JOthpgYgBh+mV0DLqJhx/1DLS/xiqcoHDlndQDmYbtvvY7RlMo00+nGzkRVOfrqy +hC+1KsYHGPbSQixNQXtvFbAAVMSo+RRBkVGINYGDFnlQUpkppYRk +-----END RSA PRIVATE KEY----- diff --git a/src/test/resources/test-pem/test-auth0.pem b/src/test/resources/test-pem/test-auth0.pem new file mode 100644 index 0000000..47e8e14 --- /dev/null +++ b/src/test/resources/test-pem/test-auth0.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIJALr9HwgrQ7GeMA0GCSqGSIb3DQEBBQUAMGIxGDAWBgNV +BAMTD2F1dGgwLmF1dGgwLmNvbTESMBAGA1UEChMJQXV0aDAgTExDMQswCQYDVQQG +EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDAeFw0x +MjEyMjkxNTMwNDdaFw0xMzAxMjgxNTMwNDdaMGIxGDAWBgNVBAMTD2F1dGgwLmF1 +dGgwLmNvbTESMBAGA1UEChMJQXV0aDAgTExDMQswCQYDVQQGEwJVUzETMBEGA1UE +CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMZiVmNHiXLldrgbS50ONNOH7pJ2zg6OcSMkYZGDZJbO +Z/TqwauC6JOnI7+xtkPJsQHZSFJs4U0srjZKzDCmaz2jLAJDShP2jaXlrki16nDL +PE//IGAg3BJguSmBCWpDbSm92V9hSsE+Mhx6bDaJiw8yQ+Q8iSm0aTQZtp6O4ICM +u00ESdh9NJqIECELvP31ADV1Xhj7IbyyVPDFxMv3ol5BySE9wwwOFUq/wv7Xz9LR +iUjUzPO+Lq3OM3o/uCDbk7jD7XrGUuOydALD8ULsXp4EuDO+nFbeXB/iKndZynuV +Kokirywl2nD2IP0/yncdLQZ8ByIyqP3G82fq/l8p7AsCAwEAAaOBxzCBxDAdBgNV +HQ4EFgQUHI2rUXeBjTv1zAllaPGrHFcEK0YwgZQGA1UdIwSBjDCBiYAUHI2rUXeB +jTv1zAllaPGrHFcEK0ahZqRkMGIxGDAWBgNVBAMTD2F1dGgwLmF1dGgwLmNvbTES +MBAGA1UEChMJQXV0aDAgTExDMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu +Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZIIJALr9HwgrQ7GeMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAFrXIhCy4T4eGrikb0R2wHv/uS548r3pZyBV0CDb +cRwAtbnpJMvkGFqKVp4pmyoIDSVNK/j+sLEshB20XftezHZyRJbCUbtKvXQ6Fsxo +eZMlN0ITYKTaoBZKhUxxj90otAhNC58qwGUPqt2LewJhHyLucKkGJ1mQ3b5xKZ53 +2ToufouH9VLhig3H1KnxWo/zMD6Ke8cCk6qO9htuhI06s3GQGS1QWQtAmm17C6Tf +KgDwQFZwhqHUUZnwKRH8gU6OgZsvhgV1B7H5mjZcu57KMiDBekU9MEY0DCVTN3Wk +mcTII668zLsJrkNX6PEfck1AMBbVE6pEUKcWwq3uaLvlAUo= +-----END CERTIFICATE-----