Intro
OAuth 2.0 is not backward compatible with 1.0. Do not use 1.0.
Ref: https://www.youtube.com/watch?v=996OiexHze0
https://www.oauth.com/
MUST READS: https://oauth.net/2/oauth-best-practice/
-> https://tools.ietf.org/html/draft-ietf-oauth-security-topics-16
https://oauth.net/2/browser-based-apps/
-> https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-07
Internet logins began with the standard "form login": username and password home-grown login on
a website that stashed session info in a cookie after successful login. The website and owner are
responsible for:
1. Security: Have to be aware of best practices and how they change over time
2. Maintenance: Testing auth system over time
OAuth and Open ID Connect are industry best practices at the time of writing to overcome the above
disadvantages.
Pre mobile era commonly identity use cases included
1. Simple login (forms and cookies)
2. Single Sign On (SSO) using a protocol called (SAML)
Now, post 2010, two more use cases arise:
1. Mobile app login
2. Delegated authentication.
The client should never get the resource owner's password. This is because the password is generally
the "keys to the kingdom". For example, an app that wants to share a post on my facebook page. If I
give it my FB password it can share the post, but it can also get my friends list, send them messages,
block them, make other unauthoized posts and critically access ANY other service which I access using
my FB credentials!
So, I must avoid giving any third party my password. This is where OAuth comes in.
DELEGATED AUTHENTICATION is where you allow a 3rd party access to your data/platform, probably in
a restricted manner, WITHOUT giving the 3rd party you password.
Example of the "good old bad old days" were websites that asked for you email account password
so that they could send invite emails to your friends. This was GIVING AWAY THE KEYS TO THE
CASTLE! E.g. your bank password reset flow probably goes back there!!
What we want to do is say "Email provider, I authorize ABC.com to send emails on my behalf from
my account, as long as you authenticate them when they try to do this". This is delegated
authentication, and is what OAuth came out of. So ABC can send emails from my account, but,
importantly wouldn't be authorized to read my emails, for example, or add/delete contacts etc.
ABC says login to your email account -> Redirect me to email account. I trust my email provider
more than ABC so I am happy(er) to log into my email provider. The email provider then
authenticates me (makes sure its me and not Stevil). It then should warn me about the permissions
that ABC is seeking. If I say its OK it should then accept the instruction that it
should authorise ABC to send emails. It then returns a token to ABC, which ABC can then use
in requests to send emails that it sends to my email provider.
DELEGATED AUTHENTICATION is also known as IDENTITY FEDERATION:
Identity Federation is the process of delegating an individual’s or entity’s authentication
responsibility to a trusted external party. Each partner in federation plays the role of either
an identity provider(IdP) or a service provider(SP). In identity federation, an IdP vouches for
the identity of the users, and an SP provides services to the users.
(https://dinika-15.medium.com/identity-federation-a-brief-introduction-f2f823f8795a)
Summary
-------
From Udemy Course https://www.udemy.com/course/learn-oauth-2:
The OAuth standard ensures that there is no unintended leakage of information about the resource owner
to the app. The app may access only specific resources with the explicit consent of the resource owner.
The app does not get the resource owner's credentials, which would be wildcard access to all of the user's
data. By protecting the resource owner's data, especially the personal and profile data of the resource
owner, the OAuth standard can be used to ensure the privacy of the resource owner.
Nomenclature
------------
- Resource Owner - You - The person who owns the data that the application wants access to. e.g. You
own your email resource - see above example.
- Client - Just refers to the application that wants access to your data.
- Authorization Server - System the resource owner uses to authorize the client - to say "yes".
- Resource Server - API that holds the data that the client wants to get to. Sometimes resource
server and auth server are same but oftentimes they are seperate.
- Authorization Grant - The "thing" that prooves that the resource owner has consented to a certain
level of client access to the resource. This authorization grant allows the client to go
back to the resource server and get the access token. The authorization code is exchanged for
the access token.
- Redirect URI - When auth server redirects back to the client application it redirects to the
redirect URI
- Access Token - The client needs an access token - the key they use to get into the data resource
owner granted access to.
See also https://www.youtube.com/watch?v=BNEoKexlmA4:
The access token is like the electronic RFID key card for a hotel room. You sign in at the front
desk, which is where you validate using your credentials, and once you have the key you only
need to present that to get into your room (the resource).
- Scope - The subset of permissions that the access token gives the client
Auth server will have a list of scopes it understands, e.g. contacts.read. Any types of
permissions that make sense for the particular resource being accessed.
E.g. Google scopes tend to be really long URL strings.
- Back Channel - Highly secure channel. API req or HTTP req from my server to Google over HTTPS
SSL/TLS encrypted - this is a back channel. From my backend server to another system. We
completely trust our server and code.
- Front Channel - Less secure than back channel.
E.g. Browser requested website. They can see my JS/HTML code or someone could look over my
shoulder and see my password as I type it in. We don't completely trust the browser.
Why Exchange Access Code For Access Token - Why The Extra Step?
---------------------------------------------------------------
Why do we get a code rather than the token right away? The reason for the extra step is to take
advantage of the "best things about the front channel and the best things about the back chanell".
The authorisation code is returned to the browser, i.e., over the front end channel. You can
see the code openly in the redirect URL.
This code is then given to the client backend, which then gets the actual access token using this
code over the more secure backend channel. That is why there is the second step so that the thing
that really grants the client access to a resource is only ever communicated over the more secure
and thus more trusted channel.
One Downside To OAuth
---------------------
One downside to OAuth is that the login page can be easily "spoofed". Thus it is up to the user
to figure out whether the login page they are redirected to is genuine, e.g. by examining the
page address. But this can be harder/impossible if the login is embedded in another page.
From RFC6749 (The OAuth 2.0 Authorization Framework), section 9:
An embedded user-agent poses a security challenge because resource
owners are authenticating in an unidentified window without access
to the visual protections found in most external user-agents. An
embedded user-agent educates end-users to trust unidentified
requests for authentication (making phishing attacks easier to
execute).
And also in section 10.11 (Phishing Attacks):
Wide deployment of this and similar protocols may cause end-users to
become inured to the practice of being redirected to websites where
they are asked to enter their passwords. If end-users are not
careful to verify the authenticity of these websites before entering
their credentials, it will be possible for attackers to exploit this
practice to steal resource owners' passwords.
Service providers should attempt to educate end-users about the risks
phishing attacks pose and should provide mechanisms that make it easy
for end-users to confirm the authenticity of their sites. Client
developers should consider the security implications of how they
interact with the user-agent (e.g., external, embedded), and the
ability of the end-user to verify the authenticity of the
authorization server.
For an introduction to some of the VULNERABILITIES common in OAuth implementations see
https://portswigger.net/web-security/oauth
Flow In Brief
-------------
App wants to access my FB account
* It asks the OAuth server for a token
* OAuth asks me (the resource owner) if I want to give permission for a SUBSET of operations on
my resource (FB account)
* I authorize by giving my user name and password to the OAuth servier
OAuth servier validates this information either itself or by asking another third party
(OAuth server and resource sever can be seperate)
* Token is sent back to the app (client)
Thus the client never sees our password. It only gets a "passport" or "permissions slip"
that it can give to FB to access a SUBSET of the services that I can access on FB - only
those services I want the client to access
* Client asks the resource server for access to a service and gives token to resource server.
Resource server doesn't know anything about the token.
It contacts the Oauth server, gives it the token, and asks "is this token valid?".
OAuth server looks it up - is it still active? has it been revoked? etc etc
Tells the resource server whether it is valid or not, and WHAT TYPE OF ACCESS
WAS GRANTED.
* If token valid resource server gives client access to the requested service.
OAuth is used for DELEGATION and not authorization or authentication. It is the resource server that does
the authorization as to what resources can be accessed based on the OAuth token presented. Authentication
is done by the external component such as the login page - OAuth server triggers authentication but does
not do it itself. Thus everything is delegated.
SEE the RFC here: https://tools.ietf.org/html/rfc6749
The following is an annotated version of the abstract protocol flow from the RFC:
Authentication v.s. Authorization
---------------------------------
Authorization == WHAT you can do
Authentication == WHO you are
How To Prevent Oauth Authentication Vulnerabilities
From https://portswigger.net/web-security/oauth/preventing:
For OAuth client applications
1. Make sure you fully understand the details of how OAuth works before implementing it. Many
vulnerabilities are caused by a simple lack of understanding of what exactly is happening at
each stage and how this can potentially be exploited.
2. Use the state parameter even though it is not mandatory.
The state parameter should ideally contain an unguessable value, such as the hash of
something tied to the user's session when it first initiates the OAuth flow. This value is
then passed back and forth between the client application and the OAuth service as a form of
CSRF token for the client application.
3. Send a redirect_uri parameter not only to the /authorization endpoint, but also to the /token
endpoint.
4. When developing mobile or native desktop OAuth client applications, it is often not possible
to keep the client_secret private. In these situations, the PKCE (RFC7638) mechanism may be
used to provide additional protection against access code interception or leakage.
5. If you use the OpenID Connect id_token, make sure it is properly validated according to the
JSON Web Signature, JSON Web Encryption, and OpenID specifications.
6. Be careful with authorization codes - they may be leaked via Referer headers when external
images, scripts, or CSS content is loaded. It is also important to not include them in the
dynamically generated JavaScript files as they may be executed from external domains via
<script> tags.
Actors
Actor #1: OAuth Provider
OAuth server has 3 components:
Authentication component
Login page etc. Identity provider Oauth is the front end of the IAM
Consent component
Get consent for the delegation of access rights to the client
User is logged in. This page says "do you really want to provide this subset
to the app
Token management infra structure
Basically the token DB
The OAuth server generally provides 2 enpoints: their function is standard but the URL
need not be.
1. Authorization endpoint
/authorize [GET]
For "auth code grant" gives AUTHORIZATION CODE
For "implicit grant" gives ACCESS TOKEN
2. Token endpoint
/token [POST]
It is a protected enpoint so requires the client ID and secret, that would
have been delivered to the client via the autorize process. Uses HTTP BASIC
protection.
Produces an ACCESS TOKEN and a REFRESH TOKEN for "auth code grant", "client
credentials grant", "resource owner credentials grant".
Actor #2: Resource Provider (Server)
Makes a protected resource available over HTTPS. Often via a RESTful API which ensures only allowed
clents can access the data (access token), which it does via the OAuth token.
Provides the resources owned by the resource owner, that are requested by the client (3rd party)
using the access tokens provided by the Oauth provider.
Provides the resource EP
Actor #3: Resource Owner
Owner of the protected resource. S/he can access their data directly. Wih OAuth the resource owner
is giving a client permissions to indirectly access their data via the OAuth authentication mechanism
(owner delegates his access rights, or a subset of them, to the client) and can specify restricted
access to the protected resource, i.e., only allow access to a subset of the resource or restrict the
things that can be done with or to that resource.
Actor #4: Client
Third party tring to access protected resources of the resource owner. E.g. an app trying to access
my FB page etc.
The OAuth server will provide the client with an ID and a secret by which the client can then
identify itself.
Client provides the redirect EP.
Clients come in two types:
1. CONFIDENTIAL - Client can securely store client credentials or is capable of secure
client authentication using other means.
2. PUBLIC - Incapable of maintaining the confidentiality of their credentials. E.g. client
app in web browser, and incapable of secure client authentication via any other means.
A component can have the role of several actors. Eg Words with friends wants access to my FB friends list.
"Words with friends" is the client. I am the resource owner, FB is both the resource provider and the
OAuth provider.
Another example. I want to login to PrintMyPhotos.com. FB is the OAuth provider. PrintMyPhotos.com is
both the client. But who is the resource owner? It is PrintMyPhotos.com... in this case the OAuth
provider is just authenticating that I am who I say I am. The protected resource is the photos stored
on PrintMyPhotos.com.
End Points
1. Authorization EP (OAuth server): The authorization endpoint is used to interact with the
resource owner and obtain an authorization grant.
Verify identity of resource owner.
Because requests to the authorization endpoint result in user authentication and the
transmission of clear-text credentials (in the HTTP response), the authorization server MUST
require the use of TLS.
2. Token EP (OAuth server): Used by the client to obtain an access token by presenting its
authorization grant or refresh token.
3. Redirect EP (Client)
4. Resource EP(s) (Resource server)
Tokens
CAUTION WITH OAUTH TOKENS: Tokens grant access but do NOT verify who the user is! So, if Bob has access
to Alice's token, he will be able to access everything Alice can, whether or not Alice has given him
permission or not (imagine Bob somehow stole the token, for example!).
Thus it is important to keep any kind of token CONFIDENTIAL!
This means USE TLS EXCLUSIVELY for any token transmission
Access Tokens (AT):
Used by client to access resources. AT valididty is time limited. Stored and sent
by the client. Sent to resource server generally.
The holder of the token has the access rights associated with the token BUT the token
holder is not authenticated after the initial issue, so tokens must be kept
confidential!
Refresh Token (RT):
Time limited validity, longer than AT validity. Used to request new AT after AT expired.
When RT used the credentials of the resource owner do NOT have to be checked again.
Stored and sent by the client. Never sent to the resource server, only to OAuth server.
Thus, only used to refresh ATs and never used to actually access resources themselves.
Authorization Code (AC):
Send by auth server to client after authenticating the resource owner (i.e. getting
the consent of the resource owner for delegating the access). The AC is just a code
that represents the authentication and consent of the resource owner that the client
should be able to access the resource. It is not, the AT! At AC validity is normally
only valid for a couple of minutes. The AC can then be used to get an AT!
Client Registration
When new client wants access to resources. OAuth server needs some information about the client and
returns, in exchange, a client ID and a client secret.
When new client is registered, must provide
1. Redirect URI
2. Required scopes (what type/subset of resource is going to be used)
Dynamic client registration protocol: https://tools.ietf.org/html/rfc7591
Explanation taken from https://ldapwiki.com/wiki/OAuth%202.0%20Client%20Registration:
OAuth Clients must register with the Authorization Server before any transactions
may occur. Before an OAuth Client can request access to Protected Resource on a
Resource Server, the OAuth Client must first register with the Authorization Server
associated with the Resource Server.
OAuth 2.0 Client Registration is typically a one-time task. Once registered, the
registration remains valid, unless the OAuth Client registration is revoked.
At OAuth 2.0 Client Registration the OAuth Client is assigned a Client_id and a
Client Secret (password) by the Authorization Server.
The Client_id and Client Secret is unique to the OAuth Client on that Authorization Server.
If a OAuth Client registers with multiple Authorization Servers (e.g. both Facebook, Twitter
and Google), each Authorization Server will probably issue a different and unique Client ID
to the OAuth Client application.
Whenever the OAuth Client requests access to resources stored on that same Resource Server,
the OAuth Client needs to Authenticate itself by sending the Client ID and the Client Secret
to the Authorization Server.
During the registration the OAuth Client also registers a redirect_uri. This redirect_uri is
used when a Resource Owner grants Authorization to the OAuth Client. When a Resource Owner
has successfully Authorized the OAuth Client via the Authorization Server, the Resource Owner
is redirected back to the OAuth Client's redirect_uri.
OAuth 2.0 Client Registration must be done outside of the The OAuth 2.0 Authorization
Framework.
Flows Overview
OAuth Flows Overview
--------------------
From RFC:
To request an access token, the client obtains authorization from the
resource owner. The authorization is expressed in the form of an
authorization grant, which the client uses to request the access
token.
1. Authorizaton Grant Flow
A.k.a. "three-legged ouath"
Most secure flow
Client must be able to securley store client ID/secret and tokens
2. Implicit Grant Flow
*** WARNING - IT IS NOT LONGER RECOMMENDED TO USE THIS FLOW - SEE PKCE ***
*** WARNING - DO NOT USE ANYMORE! ***
Used when client can NOT securley store client ID/secret or OAuth tokens
E.g. When client written in client side JavaScript
Cons: Short validity of tokens and refreshing AT very difficult
3. Client Credential Flow
A.k.a "two-legged OAuth"
Used when client is also the resource owner
Uses ONLY the /token EP
4. Resource Owner Password Credentials Flow
When resource owner can entrust password to client
5 ** SEE PKCE ** - Authorization Grange Flow WITH PKCE as a replacement for the implicit grant flow.
For a really good guide on choosing which flow to use see:
https://auth0.com/docs/authorization/which-oauth-2-0-flow-should-i-use
Authorization Grant Flow
Checks the identity of the 3 involved actors (why its called "3-legged"). The authorization code
grant type is used to obtain both access tokens and refresh tokens and is optimized for
confidential clients.
From RFC:
The authorization code grant type is used to obtain both access
tokens and refresh tokens and is optimized for confidential clients.
Since this is a redirection-based flow, the client must be capable of
interacting with the resource owner’s user-agent (typically a web
browser) and capable of receiving incoming requests (via redirection)
from the authorization server.
OAuth server authenticates the resource owner using his/her username/password that
are provided interactively via the login mechanism that the OAuth server provides.
OAuth server authenticates the client using its client ID and secret.
Identity of the Auth server is checked by its certificate.
Flow should only be used when CLIENT PROVIDES SECURE STORAGE FOR ID, SECRET AND
TOKENS!
Resource ------------> OAuth <----------- Resource -----------> Resources
Owner <------------ Server -----------> Server <----------/
| ^
/ \ |
/auth /token |
^ ^ |
| | |
v v |
Client <---------------+
Advantages:
Relatively high security level
AT does NOT flow through browser
Username/pwd of resource owner not known to client
Convenience - Use of RT allows access for longer periods of time without
requiring re-authentication
Identities of all 3 participants is ensured
Refresh tokens
--------------
Quicker renewal of AT than having to go through entire auth flow again...
The refresh token lasts for longer than the access token (AT). Refresh token (RT) used to get a new
access token and refresh tokens with new TTL. The AT has a TTL. The RT does not have an explicit
TTL, it is just set, by the system, to some time (much) longer than the AT with the assumption the client
uses it as soon as needed.
Only the /token EP is required and the authentication of the resource owner is not needed.
Implicit Grant Flow
*** WARNING THIS SHOULD NOT BE USED ANYMROE - SEE SECTION PKCE ***
*** From best practices RFC:
*** The implicit grant (response type "token") and other response types causing the authorization
*** server to issue access tokens in the authorization response are vulnerable to access token
*** leakage and access token replay ...
*** In order to avoid these issues, Clients SHOULD NOT use the implicit grant and any other
*** response type causing the authorization server to issue an access token in the authorization
*** response.
*** SEE https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926
From the RFC:
The implicit grant is a simplified authorization code flow optimized
for clients implemented in a browser ...
... In the implicit flow, instead of issuing the client
an authorization code, the client is issued an access token directly
(as the result of the resource owner authorization). The grant type
is implicit, as no intermediate credentials (such as an authorization
code) are issued (and later used to obtain an access token).
...
...
The implicit grant type does not include client authentication, and
relies on the presence of the resource owner and the registration of
the redirection URI. Because the access token is encoded into the
redirection URI, it may be exposed to the resource owner and other
applications residing on the same device.
Used for clients that cannot securely store the client ID and client secret as well as the refresh
token: no refresh tokens are issued in this flow.
Use case is mainly client side JavaScript applications but also native apps as its relatively easy
to pull the app secret out of the binary.
From https://www.oauth.com/oauth2-servers/oauth-native-apps/:
Like browser-based apps, native apps can’t maintain a confidential client secret after the
developer registers one, as that would require that the developer ship the secret in their
binary distribution of the application. It has been proven to be relatively easy to decompile
and extract the secret. As such, native apps must use an OAuth flow that does not require a
secret.
Does not used /token EP.
/auth EP gives the access token directly - dont need the token EP - but no refresh token.
The access tokens have a SHORT VALIDITY time. This is because the client has not been
authenticated and a short validity period tries to hedge against the danger this introduces.
Thus implicit grant has a REDUCED LEVEL OF SECURITY COMPARED TO THE AUTHORIZATION GRANT from
the previous section.
The OAuth RFC talks about the AT being dropped in the redirect because it is part of the URL
fragment. This appears to now be out of date as redirects of this nature can propogate the
fragment (bit after the # in the URL) through the redirect.
See: https://trac.ietf.org/trac/httpbis/ticket/6
https://stackoverflow.com/a/2305927/1517244
Further explanation about the insecurity of the access token and why it can't be refreshed
was excellently explained at:
https://www.scottbrady91.com/OpenID-Connect/Silent-Refresh-Refreshing-Access-Tokens-when-using-the-Implicit-Flow:
When using the implicit authentication flow refresh tokens cannot be requested or used, since
the client application cannot be explicitly or securely authenticated and therefore cannot be
trusted with such a sensitive token. This also applies to any flow on a public client incapable
of keeping a secret or making secure back channel requests. If a refresh token intended for a
such a client was stolen, the thief could use it to request access tokens for that user, without
their knowledge or consent.
When using a client application running in the browser ... we expect the user to be present at
the client application. They might be currently in a different tab ... but the session is still
active. This means that if their access token expires, they should still be around to authorize
another to be issued. ...
So, I wondered, how to web apps keep users signed in if they are not permitted to use refresh
tokens? The answer was also given in the above article by Scott Brady.
Silent refresh uses the assumption that the user is still logged into the OpenID Provider to
automatically make another OpenID Connect authorization request and receive new tokens. This is
done behind the scenes without interrupting the user experience.
This request is typically made in an iFrame, too small for the user to see, with the request
looking very similar to the authorization request that the client application made to initially
authenticate the user, albeit with a few tweaks.
Interestingly from here: https://auth0.com/docs/authorization/which-oauth-2-0-flow-should-i-use
If the Client is a Single-Page App (SPA), an application running in a browser using a scripting
language like JavaScript, there are two grant options: the Authorization Code Flow with Proof
Key for Code Exchange (PKCE) and the Implicit Flow with Form Post. For most cases, we recommend
using the Authorization Code Flow with PKCE because the Access Token is not exposed on the
client side, and this flow can return Refresh Tokens.
Redirects For Apps
See: https://www.oauth.com/oauth2-servers/redirect-uris/redirect-uris-native-apps/
^^^
The authorization endpoint normally redirects the user back to the client’s registered redirect URL.
Depending on the platform, native apps can either claim a URL pattern, or register a custom URL
scheme that will launch the application. For example, an iOS application may register a custom
protocol such as myapp:// and then use a redirect_uri of myapp://callback.
Book Of Face!
SEE: https://developers.facebook.com/
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
Register app at developers.facebook.com
Things to record:
1. App ID (a.k.a. Client ID)
2. App SECRECT (do not expose this to anyone!!)
Things to enter:
1. Redirect URI. Note FB auto puts a slash at the end for you and the URI you send in your
request must match the one FB has stored, so you must send it with a terminating slash.
When you send the URI you will, of course, URL ENCODE it because it will be a parameter
of your request.
The following is an AUTHORIZATION GRANT FLOW emulation as the secret app key is "stored securely"
by us at the command line (in fact to be super secure you read it in at command line so it wont
even be stored in the bash history - or just regenerate a secret after playing).
Auth EP
Seems at time of writing its v10: https://www.facebook.com/v10.0/dialog/oauth?client_id={app-id}
&redirect_uri={redirect-uri}
&state={state-param}
You will use your URL encoded redirect URI you entered when registering you app for
{redirect-uri} and state, as we've learnt, can be any data you like.
When your redirect URL is called it will have "code" as a URL parameter. This should be
stored - it is the AUTH CODE.
To test, visit that link in your browser... the browser will show the FB login and auth
then redirect back to your redirect URI, from which you can extract the AUTH CODE.
Token EP
The AUTH CODE must be exchanged for the ACCESS TOKEN.
From FB Docs: To get an access token, make an HTTP GET request to the following OAuth endpoint:
GET https://graph.facebook.com/v10.0/oauth/access_token?
client_id={app-id}
&redirect_uri={redirect-uri}
&client_secret={app-secret}
&code={code-parameter}
This is a little no standard as it is a GET not a POST.
NOTE: This is non-standard: it is a GET instead of a POST.
Can do with CURL to SIMULATE USING THE BACK CHANNEL:
curl -ik "https://graph.facebook.com/10.0/oauth/access_token?...." (see above link template)
-i, --include
Include the HTTP response headers in the output. The HTTP response headers can include
things like server name, cookies, date of the document, HTTP version and more...
To view the request headers, consider the -v, --verbose option.
-k, --insecure
(TLS) By default, every SSL connection curl makes is verified to be secure. This
option allows curl to proceed and operate even for server connections otherwise
considered insecure.
The server connection is verified by making sure the server's certificate contains the
right name and verifies successfully using the cert store.
The response will look like:
{"access_token":"... very long string ...","token_type":"bearer","expires_in":5183057}
Notice there is no refresh token.
** NOTE IMPLICIT GRANT FLOW NO LONGER RECOMMENDED!! **
To do AN IMPLICIT GRANT FLOW note that the FB auth EP (https://www.facebook.com/v10.0/dialog/oauth)
has the following optional parameter:
* response_type. Determines whether the response data included when the redirect back to the
app occurs is in URL parameters or fragments.
* code. Response data is included as URL parameters and contains code parameter (an encrypted
string unique to each login request). This is the default behavior if this parameter
is not specified. It's most useful when your server will be handling the token.
* token. Response data is included as a URL fragment and contains an access token. Desktop
apps must use this setting for response_type. This is most useful when the client
will be handling the token.
^^
Set this to "token".
For the token EP, if it requires, as is standard, a POST request, you can change the curl command
to:
curl -ik -X POST https://the/token/endpoint/address \
-d grant_type=authorization_code \
-d code={auth code as returned by auth server} \
-d redirect_uri=... \
-d client_id=... \
-d client_secret=....
Proof Key For Code Exchange By Oauth Public Clients
SEE: https://tools.ietf.org/html/rfc7636
QUOTE: OAuth 2.0 [RFC6749] public clients are susceptible to the
authorization code interception attack.
In this attack, the attacker intercepts the authorization code [WHAT you can do]
returned from the authorization endpoint within a communication path
not protected by Transport Layer Security (TLS), such as inter-
application communication within the client's operating system.
Once the attacker has gained access to the authorization code, it can
use it to obtain the access token.
So why is it problematic that the authz code is intercepted? This just says WHAT the owner of the
token is allowed to do. It is not the authentication token (the app secret) which verifies WHO
the app is. It's problematic for flows that do not use the authentication EP - I.e. do not have an
app secret to act as the authentication mechanism.
SEE ALSO: https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce
https://developer.okta.com/blog/2019/08/22/okta-authjs-pkce#:~:text=PKCE%20works%20by%20having%20the,is%20called%20the%20Code%20Challenge
https://medium.com/identity-beyond-borders/what-the-heck-is-pkce-40662e801a76
Terms:
------
CODE VERIFIER: A random value generated by the app. (RFC describes it as a "a dynamically
created cryptographically random key"). A UNIQUE code verifier must be used for
every authorization request.
CODE CHALLENGE: A hash of the code verifier.
Openid Connect
OpenID Connect supersedes and obsoletes OpenId 2.0 * OpenId 1.0/
From https://portswigger.net/web-security/oauth/openid:
OpenID Connect extends the OAuth protocol to provide a dedicated identity and authentication
layer that sits on top of the basic OAuth implementation. It adds some simple functionality that
enables better support for the authentication use case of OAuth.
...
OpenID Connect .. [adds] standardized, identity-related features to make authentication via OAuth
work in a more reliable and uniform way.
SEE SPEC: https://openid.net/specs/openid-connect-core-1_0.html
The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be
Authenticated is the ID Token data structure. The ID Token is a security token that contains
Claims about the Authentication of an End-User by an Authorization Server when using a Client,
and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT).
For JWT see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-json-web-token.
From nice big-picures tutorial: https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc
OAuth 2.0 is designed only for authorization, for granting access to data and features from one
application to another. OpenID Connect (OIDC) is a thin layer that sits on top of OAuth 2.0 that
adds login and profile information about the person who is logged in. Establishing a login
session is often referred to as authentication, and information about the person logged in
(i.e. the Resource Owner) is called identity. When an Authorization Server supports OIDC, it is
sometimes called an identity provider, since it provides information about the Resource Owner
back to the Client.
Oauth And Jwt
https://stackoverflow.com/a/28503265
https://www.loginradius.com/blog/engineering/using-jwt-with-oauth2-when-and-why/