oauth2-jwt-bearer: OAuth2 jwt-bearer client flow as per rfc7523

[ bsd3, library, network ] [ Propose Tags ]

This is an implementation of the jwt-bearer authorization grant flow that is specified by the OAuth2 JWT profile in rfc7523.

[Skip to Readme]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Versions [RSS] 0.0.1
Change log ChangeLog.md
Dependencies aeson (>=1.0 && <1.5), base (>=4.10 && <5), bytestring (>=0.10 && <0.11), http-client (>=0.5 && <0.6), http-client-tls (>=0.2 && <0.4), http-types (<1), jose (>=0.7 && <0.8), lens (>=4 && <5), text (>=1 && <2), time (>=1 && <2), transformers (>=0.4 && <0.6), transformers-bifunctors (<1), unordered-containers (>=0.2 && <0.3) [details]
License BSD-3-Clause
Copyright (c) 2018, HotelKilo
Author Mark Hibberd
Maintainer mth@smith.st
Category Network
Home page https://github.com/smith-security/oauth2-jwt-bearer
Bug tracker https://github.com/smith-security/oauth2-jwt-bearer/issues
Source repo head: git clone git@github.com:smith-security/oauth2-jwt-bearer.git
Uploaded by MarkHibberd at 2018-11-07T19:23:59Z
Reverse Dependencies 2 direct, 0 indirect [details]
Downloads 744 total (4 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2018-11-07 [all 1 reports]

Readme for oauth2-jwt-bearer-0.0.1

[back to package description]


This is an implementation of the jwt-bearer authorization grant flow that is specified by the OAuth2 JWT profile in rfc7523.

The goal is to implement a portable implementation of this flow that can be used against multiple servers. Its goal is to be pretty general, and has been tested against the Google Cloud Platform OAuth2 implementation, and the Smith implementation as well as a generic test server, but there may be a way to go. If you find a server that this implementation doesn't work with, let me know and I will add a test and address it.


OAuth2 / OIDC flows are complicated enough that it warrants having an implementation to fall back on. The scope of this library is one specific flow to make the implementation manageable. It would be nice to have a complete set of flow implentations, but the reality is that OAuth2 doesn't really offer much in the terms of interoperability - it is about consistency/security, not about interchangable implementations - this means that implementing everything at once is a somewhat lost battle. Restricting ourselves to this specific flow allows us to provide something useful and possible.


This library is new, and should have the disclaimers that normally comes with that, but the API should be stable and is currently in production level usage. The library will be maintained going forward.


A crude example:

{-# LANGUAGE OverloadedStrings #-}
module Network.OAuth2.JWT.Client.Example where

import           Crypto.JWT (JWK)
import           Network.OAuth2.JWT.Client
import           Network.HTTP.Client (Manager)

example :: Manager -> JWK -> IO (Either GrantError AccessToken)
example manager key =  do
    endpoint = TokenEndpoint "https://www.googleapis.com/oauth2/v4/token"
    iss = Issuer "example@example.org"
    scopes = [Scope "profile"]
    aud = Audience "https://www.googleapis.com/oauth2/v4/token"
    expiry = ExpiresIn 3600
    claims = Claims iss Nothing aud scopes expiry []
  store <- newStore manager endpoint claims key
  grant store

The key function here is the grant function which is what you call to get your access token.

The grant function obtains an access token, if we have already aquired one (and it is still valid) we will re-use that token, if we don't already have a token or the token has expired, we go and ask for a new one.

This operation is safe to call from multiple threads. If we are using a current token reads will happen concurrently, If we have to go to the network the request will be serialised so that only one request is made for a new token.

The access token can be used as a bearer token in an Authorization header. See the specification for more details but it would be something like:

Authorization: Bearer ${ACCESS_TOKEN}