Oauth2 JWT Verifier for Spring Boot

Verify Oauth2 JWTs in Spring Boot projects using annotations.

License

License

Categories

Categories

H2 Data Databases OAuth2 Security
GroupId

GroupId

space.crickets
ArtifactId

ArtifactId

oauth2-jwt-verifier-springboot
Last Version

Last Version

0.1.0
Release Date

Release Date

Type

Type

jar
Description

Description

Oauth2 JWT Verifier for Spring Boot
Verify Oauth2 JWTs in Spring Boot projects using annotations.
Project URL

Project URL

https://github.com/jatin-sonavane/oauth2-jwt-verifier-springboot
Source Code Management

Source Code Management

https://github.com/jatin-sonavane/oauth2-jwt-verifier-springboot

Download oauth2-jwt-verifier-springboot

How to add to project

<!-- https://jarcasting.com/artifacts/space.crickets/oauth2-jwt-verifier-springboot/ -->
<dependency>
    <groupId>space.crickets</groupId>
    <artifactId>oauth2-jwt-verifier-springboot</artifactId>
    <version>0.1.0</version>
</dependency>
// https://jarcasting.com/artifacts/space.crickets/oauth2-jwt-verifier-springboot/
implementation 'space.crickets:oauth2-jwt-verifier-springboot:0.1.0'
// https://jarcasting.com/artifacts/space.crickets/oauth2-jwt-verifier-springboot/
implementation ("space.crickets:oauth2-jwt-verifier-springboot:0.1.0")
'space.crickets:oauth2-jwt-verifier-springboot:jar:0.1.0'
<dependency org="space.crickets" name="oauth2-jwt-verifier-springboot" rev="0.1.0">
  <artifact name="oauth2-jwt-verifier-springboot" type="jar" />
</dependency>
@Grapes(
@Grab(group='space.crickets', module='oauth2-jwt-verifier-springboot', version='0.1.0')
)
libraryDependencies += "space.crickets" % "oauth2-jwt-verifier-springboot" % "0.1.0"
[space.crickets/oauth2-jwt-verifier-springboot "0.1.0"]

Dependencies

compile (7)

Group / Artifact Type Version
io.jsonwebtoken : jjwt-api jar 0.10.7
io.jsonwebtoken : jjwt-impl jar 0.10.7
org.springframework : spring-context jar 5.1.9.RELEASE
org.springframework : spring-aop jar 5.1.9.RELEASE
org.aspectj : aspectjweaver jar 1.9.4
org.apache.logging.log4j : log4j-api jar 2.12.0
org.apache.logging.log4j : log4j-core jar 2.12.0

runtime (4)

Group / Artifact Type Version
com.google.code.gson : gson jar 2.8.5
com.squareup.okhttp3 : okhttp jar 4.0.1
com.google.guava : guava jar 27.1-jre
io.jsonwebtoken : jjwt-jackson jar 0.10.7

test (5)

Group / Artifact Type Version
org.springframework : spring-test jar 5.1.9.RELEASE
org.springframework.boot : spring-boot-test jar 2.1.6.RELEASE
org.mockito : mockito-core jar 3.0.0
junit : junit jar 4.12
com.squareup.okhttp3 : mockwebserver jar 4.0.1

Project Modules

There are no modules declared in this project.

Oauth2 JWT Verifier for Spring Boot

Once a human or machine is successfully authenticated by an Oauth2 provider (via the Authorization Code flow for humans or the Client Credentials flow for machines), they receive a Json Web Token (JWT, see https://jwt.io) in the form of an access_token or an id_token. This token is usually included as an HTTP request header that looks like:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIx...

For more information on verifying access tokens:

https://auth0.com/docs/api-auth/tutorials/verify-access-token

Java services receiving such tokens as request headers on any of its API endpoints will need to verify that the token is not counterfeit and has not expired. Additionally the API endpoint may have requirements governing the claims in the token, such as whether the right scopes or groups are specified in the token, and may want to do further claim verification.

There are other libraries that aim to help java services with this:

So what's special about Oauth2 JWT Verifier for Spring Boot?

Intuitive annotation-based authorization in Spring Boot

This library considerably simplifies the code you'd otherwise write by allowing the service to specify its authorization requirements via annotations applied to the API method and its parameters. This reduces boilerplate, and makes it easy for different API endpoints to customize their authorization requirements, while making explicit at the API method level, what those requirements are.

Here is the simplest example showing how the @Authorize and @Jwt annotations are used:

     @Authorize
     public T someApiCall(@Jwt String authorization) { 
         ... 
     }

The requirement above says - "make sure that the incoming JWT is legitimate". If the JWT were not legitimate, an UnauthorizedException would be thrown, aborting execution before reaching the code in the method.

Here's a more involved example:

     @Authorize(scopes = {"contacts.read", "contacts.write"})
     @GetMapping
     public List<Contacts> getContacts(
             @MatchClaim("sub") String userEmail,
             int requestedContactCount,
             @BindClaim("max_contacts") Integer maxContactCount,
             @Jwt String authorization) { 
         ...
         // Custom logic checking that requestedContactCount <= maxContactCount...
         ...
     }

This requirement says -

  • Make sure the JWT passed in the authorization parameter is legitimate, AND
  • That the token has at least the contacts.read or contacts.write scope, AND
  • The sub claim must match the value passed in to the userEmail parameter.
  • Also, please update the maxContactCount parameter with the value of the max_contacts claim found in the JWT so that we can do our own custom authorization logic.

There are more capabilities such as validating the groups claim, or being either lenient or strict with the @MatchClaim directive. See the code documentation for these annotations for more detail.

  • @Authorize
  • @Jwt
  • @MatchClaim
  • @BindClaim

Dependencies

Add this library to your service via:

  <dependency>
    <groupId>space.crickets</groupId>
    <artifactId>oauth2-jwt-verifier-springboot</artifactId>
    <version>0.1.0</version>
  </dependency>

Providing the remote Json Web Keys endpoint(s)

Assuming your service is already working with an Oauth2 provider like Okta or Auth0, your service will need to add the following bean in one of its @Configuration classes like this:

    @Bean
    public JwksEndpoints jwksEndpoints() {
        return new JwksEndpoints(
                "https://yourcompany.okta.com/oauth2/abc123/v1/keys",
                "https://yourothercompany.okta.com/oauth2/abc123/v1/keys"
        );
    }

This will allow the library to get the public Json Web Keys it needs to verify JWTs.

That's about it. Start using the annotations.

Versions

Version
0.1.0