hoauth2-2.15.0: Haskell OAuth2 authentication client
Safe HaskellNone
LanguageHaskell2010

Network.OAuth2.Experiment

Description

This module contains a new way of doing OAuth2 authorization and authentication in order to obtain Access Token and maybe Refresh Token base on rfc6749.

This module will become default in future release.

The key concept/change is to introduce the Grant flow, which determines the entire work flow per spec. Each work flow will have slight different request parameters, which often time you'll see different configuration when creating OAuth2 application in the IdP developer application page.

Here are supported flows

  1. Authorization Code. This flow requires authorize call to obtain an authorize code, then exchange the code for tokens.
  2. Resource Owner Password. This flow only requires to hit token endpoint with, of course, username and password, to obtain tokens.
  3. Client Credentials. This flow also only requires to hit token endpoint but with different parameters. Client credentials flow does not involve an end user hence you won't be able to hit userinfo endpoint with access token obtained.
  4. PKCE (rfc7636). This is enhancement on top of authorization code flow.

Implicit flow is not supported because it is more for SPA (single page app) given it is deprecated by Authorization Code flow with PKCE.

Here is quick sample for how to use vocabularies from this new module.

Firstly, initialize your IdP (use google as 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

Secondly, construct the authorize URL.

authorizeUrl = mkAuthorizationRequest fooIdpApplication

Thirdly, after a successful redirect with authorize code, you could exchange for access token

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

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

conduitUserInfoRequest fooIdpApplication mgr (accessToken tokenResp)

You could also find example from hoauth2-providers-tutorials module.

Synopsis

Application per Grant type

data DeviceAuthorizationApplication Source #

An Application that supports "Device Authorization Grant"

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

Constructors

DeviceAuthorizationApplication 

Fields

Instances

Instances details
HasClientAuthenticationMethod DeviceAuthorizationApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

HasTokenRequest DeviceAuthorizationApplication Source #

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

Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

HasUserInfoRequest DeviceAuthorizationApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

ToQueryParam (TokenRequest DeviceAuthorizationApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

type ExchangeTokenInfo DeviceAuthorizationApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

data TokenRequest DeviceAuthorizationApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

data AuthorizationCodeApplication Source #

An Application that supports "Authorization code" flow

https://www.rfc-editor.org/rfc/rfc6749#section-4.1

Instances

Instances details
HasRefreshTokenRequest AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

HasClientAuthenticationMethod AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

HasTokenRequest AuthorizationCodeApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

HasUserInfoRequest AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

ToQueryParam (TokenRequest AuthorizationCodeApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

type ExchangeTokenInfo AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

data TokenRequest AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

data ClientCredentialsApplication Source #

An Application that supports "Client Credentials" flow

https://www.rfc-editor.org/rfc/rfc6749#section-4.4

Instances

Instances details
HasClientAuthenticationMethod ClientCredentialsApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

HasTokenRequest ClientCredentialsApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2

Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

ToQueryParam (TokenRequest ClientCredentialsApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

type ExchangeTokenInfo ClientCredentialsApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

data TokenRequest ClientCredentialsApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

data JwtBearerApplication Source #

An Application that supports "JWT Bearer" flow

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

Instances

Instances details
HasClientAuthenticationMethod JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

HasTokenRequest JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

HasUserInfoRequest JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

ToQueryParam (TokenRequest JwtBearerApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

type ExchangeTokenInfo JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

data TokenRequest JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

data ResourceOwnerPasswordApplication Source #

An Application that supports "Resource Owner Password" flow

https://www.rfc-editor.org/rfc/rfc6749#section-4.3

Instances

Instances details
HasRefreshTokenRequest ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

HasClientAuthenticationMethod ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

HasTokenRequest ResourceOwnerPasswordApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2

Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

HasUserInfoRequest ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

ToQueryParam (TokenRequest ResourceOwnerPasswordApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

type ExchangeTokenInfo ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

data TokenRequest ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

Authorization Code

mkAuthorizationRequest :: forall {k} (i :: k). IdpApplication i AuthorizationCodeApplication -> URI Source #

Constructs an Authorization Code request URI according to RFC 6749 Section 4.1.1.

The generated URI includes: * client_id * response_type (always "code") * redirect_uri * state (if provided) * scope (if provided)

mkPkceAuthorizeRequest :: forall {k} m (i :: k). MonadIO m => IdpApplication i AuthorizationCodeApplication -> m (URI, CodeVerifier) Source #

Constructs an Authorization Code request URI with PKCE support according to RFC 7636.

Returns both the authorization URI and the generated code verifier. The code verifier must be stored securely for later use in the token request.

Device Authorization

pollDeviceTokenRequest :: forall {k} (m :: Type -> Type) (i :: k). MonadIO m => IdpApplication i DeviceAuthorizationApplication -> Manager -> DeviceAuthorizationResponse -> ExceptT TokenResponseError m TokenResponse Source #

Polls for a token using the device authorization flow.

This implements the polling mechanism described in RFC 8628 Section 3.5. Handles automatic retries and interval adjustments based on IdP responses.

Token Request

class HasClientAuthenticationMethod a => HasTokenRequest a Source #

Minimal complete definition

mkTokenRequestParam

Associated Types

data TokenRequest a Source #

type ExchangeTokenInfo a Source #

Instances

Instances details
HasTokenRequest AuthorizationCodeApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

HasTokenRequest ClientCredentialsApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2

Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

HasTokenRequest DeviceAuthorizationApplication Source #

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

Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

HasTokenRequest JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

HasTokenRequest ResourceOwnerPasswordApplication Source #

https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2

Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

data family TokenRequest a Source #

Instances

Instances details
ToQueryParam (TokenRequest AuthorizationCodeApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

ToQueryParam (TokenRequest ClientCredentialsApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

ToQueryParam (TokenRequest DeviceAuthorizationApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

ToQueryParam (TokenRequest JwtBearerApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

ToQueryParam (TokenRequest ResourceOwnerPasswordApplication) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

data TokenRequest AuthorizationCodeApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.AuthorizationCode

data TokenRequest ClientCredentialsApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ClientCredentials

data TokenRequest DeviceAuthorizationApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.DeviceAuthorization

data TokenRequest JwtBearerApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.JwtBearer

data TokenRequest ResourceOwnerPasswordApplication Source # 
Instance details

Defined in Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

data NoNeedExchangeToken Source #

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

Constructors

NoNeedExchangeToken 

conduitTokenRequest :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> ExchangeTokenInfo a -> ExceptT TokenResponseError m TokenResponse Source #

Sends a token request according to RFC 6749 Section 4.1.3.

This is used for exchanging authorization codes, device codes, or other grant types for access tokens.

Refresh Token Request

conduitRefreshTokenRequest :: forall {k} (m :: Type -> Type) a (i :: k). (MonadIO m, HasRefreshTokenRequest a) => IdpApplication i a -> Manager -> RefreshToken -> ExceptT TokenResponseError m TokenResponse Source #

Makes a Refresh Token Request according to RFC 6749 Section 6.

Used to obtain a new access token using a refresh token.

UserInfo Request

conduitUserInfoRequest :: forall {k} (m :: Type -> Type) a b (i :: k). (MonadIO m, HasUserInfoRequest a, FromJSON b) => IdpApplication i a -> Manager -> AccessToken -> ExceptT ByteString m b Source #

Makes a standard request to the userinfo endpoint using GET method.

This is commonly used with OpenID Connect providers to fetch user profile information using an access token.

conduitUserInfoRequestWithCustomMethod :: forall {k} (m :: Type -> Type) a b (i :: k). (MonadIO m, HasUserInfoRequest a, FromJSON b) => (Manager -> AccessToken -> URI -> ExceptT ByteString m b) -> IdpApplication i a -> Manager -> AccessToken -> ExceptT ByteString m b Source #

Makes a request to the userinfo endpoint using a custom HTTP method.

Some IdPs may require different HTTP methods (instead of GET) or custom headers for fetching user information. This function provides that flexibility.

Types

newtype ClientId Source #

Constructors

ClientId 

Fields

Instances

Instances details
IsString ClientId Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Show ClientId Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Eq ClientId Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

ToQueryParam ClientId Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

newtype ClientSecret Source #

Can be either "Client Secret" or JWT base on client authentication method

Constructors

ClientSecret 

Fields

data Idp (i :: k) Source #

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

Idp 

Fields

newtype Password Source #

Constructors

Password 

Fields

Instances

Instances details
IsString Password Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Eq Password Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

ToQueryParam Password Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

newtype RedirectUri Source #

Constructors

RedirectUri 

Fields

Instances

Instances details
Eq RedirectUri Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

ToQueryParam RedirectUri Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

newtype Scope Source #

Constructors

Scope 

Fields

Instances

Instances details
IsString Scope Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Methods

fromString :: String -> Scope #

Show Scope Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Methods

showsPrec :: Int -> Scope -> ShowS #

show :: Scope -> String #

showList :: [Scope] -> ShowS #

Eq Scope Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Methods

(==) :: Scope -> Scope -> Bool #

(/=) :: Scope -> Scope -> Bool #

Ord Scope Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Methods

compare :: Scope -> Scope -> Ordering #

(<) :: Scope -> Scope -> Bool #

(<=) :: Scope -> Scope -> Bool #

(>) :: Scope -> Scope -> Bool #

(>=) :: Scope -> Scope -> Bool #

max :: Scope -> Scope -> Scope #

min :: Scope -> Scope -> Scope #

ToQueryParam (Set Scope) Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

newtype Username Source #

Constructors

Username 

Fields

Instances

Instances details
IsString Username Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Eq Username Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

ToQueryParam Username Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

newtype CodeVerifier Source #

Constructors

CodeVerifier 

Fields

Instances

Instances details
ToQueryParam CodeVerifier Source # 
Instance details

Defined in Network.OAuth2.Experiment.Types

Utils