Enhancing OAuth Security for Mobile Applications with PKCE
OpenID Connect has become the leading standard for single sign-on and identity provision on the Internet. Applications often need to identify their users. The simplistic approach is to create a local database for the users' accounts and credentials. Given enough technical care this can be made to work well. People find sign up and account creation tedious, and rightly so. For enterprises with many apps, maintenance of separate user databases can easily become an administrative and security nightmare.
Google, Facebook and Twitter, where many people on the internet are registered, offer such IdP services for their users. In a enterprise, this would ideally be one internal IdP service, for employees and contractors to log into the internal applications. Centralisation has considerable benefits, such as easier administration and potentially faster development cycles for new apps. You may ask: Isn't that going to create a single point of failure?
JWTs are appreciated for their elegance and portability, and for their ready support for a wide range of signature and encryption algorithms. Based on the OAuth 2. OAuth 2. Authentication must take place at the identity provider, where the user's session or credentials will be checked. A browser popup is the preferred way for a web application to redirect the user to the IdP. Mobile apps on platforms such as Android or iOS should launch the system browser for that purpose.
Embedded web views are not be trusted, as there's nothing to prevent the app from snooping on the user password. User authentication must always occur in a trusted context that is separate from the app e.
This does away with the need to store sessions on the server side in memory or on diskwhich can be a burden to manage and scale. The session is checked by validating the ID token. Token exchange -- The ID token may be exchanged for an access token at the token endpoint of an OAuth 2. There are real world scenarios when an identity document is required to obtain access, for example when you check in at a hotel to get your room key.
We will now go through a minimal example of how to obtain an ID token for a user from an OP, using the authorisation code flow.
This is the most commonly used flow by traditional web applications. Examples of the implicit and hybrid flow can be found in the OpenID Connect spec. The RP initiates user authentication by redirecting the browser to the OAuth 2. At the OP, the user will typically be authenticated by checking if they have a valid session established by a browser cookieand in the absence of that, by prompting the user to login.
The authorisation code is an intermediate credential, which encodes the authorisation obtained at step 1. It is therefore opaque to the RP and only has meaning to the OP server. The client ID and secret are passed via the Authorization header.
Apart from HTTP basic authentication OpenID Connect also supports authentication with a JWTwhich doesn't expose the client credentials with the token request, has expiration, and thus provides stronger security.OAuth 2. Upon receiving a call, the API extracts the token, validates it checks issuer, lifetime, associated authorizations, etc and then determines whether the request should be allowed or denied. Of course, before the native application can use an access token on an API call, it must necessarily have first been issued that token.
The current reality is that there is a security risk associated with Steps above that could result in a malicious application being able to insert itself into the above flow and obtain the access token — and so be able to inappropriately access the business or personal data stored behind the API.
The risk arises due to a combination of factors. PKCE Proof Key for Code Exchange by OAuth Public Clients is an IETF draft specification designed to mitigate the above risk by preventing a malicious application, having obtained the code by scheme squatting, being able to actually exchange it for the more fundamental access token. PKCE allows the native application to create an ephemeral one-time secret and use that to authenticate to the AS on Step 8 in the above. A malicious application, even if able to steal the code, will not have this secret and so will be unable to trade the stolen code for the access token.
If using PKCE, the overall flow is identical to the above, but with additional parameters added to certain messages. The AS stores away this string before returning the code back to the native application. After installation, the native application invites the user to authenticate. The native application launches the device system browser and loads a page at the appropriate AS. In that browser window, the AS authenticates the user. The OS determines the appropriate handler, and passes the URL to the appropriate application The native application parses the URL and extracts the authorization code from the end The native application sends the authorization code back to the AS The AS validates the authorization code and returns to the native application an access token plus potentially other tokens The native application then stores that access token away in secure storage so it can be subsequently used on API calls.
The risk arises due to a combination of factors The nature of how native applications are distributed through public stores prevents individual instances of applications having unique or secret credentials.
Consequently, it is not currently practical to expect that the native application can authenticate to the AS when exchanging the code for tokens in Step 8. As a result, if a malicious application is able to get hold of the code, it will be able to exchange that code for the desired tokens.
Find sample code
In addition to mapping the raw protocol flows, convenience methods are available to assist with common tasks like performing an action with fresh tokens. For this reason, WebView is explicitly not supported due to usability and security reasons.
The library is friendly to other extensions standard or otherwise with the ability to handle additional parameters in all protocol requests and responses. A talk providing an overview of using the library for enterprise single sign-on produced by Google can be found here: Enterprise SSO with Chrome Custom Tabs. Instructions for downloading the binary releases of AppAuth, or to add a dependency using Maven, Gradle or Ivy, can be found on our Bintray page.
Browsers which provide a custom tabs implementation are preferred by the library, but not required. AS's that assume all clients are web-based or require clients to maintain confidentiality of the client secrets may not work well.
A demo app is contained within this repository. For instructions on how to build and configure this app, see the demo app readme. A sample integration with Ping Identity can be found here. AppAuth encapsulates the authorization state of the user in the net. AuthState class, and communicates with an authorization server through the use of the net. AuthorizationService class.
AuthState is designed to be easily persistable as a JSON string, using the storage mechanism of your choice e. SharedPreferencessqliteor even just in a file.
AppAuth provides data classes which are intended to model the OAuth2 specification as closely as possible; this provides the greatest flexibility in interacting with a wide variety of OAuth2 and OpenID Connect implementations.
Authorizing the user occurs via the user's web browser, and the request is described using instances of AuthorizationRequest. The request is dispatched using performAuthorizationRequest on an AuthorizationService instance, and the response an AuthorizationResponse instance will be dispatched to the activity of your choice, expressed via an Intent.
Token requests, such as obtaining a new access token using a refresh token, follow a similar pattern: TokenRequest instances are dispatched using performTokenRequest on an AuthorizationService instance, and a TokenResponse instance is returned via a callback.It strives to directly map the requests and responses of those specifications, while following the idiomatic style of the implementation language. In addition to mapping the raw protocol flows, convenience methods are available to assist with common tasks like performing an action with fresh tokens.
The library follows the best practices set out in OAuth 2. For this reason, WebView is explicitly not supported due to usability and security reasons. The library is friendly to other extensions standard or otherwise with the ability to handle additional parameters in all protocol requests and responses. When a Custom Tabs implementation is provided by a browser on the device for example by ChromeCustom Tabs are used for authorization requests.
Otherwise, the default browser is used as a fallback. AS's that assume all clients are web-based or require clients to maintain confidentiality of the client secrets may not work well. AppAuth for Android uses Gradle as its build system. In order to build the library and app binaries, run. In order to run the tests and code analysis, run. If neither of these are defined or are not the SDK you wish to use, you must create a local.
This file must define a property sdk. For example:. Select the root folder the one with the build. If you get an error like: Error:Could not find com. Follow the Android Studio prompts to resolve the dependencies automatically. AppAuth supports both manual interaction with the Authorization Server where you need to perform your own token exchanges, as well as convenience methods that perform some of this logic for you.
This example performs a manual exchange, and stores the result as an AuthState object. AuthState is a class that keeps track of the authorization and token requests and responses, and provides a convenience method to call an API with fresh tokens. This is the only object that you need to serialize to retain the authorization state of the session.
Typically, one would do this by storing the authorization state in SharedPreferences or some other persistent store private to the app:.OpenID Connect is an open standard for authentication that is supported by a number of login providers. Once you have a token, add the token to the logins map, using the URI of your provider as the key. When first integrating with Amazon Cognito, you may receive an InvalidToken exception. The iss parameter must match the key used in the logins map such as login.
The signature must be valid. The signature must be verifiable via an RSA public key. The fingerprint of the certificate hosting the public key matches what's configured on your OpenId Connect Provider. If the azp parameter is present, check this value against listed client IDs in your OpenId Connect provider. If the azp parameter is not present, check the aud parameter against listed client IDs in your OpenId Connect provider. The website jwt.
Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better. Document Conventions. Sign in with Apple.
Did this page help you? Thanks for letting us know we're doing a good job!Android Studio provides a selection of code samples and templates for you to use to accelerate your app development. Browse sample code to learn how to build different components for your applications.
Use templates to create new app modules, individual activities, or other specific Android project components. This page describes how to access and use the high-quality, Google-provided Android code samples. For information about templates, see Add Code from a Template. You can use the samples browser to select, preview, and import one or more sample apps as projects.
You can also browse the source code through GitHub. Figure 1. Browse Samples dialog with sample highlighted in the left column and previewed in the right column. The Code Sample Browser in Android Studio helps you find Android code samples based on the currently highlighted symbol in your project. Content and code samples on this page are subject to the licenses described in the Content License. Android Studio.
Download What's new User guide Preview. Meet Android Studio. Manage your project. Write your app. Build and run your app. Run apps on the emulator.
Run apps on a hardware device. Configure your build. Debug your app. Test your app. Profile your app.Google's OAuth 2. This document describes our OAuth 2. The documentation found in Using OAuth 2. If you want to explore this protocol interactively, we recommend the Google OAuth 2.
To get help on Stack Overflowtag your questions with 'google-oauth'. Before your application can use Google's OAuth 2. You can also use the API Console to create a service account, enable billing, set up filtering, and do other tasks. You need OAuth 2. To view the client ID and client secret for a given OAuth 2.
In the window that opens, choose your project and the credential you want, then click View. If there is no OAuth 2. To create one, click Create credentials. For your users, the OAuth 2. For example, when the user logs in, they might be asked to give your app access to their email address and basic account information. You request access to this information using the scope parameter, which your app includes in its authentication request. You can also use scopes to request access to other Google APIs.
The user consent screen also presents branding information such as your product name, logo, and a homepage URL. You control the branding information in the API Console. The following consent dialog shows what a user would see when a combination of OAuth 2. This generic dialog was generated using the Google OAuth 2. Google and third parties provide libraries that you can use to take care of many of the implementation details of authenticating users and gaining access to Google APIs.
Examples include Google Sign-In and the Google client librarieswhich are available for a variety of platforms. If you choose not to use a library, follow the instructions in the remainder of this document, which describes the HTTP request flows that underly the available libraries. Authenticating the user involves obtaining an ID token and validating it. ID tokens are a standardized feature of OpenID Connect designed for use in sharing identity assertions on the Internet.
The most commonly used approaches for authenticating a user and obtaining an ID token are called the "server" flow and the "implicit" flow. The server flow allows the back-end server of an application to verify the identity of the person using a browser or mobile device.
The implicit flow is significantly more complicated because of security risks in handling and using tokens on the client side. If you need to implement an implicit flow, we highly recommend using Google Sign-In.
Make sure you set up your app in the API Console to enable it to use these protocols and authenticate your users. When a user tries to log in with Google, you need to:. You must protect the security of your users by preventing request forgery attacks.
The first step is creating a unique session token that holds state between your app and the user's client. You later match this unique session token with the authentication response returned by the Google OAuth Login service to verify that the user is making the request and not a malicious attacker.
These tokens are often referred to as cross-site request forgery CSRF tokens.