https://www.mutuallyhuman.com/blog/2013/05/09/choosing-an-sso-strategy-saml-vs-oauth2/
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
http://cakebaker.42dh.com/2008/04/01/openid-versus-oauth-from-the-users-perspective/
https://auth0.com/blog/cookies-vs-tokens-definitive-guide/
Process
- Client request URL from Resource Server (service provider server)
- Resurce server redirect user to Authorization Server (IdP) with SAML Authnrequest
- IdP after validating the request, present user with a login form and allow user login with username and password
- IdP generates a SAML token (SAML Assertion, the formal name) and redirect the user back to the Service Provider (Resource Server). The token include user id information such as email, username etc.
- Service provider verifies the token and extract the information, logs in the user.
Limitation
- uses HTTP Redirect or HTTP Post in step 4 (concept of binding), both has limitations
- showing the standard's age (2005, where HTTP POST is the only form existed at that time to send the token back)
- does not support app - where app can be launched with a url (on iOS - registering a custom URI scheme)
- work around: embedded web views, proxy server, ignore specification's recommendation and use redirection
Out in late 2012. At high level the flow is similar to SAML.
OAuth Roles:
- Resource Owner: user who authorizes an application to access their account, limited to the "scope" of authorization (Joe)
- Client: the application (Photo editor) that wants to access user's account, after authorized by the user & validated by the API
- browser based web app, mobile app, desktop app, server-side app, etc.
- Service or API role:
- Resource Server (Google Drive): hosts the protected user resources
- Authorization Server (Google Federated Id): verifies user id and issues access tokens to the application
Abstract Protocol Flow (only to show the ideas, not actual flow)
- Client (the application) requests authorization from user (Resource Owner)
- If user authorized, application receives an Authorization Grant
- Application requests an Access Token from the Authorization Server (API) by presenting authentication of its own ID (Application's ID) and the Authorization Grant
- Authorization Server (API)issues an Access Token
- Application requests resource from Resource Server (API) and presents the Access Token
- Resource Server (API) serves the resource
So,
- Authorization Grant: authorization of access of scope of user resources to an application
- Access Token: obtained by the Application server after authenticating itself and providing the Authorization Grant
Actual flow will differ depending on the Authorization Grant type. Before all these can happen, application must do Application Registration with the authorization service:
- Provides
- Application Name
- Application Website
- Redirect URI or Callback URL
- Obtains Client Credentials
- client identifier - public string used to id the application
- client secret - to authenticate the application, must keep secret between application and API
Authorization Grant types depends on the application's method to request authorization and the grant types supported by the API. OAuth2 defines 4 types
- Authorization Code: with server-side applications
- application redirect user-agent (browser)
- receive API authorization codes that are routed through user-agent
- most commonly used, optimized for server side applications (because server can protect client secret)
- user agent (browser) only get authorization code (when being redirected), give that code to server (via URL), and server request ACCESS TOKEN
- steps
- user agent is redirected to authorization server's end point with client id (application id), redirect_uri (where to redirect user after authorization), response_type (specify application is requesting an authorization code grant) and scope (specifies level of access being requested such as read, write, etc.)
- authorization server authenticates the user (if not already logged in) and prompts user to authorize or deny the access
- if granted, service redirects user agent back to application redirect URI with parameter "?code=AUTHORIZATION_CODE"
- application (on server) then request ACCESS TOKEN from an end point with (example)
- client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
- response is the ACCESS TOKEN
- Implicit: with mobile apps or web applications
- applications run on user's device
- cannot keep client secret
- access token is given to the user-agent, so may be exposed & breached
- does not authenticate ID of application (redirect URI serve as protection)
- does not support refresh tokens
- Steps:
- just like "authorization code" but request TOKEN not CODE
- just like "authorization code"
- if success user is redirected with #token=ACCESS_TOKEN (fragment, not query)
- user agent follow redirect URL but retain the token (because it's a fragment not query)
- server send back a page with a script to extract the ACCESS_TOKEN
- user agent (browser) execute that code and extracts the ACCESS_TOKEN
- Resource Owner Password Credentials: with trusted applications, such as those owned by the service itself
- user provides username and password directly to the application, and the application uses it to obtain an access token
- should only be enabled if other flows not viable, and the application is trusted
- Client credentials: with the Applications API access
- application sends its credentials (client id + secret) to authorization server and obtain the access token
- (so, without user involved)
Token Refresh : if a refresh token is issued with the original access token, client (application) can use the refresh token to request a new access token (when doing so need to id itself again)
OAuth is about authorization (grant access of resources to an application). Open ID is about authentication (prove user who he or she is). OAuth can use OpenID for authentication.
Scenario of Open ID:
- User wants to access his account on example.com
- example.com (the “Relying Party” in OpenID lingo) asks the user for his OpenID
- User enters his OpenID
- example.com redirects the user to his OpenID provider
- User authenticates himself to the OpenID provider
- OpenID provider redirects the user back to example.com
- example.com allows the user to access his account
Open ID just share user identification related details (photo, id, email etc.) but not authorizing access to user resources. While OAuth authorize access to user resources but does not specify how user be authenticated.
How token works
- Each request to server is accompanied by a signed token which the server verifies before responding. If not verified, 401 Unauthorized
- JSON Web Token (JWT) defines a compact and self-contained method for securely transmitting JSON between parties
- the compact size allow token as query strings, header attributes or within POST body
- self-contained means server need not to go back to database because all needed information is there
- stateless - token contains all information it needs for authentication & server need not to store session state
- can be generated from anywhere - generation is decoupled from verification
- find-grained access control - can specify user roles, permissions and accessible resources
JWT
- format: header.payload(claims).signature
- header - BASE64 encoded
- type of token
- hashing algorithm (for signature)
- claims payload
- reserved claims (predefined): iss (issuer) exp (expiration time) sub(subject) aud (audience)
- public claims (defined in IANA JWT registry):
- private claims -custom claims
- signature - protect integrity, not encrypted (jwt.io)
- can be signed using a secret (HMAC) or public/private key pair (RSA)
- content signed include header and payload
- scenario
- client obtain a token from server after logs in - token generated and signed by server
- contains possibly the user id
- client send the token with every request, verified by server
- typically in "Authorization" header using Bearer schema, like "Authorization: Bearer <token>"
- server extract information from the token
- best practice
- keep signing key private
- don't send sensitive data - not encrpted
- give tokens an expiration
- use https
- consider all use cases - sometimes needs a secondary token verification
Why token (over cookie)
- token based authentication goes well with Single Page Application frameworks
- stateless, salable and decoupled
- with cookie (stateful)
- server needs to store session and cookie contains the id
- server needs to lookup session in every request
- with token (stateless)
- server does not keep record of which users are logged in or which JWT has been issued
- server does not lookup session for anything already in token
- Cross Domain (CORS)
- cookie does not work well when crossing different domains
- since issue and verification of tokens are decoupled, token work well in cross domain scenario
- Any data can be stored in token (but still keep it compact)
- Mobile ready
- token are much easier for mobile apps (iOS/Android) andfor IoT
Common questions and concerns to tokens
- Size - JWT is (much) larger than cookie
- Storage
- commonly in browsers local storage
- recommended to prevent XSRF
- sandboxed to specific domain (not accessible to other including sub domains)
- in browser session store
- cleared as soon as closes browser
- in cookie
- XSS & XSRF protection
- XSS - cross site scripting
- when: outside code may execute within your website or app
- solution:
- use framework that automatically sanitize inputs and prevent arbitrary code execution
- use plugins such as Google caja
- XSRF - cross site request forgery
- when: using JWT in cookie (if with local storage not an issue)
- how: see https://en.wikipedia.org/wiki/Cross-site_request_forgery
- solution: server generate a unique token and anytime data is submitted to server, hidden input field will contain that token for check by server
- protection:
- have short expiration time for tokens
- maintain a blacklist of compromised tokens
- nuclear approach - change signing algorithm to invalidate all tokens in event of severe breach
- Encrypted token
- JWT NOT encrypted
- If must send sensitive data, use JSON Web Encryption (JWE)