By Dominick Baier
Enterprise security
- Kerberos/LDAP (intranet)
- SOAP WS*, XML SAML (internet)
OAuth2 (Authorization Server)
- Request token for backend consumption
- Forward token to backend (webapi)
OpenID Connect (Authentication Server)
- Request token for client consumption
- Parse and validate token
Security Tokens
- Security tokens are (protected) data structures
- Contains information about issuer and subject (claims)
- signed (tamper proof & authenticity)
- typically contain an expiration time
- A client requests a token
- An issuer issues a token
- A resource consumes a token (has a trust relationship with the issuer)
SAML 1.1/2.0
- XML based
- many encryption & signature options
- very expressive
Simple Web Token (SWT)
- Form/URL encoded
- symmetric signatures only
JSON Web Token (JWT)
- JSON encoded
- symmetric and asymmetric signatures (HMAC-SHA256-384, ECDSA, RSA)
- symmetric and asymmetric encryption (RSA, AES/CGM)
- http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
Header: metadata, algorithms & keys used
Claims: Issuer (iss), Audience (aud), IssuedAt (iat), Expiration (exp), Subject (sub), ... application defined claims, Signature
Header.Claims.Signature
{ "typ":"JWT", "alg":"HS256" }
{ "iss":"https://myIssuer", "exp":"1340819380", "aud":"https://myResource", "sub":"alice", "client":"xyz", "scope":["read", "search"]}
http://nuget.org/packages/Microsoft.IdentityModel.Tokens.JWT
SEND: var tokenString = new JWTSecurityTokenHandler().WriteToken(new JWTSecurityToken(...))
RECEIVE: principal = new JWTSecurityTokenHandler().ValidateToken(token, validationParams);
The OAuth 2.0 Authorization Framework (October 2012 - RFC6749, RFC6750)
- Resource Server, Client, Resource Owner = User, Authorization Server
- Valet Parking Key Analogy
- Main goal is to assume the client is not trusted
Authorization Code Flow
- Resource Owner -> Web Application -> Resource Server
- 0. Client registers at authorization server
- 1a. Owner to AS: GET /authorize?client_id=webapp&scope=resource
- &redirect_uri=https://webapp/cb&response_type=code&state=123
- http://zachholman.com/2011/01/oauth_will_murder_your_children/
- 1b. Owner to client: GET /cb?code=xyz&state=123
- 2a. WebApp to AS: POST /token Authorization: Basic (client_id:secret)
- grant_type=authorization_code&authorization_code=xyz &redirect_uri=https://webapp/cb
- 2b. AS to WebApp: token response access_token and refresh_token
- 3. WebApp to Resource Server: GET /Resource
- 4. send refresh tokens
Implicit Flow
- 1a. Owner to AS: GET /authorize?client_id=webapp&scope=resource &redirect_uri=https://webapp/cb&response_type=token&state=123
- 1b. AS to Client: GET /cb#access_token=abc&expires_in=3600&state=123
- 3. GET /resource
Windows RT - WebAuthenticationBroker.AuthenticateAsync
Resource Owner Credential Flow
- For trusted applications and devices
- 1a. Client to AS: POST /token grant_type=password &scope=resource&user_name=owner&password=password
- 1b. Token response, you should store the token and refresh token, not the credentials
- Resource owner credentials are exposed to client
- User should not become accustomed to typing in credentials everywhere
Client Credential Flow
- No human involved at all
- POST /token grant_type=client_credentials&scope=resource
OAuth2 abused for authentication by getting userinfo
Client to AS: GET /authorize?client_id=nativeapp&redirect_uri=http://localhost/cb&scope=signin&response_type=token&state=123
AS to Client: GET /CB?access_token
Client to Resource server: GET /userinfo
The Problem
1. User logs into maliciousapp that steals token
2. Malicious developer uses stolen access token in legitimate app (impersonated)
So we now have to write custom code for each provider (https://OAuth.io)
OpenID Connect (on top of OAuth2)
ID Token, UserInfo endpoint, discovery & dynamic registration, session management
Identity Provider, Authorization Endpoint, Token Endpoint, UserInfo Endpoint
- 1a. user agent to ae: GET /autorize ... scope=openid profile
profile claims: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at
email claims: email, email_verified
address: address
phone: phone_number, phone_number_verified
offline_access: requests refresh token
- 1b. user agent to IP
- 2b. token endpoint will return id_token on top of access_token
Client must validate the ID token (especially the audience must be himself)
Goal is to allow a client use an arbitrary OpenId Connect provider without code modifications
Eran Hammer (OAuth2 issues)
Protocol vs Framework (over 69 choices), so you can not implement the specification cause you need to build your own protocol.
- RCF 6749 The OAuth2 Authorization Framework
- RFC 6750 OAuth2 Bearer Token Usage
- RFc 6819 Threat Model and Security Considerations
Bearer Token
A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession). -> so everything depends on the safety of the transport layer, where plenty of developers ignore ssl certificate errors. (ServicePointManager)
Security Theater (Bruce Schneier)
- Does the webview redirecting make sense?
- Wouldn't it be better to let the application handle it all?
OAuth2 attack surface everywhere
Facebook Hacks
Specifications needs some refinement (basic profile, MAC tokens, ...)
Current implementations are lacking even by the big guys, let alone the myriad of DIY implementations
Very good & balanced view
Resources