HORIZON HASKELLDocslts/ghc-9.14.x45dd5372026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · 45dd537 · 2026-10-11

Modulehoauth2-2.15.2Haskell2010

Network.OAuth2.Experiment

This module contains a new way of doing OAuth2 authorization and authentication in order to obtain an access token and maybe a refresh token based on RFC 6749.

This module will become the default in a future release.

The key concept is introducing grant flows, which determine the entire workflow per the spec. Each workflow has slightly different request parameters, which is why you'll often see different configuration options when creating an OAuth2 application in an IdP developer console.

Here are the supported flows:

  1. Authorization Code. This flow requires an authorize call to obtain an authorization code, then exchange the code for tokens.

  2. Resource Owner Password. This flow only requires hitting the token endpoint with, of course, username and password, to obtain tokens.

  3. Client Credentials. This flow also only requires hitting the token endpoint, but with different parameters. The client credentials flow does not involve an end user, so you won't be able to hit the userinfo endpoint with the access token you obtain.

  4. PKCE (RFC 7636). This is an enhancement on top of the authorization code flow.

The implicit flow is not supported because it is primarily for SPAs (single-page apps), and it has been deprecated in favor of the authorization code flow with PKCE.

Here is a quick sample showing how to use the vocabulary from this module.

First, initialize your IdP (using Google as an example) and the application.


import Network.OAuth2.Experiment
import URI.ByteString.QQ

data Google = Google deriving (Eq, Show)

googleIdp :: Idp Google
googleIdp =
  Idp
    { idpAuthorizeEndpoint = [uri|https://accounts.google.com/o/oauth2/v2/auth|]
    , idpTokenEndpoint = [uri|https://oauth2.googleapis.com/token|]
    , idpUserInfoEndpoint = [uri|https://www.googleapis.com/oauth2/v2/userinfo|]
    , idpDeviceAuthorizationEndpoint = Just [uri|https://oauth2.googleapis.com/device/code|]
    }

fooApp :: AuthorizationCodeApplication
fooApp =
  AuthorizationCodeApplication
    { acClientId = "xxxxx",
      acClientSecret = "xxxxx",
      acScope =
        Set.fromList
          [ "https://www.googleapis.com/auth/userinfo.email",
            "https://www.googleapis.com/auth/userinfo.profile"
          ],
      acAuthorizeState = "CHANGE_ME",
      acAuthorizeRequestExtraParams = Map.empty,
      acRedirectUri = [uri|http://localhost/oauth2/callback|],
      acName = "sample-google-authorization-code-app",
      acClientAuthenticationMethod = ClientSecretBasic,
    }

fooIdpApplication :: IdpApplication AuthorizationCodeApplication Google
fooIdpApplication = IdpApplication fooApp googleIdp

Second, construct the authorize URL.

authorizeUrl = mkAuthorizationRequest fooIdpApplication

Third, after a successful redirect with an authorization code, you can exchange it for an access token.

mgr <- liftIO $ newManager tlsManagerSettings
tokenResp <- conduitTokenRequest fooIdpApplication mgr authorizeCode

If you'd like to fetch user info, use this method:

conduitUserInfoRequest fooIdpApplication mgr (accessToken tokenResp)

You can also find an example in the hoauth2-providers-tutorial module.

  • 18 types
  • 2 classes
  • 10 values
  • Packagehoauth2-2.15.2
  • Exports32
  • LanguageHaskell2010
  • LicenceMIT
  • SourceExperiment.hs

Application per Grant type

5 declarations
Instances7HasRefreshTokenRequest, HasTokenRequest, HasClientAuthenticationMethod, HasUserInfoRequest, ToQueryParam, ExchangeTokenInfo, …
Instances5HasTokenRequest, HasClientAuthenticationMethod, ToQueryParam, ExchangeTokenInfo, TokenRequest

An Application that supports "Device Authorization Grant"

https://www.rfc-editor.org/rfc/rfc8628#section-3.1

Constructors

Instances6HasTokenRequest, HasClientAuthenticationMethod, HasUserInfoRequest, ToQueryParam, ExchangeTokenInfo, TokenRequest
datadata JwtBearerApplication
#

An Application that supports "JWT Bearer" flow

https://datatracker.ietf.org/doc/html/rfc7523

Instances6HasTokenRequest, HasClientAuthenticationMethod, HasUserInfoRequest, ToQueryParam, ExchangeTokenInfo, TokenRequest
Instances7HasRefreshTokenRequest, HasTokenRequest, HasClientAuthenticationMethod, HasUserInfoRequest, ToQueryParam, ExchangeTokenInfo, …

Authorization Code

2 declarations

Device Authorization

3 declarations

Token Request

6 declarations
familytype family ExchangeTokenInfo a
#
Instances5ExchangeTokenInfo
classclass HasClientAuthenticationMethod a => HasTokenRequest a where
#

Associated types

Instances5HasTokenRequest
datadata NoNeedExchangeToken
#

Only Authorization Code Grant involves a Exchange Token (Authorization Code). ResourceOwnerPassword and Client Credentials make token request directly.

familydata family TokenRequest a
#
Instances10ToQueryParam, TokenRequest, …

Refresh Token Request

2 declarations

UserInfo Request

2 declarations

Types

11 declarations
datadata Idp (i :: k)
#

Idp i consists various endpoints endpoints.

The i is actually phantom type for information only (Idp name) at this moment. And it is PolyKinds.

Hence whenever Idp i or IdpApplication i a is used as function parameter, PolyKinds need to be enabled.

Constructors

datadata IdpApplication (i :: k) a
#

An OAuth2 Application "a" of IdP "i". "a" can be one of following type:

  • Network.OAuth2.Experiment.AuthorizationCodeApplication

  • Network.OAuth2.Experiment.DeviceAuthorizationApplication

  • Network.OAuth2.Experiment.ClientCredentialsApplication

  • Network.OAuth2.Experiment.ResourceOwnerPasswordApplication

  • Network.OAuth2.Experiment.JwtBearerApplication

Constructors

newtypenewtype Scope
#

Constructors

Instances5Eq, Ord, Show, IsString, ToQueryParam
  • Eq ScopeDefined in hoauth2-2.15.2 · Network.OAuth2.Experiment.Types
  • Ord ScopeDefined in hoauth2-2.15.2 · Network.OAuth2.Experiment.Types
  • Show ScopeDefined in hoauth2-2.15.2 · Network.OAuth2.Experiment.Types
  • IsString ScopeDefined in hoauth2-2.15.2 · Network.OAuth2.Experiment.Types
  • ToQueryParam (Set Scope)Defined in hoauth2-2.15.2 · Network.OAuth2.Experiment.Types

How would the Client (RP) authenticate itself?

The client MUST NOT use more than one authentication method in each request. Means use Authorization header or Post body.

See more details

https://www.rfc-editor.org/rfc/rfc6749#section-2.3 https://oauth.net/private-key-jwt/ https://www.rfc-editor.org/rfc/rfc7523.html

Instances2Eq, Show

Utils

1 declaration