Skip to content

Commit

Permalink
several doc revision on all grants (diagrams, type description etc ...)
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Feb 17, 2020
1 parent 3dc3c9d commit 6199c78
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 87 deletions.
3 changes: 3 additions & 0 deletions src/OAuth.elm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ you'll only need tu use one of the additional modules:
and refresh tokens via a redirection-based flow and is optimized for confidential clients
[4.1](https://tools.ietf.org/html/rfc6749#section-4.1).
- OAuth.AuthorizationCode.PKCE: An extension of the original OAuth 2.0 specification to mitigate
authorization code interception attacks through the use of Proof Key for Code Exchange (PKCE).
- OAuth.Implicit: The implicit grant type is used to obtain access tokens (it does not support the
issuance of refresh tokens) and is optimized for public clients known to operate a particular
redirection URI [4.2](https://tools.ietf.org/html/rfc6749#section-4.2).
Expand Down
88 changes: 68 additions & 20 deletions src/OAuth/AuthorizationCode.elm
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,40 @@ interacting with the resource owner's user-agent (typically a web
browser) and capable of receiving incoming requests (via redirection)
from the authorization server.
This is a 3-step process:
- The client asks for an authorization to the OAuth provider: the user is redirected.
- The provider redirects the user back and the client parses the request query parameters from the url.
- The client authenticate itself using the authorization code found in the previous step.
+---------+ +--------+
| |---(A)- Auth Redirection ------>| |
| | | Auth |
| Browser | | Server |
| | | |
| |<--(B)- Redirection Callback ---| |
+---------+ (w/ Auth Code) +--------+
^ | ^ |
| | | |
(A) (B) | |
| | | |
| v | |
+---------+ | |
| |----(C)---- Auth Code ------------+ |
| Elm App | |
| | |
| |<---(D)------ Access Token ------------+
+---------+ (w/ Optional Refresh Token)
- (A) The client initiates the flow by directing the resource owner's
user-agent to the authorization endpoint.
- (B) Assuming the resource owner grants access, the authorization
server redirects the user-agent back to the client including an
authorization code and any local state provided by the client
earlier.
- (C) The client requests an access token from the authorization
server's token endpoint by including the authorization code
received in the previous step.
- (D) The authorization server authenticates the client and validates
the authorization code. If valid, the authorization server responds
back with an access token and, optionally, a refresh token.
After those steps, the client owns a `Token` that can be used to authorize any subsequent
request.
Expand Down Expand Up @@ -66,6 +95,27 @@ import Url.Parser.Query as Query


{-| Request configuration for an authorization (Authorization Code & Implicit flows)
- clientId (_REQUIRED_):
The client identifier issues by the authorization server via an off-band mechanism.
- url (_REQUIRED_):
The authorization endpoint to contact the authorization server.
- redirectUri (_OPTIONAL_):
After completing its interaction with the resource owner, the authorization
server directs the resource owner's user-agent back to the client via this
URL. May be already defined on the authorization server itself.
- scope (_OPTIONAL_):
The scope of the access request.
- state (_RECOMMENDED_):
An opaque value used by the client to maintain state between the request
and callback. The authorization server includes this value when redirecting
the user-agent back to the client. The parameter SHOULD be used for preventing
cross-site request forgery.
-}
type alias Authorization =
{ clientId : String
Expand Down Expand Up @@ -253,21 +303,19 @@ defaultAuthorizationErrorParser =

{-| Request configuration for an AuthorizationCode authentication
let authentication =
{ credentials =
-- Only the clientId is required. Specify a secret
-- if a Basic OAuth is required by the resource
-- provider
{ clientId = "<my-client-id>"
, secret = Nothing
}
-- Authorization code from the authorization result
, code = "<authorization-code>"
-- Token endpoint of the resource provider
, url = "<token-endpoint>"
-- Redirect Uri to your webserver
, redirectUri = "<my-web-server>"
}
- credentials (_REQUIRED_):
Only the clientId is required. Specify a secret if a Basic OAuth
is required by the resource provider.
- code (_REQUIRED_):
Authorization code from the authorization result
- url (_REQUIRED_):
Token endpoint of the resource provider
- redirectUri (_REQUIRED_):
Redirect Uri to your webserver used in the authorization step, provided
here for verification.
-}
type alias Authentication =
Expand Down
67 changes: 39 additions & 28 deletions src/OAuth/AuthorizationCode/PKCE.elm
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,24 @@ module OAuth.AuthorizationCode.PKCE exposing
susceptible to the authorization code interception attack. A possible
mitigation against the threat is to use a technique called Proof Key for
Code Exchange (PKCE, pronounced "pixy") when supported by the target
authorization server.
+-------------------+
| Authz Server |
+--------+ | +---------------+ |
| |--(A)- Authorization Request ---->| | |
| | + t(code_verifier), t_m | | Authorization | |
| | | | Endpoint | |
| |<-(B)---- Authorization Code -----| | |
| Elm | | +---------------+ |
| App | | |
| | | +---------------+ |
| |--(C)-- Access Token Request ---->| | |
| | + code_verifier | | Token | |
| | | | Endpoint | |
| |<-(D)------ Access Token ---------| | |
+--------+ | +---------------+ |
+-------------------+
Abstract Protocol Flow
authorization server. See also [RFC 7636](https://tools.ietf.org/html/rfc7636).
+-----------------+
| Auth Server |
+-------+ | +-------------+ |
| |--(1)- Auth Request --->| | | |
| | + code_challenge | | Auth | |
| | | | Endpoint | |
| |<-(2)-- Auth Code ------| | | |
| Elm | | +-------------+ |
| App | | |
| | | +-------------+ |
| |--(3)- Token Request -->| | | |
| | + code_verifier | | Token | |
| | | | Endpoint | |
| |<-(4)- Access Token --->| | | |
+-------+ | +-------------+ |
+-----------------+
See also the Authorization Code flow for details about the basic version
of this flow.
Expand Down Expand Up @@ -86,14 +84,26 @@ import Url.Parser.Query as Query
--


type CodeChallenge
= CodeChallenge Base64.Encoder
{-| An opaque type representing a code verifier. Typically constructed from a high quality entropy.
case codeVerifierFromBytes entropy of
Nothing -> {- ...-}
Just codeVerifier -> {- ... -}
-}
type CodeVerifier
= CodeVerifier Base64.Encoder


{-| An opaque type representing a code challenge. Typically constructed from a `CodeVerifier`.
let codeChallenge = mkCodeChallenge codeVerifier
-}
type CodeChallenge
= CodeChallenge Base64.Encoder


{-| Construct a code verifier from a byte sequence generated from a **high quality randomness** source (i.e. cryptographic).
Ideally, the byte sequence _should be_ 32 or 64 bytes, and it _must be_ at least 32 bytes and at most 90 bytes.
Expand Down Expand Up @@ -360,22 +370,23 @@ defaultAuthorizationErrorParser =

{-| Request configuration for an AuthorizationCode authentication
- credentials:
- credentials (_REQUIRED_):
Only the clientId is required. Specify a secret if a Basic OAuth
is required by the resource provider.
- code:
- code (_REQUIRED_):
Authorization code from the authorization result
- codeVerifier:
- codeVerifier (_REQUIRED_):
The code verifier proving you are the rightful recipient of the
access token.
- url:
- url (_REQUIRED_):
Token endpoint of the resource provider
- redirectUri:
Redirect Uri to your webserver.
- redirectUri (_REQUIRED_):
Redirect Uri to your webserver used in the authorization step, provided
here for verification.
-}
type alias Authentication =
Expand Down
18 changes: 9 additions & 9 deletions src/OAuth/ClientCredentials.elm
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,20 @@ import Url.Builder as Builder

{-| Request configuration for a ClientCredentials authentication
let authentication =
-- Credentials needed for Basic authentication
{ credentials =
-- Token endpoint of the resource provider
, url = "<token-endpoint>"
-- Scopes requested, can be empty
, scope = ["read:whatever"]
}
- credentials (_REQUIRED_):
Credentials needed for `Basic` authentication.
- url (_REQUIRED_):
The token endpoint to contact the authorization server.
- scope (_OPTIONAL_):
The scope of the access request.
-}
type alias Authentication =
{ credentials : Credentials
, scope : List String
, url : Url
, scope : List String
}


Expand Down
43 changes: 39 additions & 4 deletions src/OAuth/Implicit.elm
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,24 @@ support the issuance of refresh tokens) and is optimized for public clients know
particular redirection URI. These clients are typically implemented in a browser using a
scripting language such as JavaScript.
This is a 2-step process:
- The client asks for an authorization and implicit authentication to the OAuth provider: the user is redirected.
- The provider redirects the user back and the client parses the request query parameters from the url.
+---------+ +--------+
| |---(A)- Auth Redirection ------>| |
| | | Auth |
| Browser | | Server |
| | | |
| |<--(B)- Redirection Callback ---| |
+---------+ w/ Access Token +--------+
^ |
| |
(A) (B)
| |
| v
+---------+
| |
| Elm App |
| |
| |
+---------+
After those steps, the client owns a `Token` that can be used to authorize any subsequent
request.
Expand Down Expand Up @@ -42,6 +56,27 @@ import Url.Parser.Query as Query


{-| Request configuration for an authorization
- clientId (_REQUIRED_):
The client identifier issues by the authorization server via an off-band mechanism.
- url (_REQUIRED_):
The authorization endpoint to contact the authorization server.
- redirectUri (_OPTIONAL_):
After completing its interaction with the resource owner, the authorization
server directs the resource owner's user-agent back to the client via this
URL. May be already defined on the authorization server itself.
- scope (_OPTIONAL_):
The scope of the access request.
- state (_RECOMMENDED_):
An opaque value used by the client to maintain state between the request
and callback. The authorization server includes this value when redirecting
the user-agent back to the client. The parameter SHOULD be used for preventing
cross-site request forgery.
-}
type alias Authorization =
{ clientId : String
Expand Down
31 changes: 17 additions & 14 deletions src/OAuth/Password.elm
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,29 @@ import Url.Builder as Builder

{-| Request configuration for a Password authentication
let authentication =
-- Optional, unless required by the resource provider
{ credentials = credentials
-- Resource owner's password
, password = "<user-password>"
-- Scopes requested, can be empty
, scope = ["read:whatever"]
-- Token endpoint of the resource provider
, url = "<token-endpoint>"
-- Resource owner's username
, username = "<user-username>"
}
- credentials (_RECOMMENDED_):
Credentials needed for `Basic` authentication, if needed by the
authorization server.
- url (_REQUIRED_):
The token endpoint to contact the authorization server.
- scope (_OPTIONAL_):
The scope of the access request.
- password (_REQUIRED_):
Resource owner's password
- username (_REQUIRED_):
Resource owner's username
-}
type alias Authentication =
{ credentials : Maybe Credentials
, password : String
, scope : List String
, url : Url
, scope : List String
, username : String
, password : String
}


Expand Down
26 changes: 14 additions & 12 deletions src/OAuth/Refresh.elm
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,25 @@ import Url.Builder as Builder

{-| Request configuration for a Refresh authentication
let authentication =
-- Optional, unless required by the resource provider
{ credentials = Nothing
-- Scopes requested, can be empty
, scope = ["read:whatever"]
-- A refresh token previously delivered
, token = OAuth.Bearer "abcdef1234567890"
-- Token endpoint of the resource provider
, url = "<token-endpoint>"
}
- credentials (_RECOMMENDED_):
Credentials needed for `Basic` authentication, if needed by the
authorization server.
- url (_REQUIRED_):
The token endpoint to contact the authorization server.
- scope (_OPTIONAL_):
The scope of the access request.
- token (_REQUIRED_):
Token endpoint of the resource provider
-}
type alias Authentication =
{ credentials : Maybe Credentials
, token : Token
, scope : List String
, url : Url
, scope : List String
, token : Token
}


Expand Down

0 comments on commit 6199c78

Please sign in to comment.