Securing REST-ful Web Services with OAuth2
Dave Syer, 2012
Twitter: @david_syer
Email: dsyer@vmware.com
Introduction
- There is a strong trend distributed systems with
lightweight architectures
- So what are people doing about security in such systems?
What is a Lightweight Service?
- HTTP transport.
- Text-based message content, usually JSON.
- Small, compact messages, and quick responses.
- REST-ful, or at least inspired by the REST
- Some degree of statelessness
- Interoperability.
What Are the Security Requirements
Identity and permissions:
- how is identity and permission information conveyed to a service?
- how is it decoded and interpreted?
- what data are needed to make the access decision (user accounts,
roles, ACLs etc.)?
- how is the data managed: who is responsible for storing and
retrieving it?
HTTP Basic Authentication
- something of a lowest common denominator
- supported on practically all servers natively and out of the box
- ubiquitous support on the client side in all languages
Example:
$ curl "https://$username:$password@myhost/resource"
So what's wrong with that?
- Nothing, but...
- Where do you get the credentials (the username and password)?
- Fine for systems where all participants can share secrets securely
- In practice that means small systems
- Only supports username/password
- Only covers authentication
User or Client Permissions
- Finer-grained information about the authenticated party
- Role-based access: very common, sometimes available in
server/container
- Need to categorize user accounts, e.g. USER and ADMIN
- Often business requirements are more complex
Identity Management: Three Corners
Identity Management: Four Corners
Centralized Identity Management
Centralized Identity Management
- Centralized: scales better than peers sharing secrets
- Peer-to-peer:
N(N-1)/2
pairs
- Centralized:
N
pairs
- For user accounts the scalability benefit is even bigger
OAuth2
Centralizing accounts and secrets is great, but what about
permissions?
- OAuth 2.0 adds an extra dimension - more information for the access
decision
- Standards always help in security
- Lightweight - easy to
curl
- Requires HTTPS for secure operation, but you can test with HTTP
Quick Introduction to OAuth2
A Client application, often web application, acts on behalf of a
User, but with the User's approval
- Authorization Server
- Resource Server
- Client application
Common examples of Authorization Servers on the internet:
Typical Web Application Client
OAuth2 and the Lightweight Service
Example command line Client:
$ curl -H "Authorization: Bearer $TOKEN" https://myhost/resource
https://myhost
is a Resource Server
TOKEN
is a Bearer Token
- it came from an Authorization Server
Role of Client Application
- Register with Authorization Server (get a
client_id
and maybe a
client_secret
)
- Do not collect user credentials
- Obtain a token (opaque) from Authorization Server
- On its own behalf -
client_credentials
- On behalf of a user
- Use it to access Resource Server
Obtaining a Client Credentials Token
A client can act in its own right (not on behalf of a user):
$ curl "https://myclient:mysecret@uaa.cloudfoundry.com"
-d grant_type=client_credentials -d client_id=myclient
Result:
{
access_token: FUYGKRWFG.jhdfgair7fylzshjg.o98q47tgh.fljgh,
expires_in: 43200,
client_id: myclient,
scope: uaa.admin
}
Web Application Client Again
The Client wants to access a Resource on behalf of the User
Obtaining a User Token
A client can act on behalf of a user (e.g. authorization_code
grant):
Authorization Code Grant Summary
Authorization Server authenticates the User
Client starts the authorization flow and obtain User's approval
Authorization Server issues an authorization code (opaque one-time
token)
Client exchanges the authorization code for an access token.
Role of Resource Server
- Extract token from request and decode it
- Make access control decision
- Scope
- Audience
- User account information (id, roles etc.)
- Client information (id, roles etc.)
- Send 403 (FORBIDDEN) if token not sufficient
Role of the Authorization Server
- Grant tokens
- Interface for users to confirm that they authorize the Client to act
on their behalf
- Authenticate users (
/authorize
)
- Authenticate clients (
/token
)
#1 and #4 are covered thoroughly by the spec; #2 and #3 not (for
good reasons).
Client Registration and Scopes
For secure channels a client has to authenticate itself to obtain a
token, so it has to be known to the Authorization Server.
Registration provides at a mimimum:
- authentication (shared secret)
- registered redirect URI (optional but essential to prevent attacks)
- allowed scopes (clients are not permitted access to all resources)
Also useful:
- a way to identify which resources can be accessed
- ownership information (which user registered the client)
More on Scopes
Per the spec they are arbitrary strings. The Authorization Server and
the Resource Servers agree on the content and meanings.
Examples:
- Google:
https://www.googleapis.com/auth/userinfo.profile
- Facebook:
email
, read_stream
, write_stream
- UAA:
cloud_controller.read
, cloud_controller.write
, scim.read
,
openid
Authorization Server has to decide whether to grant a token to a given
client and user based on the requested scope (if any).
Special Mention for Vmc
The UAA authenticates requests from vmc
in a special way:
$ curl https://uaa.cloudfoundry.com/oauth/authorize
-d response_type=token -d client_id=vmc
-d redirect_uri=https:uaa.cloudfoundry.com/redirect/vmc
-d source=credentials
-d username=$username -d password=$password
Result:
302 FOUND
...
Location: https:uaa.cloudfoundry.com/redirect/vmc#access_token=FUYGKRWFG.jhdfgair7fylzshjg.o98q47tgh.fljgh...
Authentication and the Authorization Server
- Authentication (checking user credentials) is orthogonal to
authorization (granting tokens)
- They don't have to be handled in the same component of a large
system
- Authentication is often deferred to existing systems (SSO)
- Authorization Server has to be able to authenticate the OAuth
endpoints (
/authorize
and /token
)
- It does not have to collect credentials (except for
grant_type=password
)
Cloud Foundry UAA Authorization Server
Cloud Foundry Login Server
Role of Login Server
- Authenticate users and collect user approvals for OAuth2 scopes
- Send authenticated user info in trusted channel to UAA
- Maintain SSO state (e.g. session cookie)
- Branded UI
- OAuth2 endpoints - delegate (pass through) to UAA
Cloud Foundry UAA as a General Purpose Solution
UAA OAuth Implementation
UAA makes some explicit choices where the spec allows it, and also
adds some useful features:
- Client registration validation, e.g. implicit has no secret
- Client has separate allowed scopes for user tokens and client tokens
(if allowed).
- User account management: groups = scopes, period-separated
- JWT tokens, signed but not encoded, includes audience
(a.k.a.
resource_id
)
/userinfo
endpoint for remote authentication (SSO)
- Auto-approve for client apps that are part of platform
- Special authentication channels for
/authorize
:
source=credentials
- used by vmc
source=login
- used by Login Server
- (Login Server) autologin via
code=...
UAA Resources (Endpoints)
Brief list of all the UAA endpoints (with valid scopes if it is an
OAuth2 resource):
- OAuth2 Authorization Server:
oauth/authorize
and /oauth/token
- User info endpoint (for SSO):
/userinfo
, scope openid
- Token decoding endpoint:
/check_token
- Login info endpoint (open to anyone):
/login
- SCIM user account management:
/Users
, scopes
[scim.read, scim.write]
.
- Password changes:
/Users/{id}/password
, scope password.write
UAA Resources (continued)
- Token management, e.g. cancelling an approval:
/oauth/users/{id}/tokens
and /oauth/clients/{id}/tokens
, scopes
[tokens.read, tokens.write]
- Client registration:
/oauth/clients
, scopes
[clients.read, clients.write, clients.secret]
- Password strength meter:
/password
- Management endpoints, used by the Cloud Foundry platform internally:
/health
and /varz
Alternatives to OAuth2
- OAuth 1.0a
- SAML
- Custom solution, e.g. HMAC signed requests
- Extensions to OAuth2
In Conclusion
- Lightweight services demand lightweight infrastructure
- Security is important, but should be unobtrusive
- OAuth 2.0 is a standard, and has a lot of useful features
- Spring Security OAuth aims to be a complete solution at
the framework level
- Cloud Foundry UAA adds some implementation details and makes
some concrete choices
←
→
#