OAuth 2.0


Intro

 

Notes on OAuth API authentication.

 


Documentation

 


Learning Resources

 

 


Tips And Notes

 

  • OAuth or OAuth 2 are synonymous with each other.  OAuth 1 is not used much today.

  • OIDC or Open ID Connect are also synonymous.

  •  Authentication (AuthN = who you are) versus Authorization (AuthZ = what you can do). 

    •  OAuth is an authorization framework. It gives you a mechanism to request, receive, and apply authorization policies across resources.

  •  OpenID Connect is just a special case of OAuth.  Designed specifically for single sign on use cases, and sharing profile information.

  • Common extensions to the OAuth framework:

    • OpenID Connect,

    • JWT

    • token revocation (RFC 7009 - optional but you should treat it as mandatory),

    • token introspect (RFC 7662 - used if a token has been revoked), 

    • Dynamic Client Registration (RFC 7591, not used often in production), 

    • Authorization server metadata (RFC 8414, the OAuth discovery document,  query the authorization server itself to get list of capabilities and related end points.

  • A scope is a permission the client can request and be granted or denied. 

  •  When you're granted a set of scopes, you're issued an access token

  • The refresh token gives you a new access token once the original expires

 


OpenID Connect, or OIDC

 

  • A widely implemented and used extension because it provides for single sign-on and profile sharing.

  • OIDC adds the ID token and it must be a JWT, and specifies specific fields that are mandatory to have. 

  •  Adds a user info endpoint to retrieve user info.

 


OAuth 2 Servers For Testing

 

 


OAuth Endpoints

 

  • The Authorization endpoint (/authorize) is used to confirm user’s identity - Gets authorization grant and user consent

  • The Token (/token) endpoint where we actually get the tokens themselves.

  • The above two tokens are the only ones specified in the core framework.

  • The /introspect endpoint allows you to analyze and decode a token. 

  • The /revoke endpoint allows you to invalidate and access a refreshed token. 

  • The /userinfo endpoint from the OpenID Connect specification publishes user profile data.

  • The endpoints can be named anything the OAuth implementer chooses so use the OAuth discovery document to get the names:

    • /.well-known/oauth-authorization-server

 


Scopes Or Permissions

 

  • They provide permission to resources.

  • Must be unique strings but naming is up to the designer. 3 common patterns:

    • OpenID Connect defines a few scopes (profile, email, address, phone). 

    • There are some simple strings: read, write, delete or admin read, admin write, etc

    •  Java-style namespace format: company.resource.action (e.g. com.app.resource.read)

      • Pros: expressive, granular, predictable

      • Cons: Long and complex names

    • URL-style patterns, like API.company.com/resource.action

      • Pros: expressive, granular and predictable. URLs can be resolve to the scope’s documentation.

      • Cons: long and complex.

    • Guidelines:

      •  Be consistent in naming so developers can understand what permissions they're requesting, granting, denying, and using in any given application.

      • Avoid “admin” scopes are they are vague in what permissions they give you

 


OAuth Tokens

 

  • Tokens are not defined in the spec. Common implementations are opaque and JWT

  • Opaque tokens are unique strings used as a database key.  They are not encoded or encrypted. Only used by the authorization server as a database ID to retrieve additional information.

  • JWT contain a lot more information. Once validated, you can use <name,value> pairs, also known as claims, to grant or deny access.  

    • The specific structure and naming conventions of those claims can vary by implementation.

    • Decode it using Base-64

 


Access And Refresh Tokens

 

  • Access tokens give access to specific resources for a specific time.  Use it when making an API request. API must validate the token.

  • Refresh tokens are opaque. They are not JWTs, which means we can’t decode and verify. They can only be used with the /token end point of our authorization server.

    • The authorization server will make sure the refresh token is still active, and then issue a new access and refresh token.

    • Protect refresh tokens

 


ID Token

 

  • The ID token comes from the OpenID Connect specification, not from OAuth itself. 

    • This token always present and always a JWT.

    • It can be validated.

  •  The resulting claims in the ID token are completely dependent on which scopes the application requests.

    •  The names and structure of those claims are completely defined by the OID specification.

  •  OIDCs primary use cases are authentication and profile creation. Because we can validate the token, as long as we trust the site that issued it, we can use it log into our own system.

  • Protect ID tokens like any other profile information, following applicable laws, like GDPR.

 

 


OAuth Grant Types

 

 

In case you need to store additional details about a client that don't fit into the standard parameter set the custom data parameter comes to help:

POST /c2id/clients HTTP/1.1 Host: demo.c2id.com Content-Type: application/json Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6 { "redirect_uris" : [ "https://myapp.example.com/callback" ], "data" : { "reg_type" : "3rd-party", "approved" : true, "author_id" : 792440 } }

The data parameter permits arbitrary content packaged in a JSON object. To set it you will need the master registration token or a one-time access token with a client-reg:data scope.


Authorization Code Flow

 

  • Most secure by default.

  • Flow:

    • Navigate to a page and request to log in. 

    • Server sends you to the identity provider or an authorization server that you both trust and you perform the authentication and grant the authorizations requested. 

    • You get back an authorization code, or auth code. 

    • Application can use the auth code, the client ID and the client secret to reach the /token endpoint and get back the access and refresh tokens.

      • The client secret is effectively the application's password for the authorization server, so you have to protect it just like you'd protect a password.

 

Source: Web Security: OAuth and OpenID Connect

 

 

  • Benefits / Drawbacks:

    • App never needs the user’s credentials

    • The authorization code is a one-time use and used for only seconds.

    • User never sees or handles access or refresh tokens.

    • Can only use in scenarios where we have both a user involved and the application has a back end component. This is why it can’t be used for microservices.

    • Since we need the client secret, we can't use it for single page apps (SPAs) or mobile apps where the app itself can't keep a secret.


Authorization Code with PKCE

 

  •  An app can't keep a secret because the source code is in the hands of the user, which means they can decompile it to find any embedded credentials.

  •  OAuth extension RFC 7636 Proof Key for Code Exchange or Auth Code plus PKCE (pronounced pixie).

  • No client secret is used.

  • Flow:

    • Client app generates a code verifier which is a random URL-safe string of at least 43 characters.

    • Then generates a code challenge which is the Base64-encoded SHA256 hash of that code verifier.

    •  App sends the code challenge to the authorization server and keeps the code verifier secret. 

    • The authorization server responds with the authorization code.

    • Instead of using the client secret, the app can use the code verifer in the request to the /token endpoint. 

    • The authorization server hashes and encodes the code verifier to compare against the original code challenge sent before. Since the verifier hasn't been sent previously and they were never sent together, the server can assume the original authorized app is the one still making the requests.

 

  •  Use the AppAuth libraries from the OpenID Foundation: https://appauth.io/

  • Use when:

    • On mobile or single-page apps is in the hands of the user.

  • Drawbacks:

    •  Can't get refresh tokens because,you can't store secrets in the application

 


Implicit Flow

  • Should be considered obsolete in favor of PKCE.

  • Once you have signed in with the authentication server, your browser app captures that Access Token and uses it with whatever protected resources.

 

 

Source: Web Security: OAuth and OpenID Connect

  • The resulting token is passed back to the application via URL or similar. 

    • Is at risk for theft or misuse by the user or other application outside your control as a developer 

    • Can’t use refresh tokens

    • Makes this flow hard to secure.

  • Common use is as the front-single-sign on interface to a back-end application, which is actually using Authorization Code flow or similar behind the scenes.

  • This is currently used by Google, LinkedIn, GitHub, Facebook whenever you create a new account in another site.

  • Security considerations:

    •  The flow passes the token back to the application via a GET parameter on the URL.

    • Don't use an authorization server that allows arbitrary redirects because a hacker can take the token above and re-direct to bad site.

    • If authorization server implements CORS, you can have it return the token via POST instead of GET.

  • Google documentation for OAuth 2.0 for Client-side Web Applications

 


Resource Owner Password Flow

 

  • Easy to implement but easier to abuse.

  • You should almost never use it.

  • Flow:

    • User hits a protected site and the application requests the user’s credentials for their identity service (eg Google, LinkedIn, not for the site!).. the application uses those credentials to request a token from the authorization server.

 

 

Source: Web Security: OAuth and OpenID Connect

  • It was put in the spec as a way to bridge OAuth and legacy applications which ask for a user/password.

 

  • Drawbacks:

    • Application had access to the user’s passwords

    • Does not support refresh tokens.

  • Security Concerns

    • Captures the user's credentials in the application itself and sends them to the server behind the scenes to get that access token!

 


Client Credential Flow

 

  • Does not require a user.

  • Flow: 

    • Application needs access to a protected resource. 

    • It makes a request for authorization server using its client ID and client secret which are effectively that application's username and password. 

    • The authorization server validates those credentials and generates an access token.

Source: Web Security: OAuth and OpenID Connect

 

  • The client ID and client secret are the application's credentials, there's no user involved in this grant type

  • This is used for backend-services and microservices only.

  • Client credentials in real use: API Keys

    • APIs keys with services like Twilio, Salesforce or SendGrid. Those work effectively the same way. When your application needs to send a text message, send an email, or retrieve the latest sales figures it's not connecting as you, it's a generic account that any user or application could use.

  • Benefits of OAuth over API Keys

    • One system for backend and for users simplifies architecture/maintenance.

    • Get all the benefits of using OAuth, including rotating credentials, granular permission via scopes, and a massive ecosystem of tools.

    • Pluggable interfaces allows the system to provide additional services. 

  • Drawback:  

    • Client Credential Flow is dependent on a client secret, therefore you can't use it in a mobile app, single-page app, or any other situation where the code is running outside your control.

    • Need way to track usage and logging since there isn’t one user.

  • This the most secure grant type by far because there are no users and no auth traffic that the end user can see.

 


Device Grant

 

  • Newest grant type, finalized in August 2019 as RFC 8628. 

  • Designed specifically to handle internet-connected devices with no browser or constrained UI such as a smart appliance, game console.

    • Not used by mobile devices or the majority of IOT devices

 

 

  • Must meet these four requirements to use this type:

    • Device itself must already be connected to the internet.

    •  Device must be able to make outbound, https requests.

    • The device must be able to communicate a URI to the end user for their authentication and eventual authorization. 

    • The user has to have a device available to use the URI.

 

  • Because it is new, not a lot of OAuth servers support it and not a lot of SDK libraries have support for it.

 


Security Guidelines

  • Use secure communication - SSL/TLS

  • Validate tokens

  • Protect the auth code returned from the server - it is valid for 60 secs but it can be used to get refresh tokens.

  • The access token is retrieved via the backend, so the user and the browser never see it or can interact within it in anyway.

  • Protect the redirect URI: we provide a redirect_uri to the authorization server. This is where the authorization server sends the Auth Code after authorization is complete.  Most auth providers force you to white list redirect_uri's so the Auth server won't send the Auth Code to an arbitrary uri. 


Examples

 

Authorization Code

 

Using Postman as explained here:

https://www.linkedin.com/learning/web-security-oauth-and-openid-connect-2/build-an-example-web-app-or-postman?u=74651402

I got the following error

 

 

I had to change the Client Authentication to send in Body only

 


Authorization Code With PKCE

 

 


OAuth Guidelines

 

Recommendations for an OAuth deployment

 

  • Resource server should validate every access token it receives and respect the expiration time.  How?

    • It can do it locally but then it won’t know if a token has been revoked.

    • If you only validate it with the authorization server, via the introspect end point, you're introducing latency into your request. 

    • Depends on application: for high-security apps (like banking), validate often. For less important resources, validate less often.

  • Once token is validated, confirm it grants the authorizations that match the action requested.

  • Don’t store or log tokens.

  • Use an API gateway (apigee, mulesoft, kong, aws, azure) because it can add extra measures, like token validation and rate limiting.

 


Complete OAuth Solution

 

  • RFC 6749 - OAuth 2.0 framework

  • RFC 7519 - access tokens are JWTs

  • RFC 6750 - Pass bearer tokens in the authorization header. 

  • RFC 8628 - improve interoperability with OpenID Connect specification.

  • RFC 7516 - the JSON web encryption, or JWE specification for passing sensitive information safely. 

 

 

  • RFC 7662, or the token introspection spec to use the authorization server to check to see if a token is still valid.

  • RFC 7009 - for token revocation spec.

  • RFC 7636 to get the authorization code flow with PKCE for better support for native apps and single page apps.

  • RFC 8628 to include the device grab type, support smart appliances, kiosks, and other systems. 

  • RFC 7591 and RFC 7592 add dynamic client registration and dynamic client management.

  • RFC 8414 for the authorization server metadata specification.

 


New Extensions

 

  • SMART on FHIR. SMART on FHIR is another OAuth extension designed specifically to integrate with electronic health records or patient portals and to more easily share data between them safely.

  • Open Banking 

 


References