Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
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. (TBD but likely 3.0).
The key concept/change is to introduce the GrantTypeFlow
, 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
- Authorization Code. This flow requires authorize call to obtain an authorize code, then exchange the code for tokens.
- Resource Owner Password. This flow only requires to hit token endpoint with, of course, username and password, to obtain tokens.
- 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.
- 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) and more or less obsolete 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.
data Google = Google deriving (Eq, Show) googleIdp = Idp Google Idp { idpFetchUserInfo = authGetJSON @(IdpUserInfo Google), 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|] } fooApp :: IdpApplication 'AuthorizationCode Google fooApp = AuthorizationCodeIdpApplication { idpAppClientId = "xxxxx", idpAppClientSecret = "xxxxx", idpAppScope = Set.fromList [ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile" ], idpAppAuthorizeState = "CHANGE_ME", idpAppAuthorizeExtraParams = Map.empty, idpAppRedirectUri = [uri|http://localhost/oauth2/callback|], idpAppName = "default-google-App", idpAppTokenRequestAuthenticationMethod = ClientSecretBasic, idp = googleIdp }
Secondly, construct the authorize URL.
authorizeUrl = mkAuthorizeRequest fooApp
Thirdly, after a successful redirect with authorize code, you could exchange for access token
mgr <- liftIO $ newManager tlsManagerSettings tokenResp <- conduitTokenRequest fooApp mgr authorizeCode
Lastly, you probably like to fetch user info
conduitUserInfoRequest fooApp mgr (accessToken tokenResp)
Also you could find example from hoauth2-providers-tutorials
module.