AppAuth Android
Android client SDK for communicating with OAuth 2.0 and OpenID Connect providers.
Install / Use
npx skills add openid/AppAuth-AndroidInstalls into whichever agent you are using.
README
AppAuth for Android is a client SDK for communicating with OAuth 2.0 and OpenID Connect providers. 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
RFC 8252 - OAuth 2.0 for Native Apps,
including using
Custom Tabs
for authorization requests. For this reason,
WebView is explicitly not supported due to usability and security reasons.
The library also supports the PKCE extension to OAuth which was created to secure authorization codes in public clients when custom URI scheme redirects are used. 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.
Download
AppAuth for Android is available on MavenCentral
implementation 'net.openid:appauth:<version>'
Requirements
AppAuth supports Android API 16 (Jellybean) and above. Browsers which provide a custom tabs implementation are preferred by the library, but not required. Both Custom URI Schemes (all supported versions of Android) and App Links (Android M / API 23+) can be used with the library.
In general, AppAuth can work with any Authorization Server (AS) that supports native apps as documented in RFC 8252, either through custom URI scheme redirects, or App Links. AS's that assume all clients are web-based or require clients to maintain confidentiality of the client secrets may not work well.
Demo app
A demo app is contained within this repository. For instructions on how to build and configure this app, see the demo app readme.
Conceptual overview
AppAuth encapsulates the authorization state of the user in the net.openid.appauth.AuthState class, and communicates with an authorization server through the use of the net.openid.appauth.AuthorizationService class. AuthState is designed to be easily persistable as a JSON string, using the storage mechanism of your choice (e.g. SharedPreferences, sqlite, or 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.
Responses can be provided to the update() methods on AuthState in order to track and persist changes to the authorization state. Once in an authorized state, the performActionWithFreshTokens() method on AuthState can be used to automatically refresh access tokens as necessary before performing actions that require valid tokens.
Implementing the authorization code flow
It is recommended that native apps use the authorization code flow with a public client to gain authorization to access user data. This has the primary advantage for native clients that the authorization flow, which must occur in a browser, only needs to be performed once.
This flow is effectively composed of four stages:
- Discovering or specifying the endpoints to interact with the provider.
- Authorizing the user, via a browser, in order to obtain an authorization code.
- Exchanging the authorization code with the authorization server, to obtain a refresh token and/or ID token.
- Using access tokens derived from the refresh token to interact with a resource server for further access to user data.
At each step of the process, an AuthState instance can (optionally) be updated with the result to help with tracking the state of the flow.
Authorization service configuration
First, AppAuth must be instructed how to interact with the authorization service. This can be done either by directly creating an AuthorizationServiceConfiguration instance, or by retrieving an OpenID Connect discovery document.
Directly specifying an AuthorizationServiceConfiguration involves providing the URIs of the authorization endpoint and token endpoint, and optionally a dynamic client registration endpoint (see "Dynamic client registration" for more info):
AuthorizationServiceConfiguration serviceConfig =
new AuthorizationServiceConfiguration(
Uri.parse("https://idp.example.com/auth"), // authorization endpoint
Uri.parse("https://idp.example.com/token")); // token endpoint
Where available, using an OpenID Connect discovery document is preferable:
AuthorizationServiceConfiguration.fetchFromIssuer(
Uri.parse("https://idp.example.com"),
new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() {
public void onFetchConfigurationCompleted(
@Nullable AuthorizationServiceConfiguration serviceConfiguration,
@Nullable AuthorizationException ex) {
if (ex != null) {
Log.e(TAG, "failed to fetch configuration");
return;
}
// use serviceConfiguration as needed
}
});
This will attempt to download a discovery document from the standard location
under this base URI,
https://idp.example.com/.well-known/openid-configuration. If the discovery
document for your IDP is in some other non-standard location, you can instead
provide the full URI as follows:
AuthorizationServiceConfiguration.fetchFromUrl(
Uri.parse("https://idp.example.com/exampletenant/openid-config"),
new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() {
...
}
});
If desired, this configuration can be used to seed an AuthState instance, to persist the configuration easily:
AuthState authState = new AuthState(serviceConfig);
Obtaining an authorization code
An authorization code can now be acquired by constructing an AuthorizationRequest, using its Builder. In AppAuth, the builders for each data class accept the mandatory parameters via the builder constructor:
AuthorizationRequest.Builder authRequestBuilder =
new AuthorizationRequest.Builder(
serviceConfig, // the authorization service configuration
MY_CLIENT_ID, // the client ID, typically pre-registered and static
ResponseTypeValues.CODE, // the response_type value: we want a code
MY_REDIRECT_URI); // the redirect URI to which the auth response is sent
Other optional parameters, such as the OAuth2 scope string or OpenID Connect [login hint](http://o
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.7kCommit, push, and open a PR
