The current state-of-the-art of web is that service providers expose their services as web accessible application programming interfaces (APIs) for users to build applications or consume services. One of the key aspects of designing an API platform is controlling who has access to data. Ideally, an API platform should be capable of allowing different levels of user access strategies where authorized consumers may get unlimited access to secure APIs while non-authorized consumers can only access APIs that are public. From the API platform perspective, granting access to different levels of consumers must be made as easy as possible [1]. Most web applications access user data to provide application-specific functionality to the user. For example, applications may need to access users’ Facebook friends. However, requesting user credentials to access Facebook API from a third-party application poses a security risk to the user. As a result, many organizations provide different authorization strategies to access their APIs on behalf of the user. This has created a major requirement for a common global standard for securing APIs. This is where OAuth stands out among other standards.
What is OAuth?
OAuth is an open standard for authorization and provides a method for clients to access server resources on behalf of a resource owner, such as a different client or an end-user. It also provides a process for end-users to authorize third-party access to their server resources without sharing their credentials, typically a username and password pair, using user-agent redirections [2]. In OAuth, the client requests access to resources controlled by the resource owner and hosted by the resource server by giving a different set of credentials (not the resource owner’s credentials) to access the resource. In OAuth, the client will obtain an access token from the authorization server, which can be used to access server resources on behalf of the resource owner. In this method, resource owner credentials will not be exposed to third-party application. This article will use OAuth 2.0 [3] standard terms to describe OAuth functionality.
Basic terms Roles
There are four types of roles specified in OAuth2:
- Resource owner: An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user
- Resource server: The server hosting the protected resources (e.g. Google hosting your profile and personal information). The resource server will respond to the requests with an access token for the protected resource
- Client: The application requesting access to a resource server on behalf of the resource owner and with its authorization (client can be your PHP website, a Javascript application, or a mobile application)
- Authorization server: The server issuing the access token to the client after successful authentication with the resource owner. This token will be used for the client to request the resource server
Tokens are random strings generated by the authorization server after successful authentication with the resource owner, which will be used by clients to request resources from the resource server to obtain authorization for the particular resource. There are two types of tokens:
Access token: This is the more important of the two tokens as it protects the user data from being accessed by a third-party application. This token will be sent by the client to the protected resource in the resource server as a header or parameter in the request. It has a limited lifetime, which is defined by the authorization server. It must be kept as confidential as possible, but this will not always be possible where the client is a web browser that sends requests to the resource server via Javascript [4].
Refresh token: This token is issued with the access token, but unlike the latter, it is not sent in each request from the client to the resource server. The function of the refresh token is to obtain another access token when the current access token expires after its lifetime. It will not always be possible for the client to obtain the refresh token from the authorization server. We will describe the refresh token action with OAuth grant types.
Register as a client
Before the client retrieves data from a resource server using OAuth2, the client needs to register in the authorization server. During the client registration, the client will specify application name, redirection URI to receive authorization code and access token, and several other parameters. Note that there are two types of clients: confidential clients and public clients. After successful registration, confidential clients will receive client credentials that include the credentials listed below:
Client ID: A unique string representing registration information provided by the client
Client secret: A secret key that must be kept confidential, and which the client can use to get the access token from the authorization server
OAuth2 flow
The abstract OAuth 2.0 flow illustrated in Figure 1 describes the interaction between the four roles.
Figure 1: OAuth2 flow
As shown in Figure 1, the client first requests authorization from the resource owner using one of four major grant types or a grant type extension. The authorization grant type depends on the method used by the client to request authorization and the types supported by the authorization server. After the client receives the authorization grant, the client requests an access token from the authorization server presenting the authorization grant. The authorization server then validates the authorization grant and issues the access token for the client. After completing this step, the client can request access for the protected resource in the resource server by presenting the access token. This highlights the basic flow of obtaining access for the protected source by a client.
Authorization grant types An authorization grant type is a credential representing the resource owner's authorization (to access its protected resources) used by the client to obtain an access token [3]. There are four major grant types available in the OAuth2 specification. The client can use any grant type depending on the scope of the application.
Authorization code grant
Applications
This grant type can be used when the client is a web server. With this grant, the client can have lifetime access to the protected resources with the use of a refresh token. Security implications
Token request The authorization code is obtained by using an authorization server as an intermediary between the client and resource owner. Instead of requesting authorization directly from the resource owner, the client directs the resource owner to an authorization server, which in turn directs the resource owner back to the client with the authorization code. Right before the authorization server redirects to the client with the authorization code, the resource owner needs to authenticate with the authorization server. Since the resource owner directly interacts with the authorization server, resource owner credentials won’t be shared with the client. There are some benefits with the use of this grant, such as the ability to authenticate the client as well as transmission of the access token directly to the client without passing it through the resource owner's user-agent and potentially exposing it to others, including the resource owner [3]. Using this grant, access token is not visible to the client as it is stored in the client session. Figure 2 shows the authorization grant flow. Using this grant, the client will receive a refresh token that can be used to obtain a new access token when the current token expires. A refresh token is issued because this grant type is bound to the confidential client type.
Figure 2: Authorization code grant flow
Scenario
Take a scenario where some webapp is required by the client to view your Twitter profile. In this scenario, you are the Resource Owner. Similarly, the authorization server and resource server will be the servers from Twitter. A website wants to obtain information about your Twitter profile You are redirected by the client (the webapp) to Twitter’s authorization server If you authorize access, the authorization server sends an authorization code to the client (the webapp) in the callback response Then, this code is exchanged with an access token between the client and the authorization server The webapp will access your data from Twitter's APIs with the access token Security implications Redirect URL bases attacks are possible with this grant type, hence redirect URI needs to be properly validated.
Resource owner credentials grant
Applications
The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application [3]. Moreover, this grant type is more suitable for clients who are capable of getting the resource owner’s username and password via a form or other way without violating the resource owner’s security. It is mainly used when the client has been developed by the same authority as the authorization server [4].
Access token request
During this grant, the resource owner provides his username and password to the client, which then the client uses to request an access token from the authorization server with the client’s credentials. The authorization server responds to the client after successful authentication with the access token and the refresh token. Since the client type is confidential, a refresh token is issued from the authorization server. Figure 3 shows the flow of this grant.
Figure 3: Resource owner credentials grant flow
Scenario
This grant can be used when the client connects to the same authority as in the authorization server. Think of a scenario where you have an account on foo.com and where you are the resource owner. foo.com exposes its services for external users via service.foo.com, which is the resource server. The client is the foo.com website and authorization server will be foo.com’s server. In this scenario, the client of foo.com uses the services exposed by foo.com for build application. In this scenario, both foo.com and service.foo.com are trusted by the client. Therefore, there is a risk of providing the resource owner’s username and password to access APIs. Foo company exposes its APIs via RESTful interface for users to create third-party applications Users of this company need an access token to call the services of its own API Application developers will ask to enter your credentials via a form The server-side application (website foo.com) will exchange your credentials against an access token from the authorization server This application then uses the access token to query its own resource server (service.foo.com)
Client credentials grant
Applications
This grant is applicable when the client itself is the resource owner. This grant is used to obtain the access token by giving only the client credentials without having resource owner authentication. This grant can also be used in server to server authentication and to access APIs without the need for end-user permissions, such as application developers.
Token request
The client will request the access token from the authorization server presenting client credentials. With this grant, the resource owner’s authentication is not needed. This grant type can only be used with confidential clients. Figure 4 shows the flow of obtaining the access token using this grant. A refresh token will not be issued by the authorization server with this grant.
Figure 4: Client credentials grant flow
Scenario Let’s say company foo has SDK to develop applications with their APIs for application developers. The resource owner is you as the application developer. Since you are not a end-user, you do not want to authenticate with foo to obtain the access token to build your applications. In this scenario, the client will be the SDK [5]. You as the application developer (Resource Owner) download the foo SDK from their website You will register the SDK (Client) as an app in foo’s website and get a client_id and client_secret When building the application using SDK, the application developer can request an access token from foo’s authorization server by presenting client_id and client_secret Foo’s authorization server will respond with the access token after validating client credentials, which the application developer can use to call foo’s APIs
Implicit grant
Applications
The implicit grant type is used to obtain access tokens and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript [3].
Token request
Implicit grant is based on redirection based flow. As a result, the client should be capable of interacting with the resource owner user agent (such as the browser) to obtain the token from the redirection URI coming from the authorization server. The implicit grant type does not require client authentication, and relies on the presence of the resource owner and the registration of the redirection URI. The resource owner needs to authenticate with the authorization server to obtain the access token. Because the access token is encoded into the redirection URI, it may be exposed to the resource owner and other applications residing in the same device [3]. The client requests for the access token with the client ID and grant type with optional parameters as in Figure 5. Figure 5 describes the complete flow of the implicit grant. Since the resource owner authenticates directly with the authorization server, his/her credentials will not be shared with the client. With this grant, the refresh token will not be issued for the client as the client type is public.
Figure 5: Implicit grant flow
Scenario
Think of there is a JavaScript (JS) application without any server-side implementation, which requires access of your Twitter profile data. The client will be the JS application and the authorization server will be Twitter’s authorization server. You as resource owner will need to grant access to your profile data from Twitter’s resource server.
- JS application needs to access your Twitter profile data
- JS application then sends a request to Twitter’s authorization server presenting the client_id to obtain access of your profile data
- Twitter’s authorization server then asks for resource owner authentication to respond with the access token in redirection URI
- After successful resource owner authentication, the authorization server responds with the access token as a URI fragment in redirect URI as https://yourapplication..com/mydata?access_token=8d1c93acf1ce504ebaf75213e455f62&expires_in=3600
- Then the client can obtain the access token from the URI fragment to access your profile data
Implicit grant type is the least secure grant type among other grant types. Because the token is expose to the client side application, it can be stolen by an attacker. Another dangerous security risk is that the client is not aware if the particular token is generated for him/her or another client. Therefore, an attacker can gain access to protected resources. Figure 6 shows a particular way of stealing a user token by an attacker. Let’s say website A allows users to login via Twitter. The same way, the attacker will create a website called website B, which allows users to login via Twitter as well. When a user logs in to the attacker’s fake website, the attacker will grab the access token from the URI fragment. Now, the access token can be used to login to access user data through website A by
manipulating the access token in website A.
Figure 6: Implicit grant token manipulation
These kind of attacks can be avoided by having proper token validation in the client side’s application. If the authorization server can provide details, such as which client_id belongs to a particular token, then the client can refuse requests that do not match with the access token and the client ID.
Why is implicit grant important?
Implicit grant type is most important for JavaScript-based applications that are not capable of keeping client secrets secure in their end. Using implicit grant, the client only requires the client_id to access protected data on behalf of the resource owner. The access token will reside on the resource owner user agent which is the browser. With the authorization code, the client will get a refresh token, which automatically allows the client to access protected resources for a lifetime. Authorize code grant permits trusted users to access protected resources until the session expires in the web server. If the session has expired, no one will be able to get access to the access token with the authorized code grant. However, when there is no web server, there will be no way to invalidate the access token until it expires. If there is no web server, the access token will be available on the Internet, which is unsecure. But by using implicit grant, we can reduce the expired time of the access token to reduce unauthorized access to protected web resources.
Implicit grant demo
This demo shows the function of implicit grant in a javascript application. We use WSO2 API Manager as the OAuth2 provider for the demo. WSO2 API Manager supports all four grant types described in the OAuth2 specification. Let’s say you as the resource owner, needs to grant access of your purchase items in an electronic shopping site to a third-party application. We have used a dummy backend API, which provides purchase goods of a user that is protected using OAuth2 with WSO2 API Manager. We have provided a step-by-step description below. We assume that you are familiar with adding APIs and subscribing to them from the API Manager store via applications. It might be useful to become familiar with WSO2 API Manager [7] first.
- The user will register to API Manager and add an application and subscribe to the backend service, which will provide the user’s purchase goods. Figure 7 shows the view of adding a new application from API Manager. Note that callback URI is important for the implicit grant type where the authorization server will redirect the access token for the URI specified in the application.
Figure 7: Add new application
- Then the user can generate client_id and a secret from the application subscription view. Note that the consumer key and consumer secret is known as client_id and client_secret. Implicit grant only requires the consumer_id(client_id) to get the access token.
Figure 8: Application Subscription view
- My sample application contains a simple interface that requires resource owner access to view the purchase goods as in Figure 9.
Figure 9: Sample interface
- You as the resource owner needs to grant permission to access data via clicking the Access Data button. At this moment, the application sends the authorization request to the API Manager authorization endpoint with the client_id. As implicit grant specifies, the resource owner needs to authenticate with the authorization server to provide an access token. WSO2 API Manager uses WSO2 IS backend as the authorization endpoint. Therefore, you will direct to WSO2 IS login interface as in Figure 10.
Figure 10: Login Interface
- After successful login you will need to provide access to the third-party application to access your data through the interface in Figure 11.
- After successful authorization, the application will receive the access token in the redirected URI fragment to access protected resources. My sample application will take the access token from the URI fragment and show the data of the user as in Figure 11. As you can see in Figure 11, the access token is in the URL as a fragment with the token expiry time.
Figure 12: Resource owner data
References
- http://www.landofshattereddreams.com/blog/2014/03/17/adventures-in-oauth2/
- http://en.wikipedia.org/wiki/OAuth http://tools.ietf.org/html/rfc6749
- http://www.bubblecode.net/en/2013/03/10/understanding-oauth2/
- http://soasecurity.org/2013/12/02/client-credential-grant-type-with-oauth-2-0/
- http://stackoverflow.com/questions/7522831/what-is-the-purpose-of-the-implicit-grant-authorization-type-in-oauth-2
- https://docs.wso2.com/display/AM170/WSO2+API+Manager+Documentation
No comments:
Post a Comment