Skip to content

PlusAuth/plusauth-oidc-android

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PlusAuth OpenID Connect Library for Android

MIT license Version Android Api GitHub issues Vulnerability

Android OpenId Connect library that can be used with any OIDC provider for easy to use authentication. We value developer time and effort, so we developed a dead simple zero config library that any one could easily integrate in a minute, while allowing veterans of authentication to customize everything to their needs.

Table of Contents

Requirements

PlusAuth OpenID Connect Library for Android supports Android Apis starting from 16(Jelly Bean) and above.

Installation

Add the library dependency to your build.gradle file:

implementation 'com.plusauth:android:0.1.10'

This library uses and requires Java 8 support. Check out Android Documentation to learn more.

To enable, add the following following to your build.gradle file

android {
    ...
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

OIDC Provider Configuration

To use the library you must have a OIDC provider account. In this part we will use PlusAuth as an example.

  1. Create a Plusauth account and a tenant at PlusAuth Dashboard
  2. Navigate to Clients tab and create a client of type Native Application.
  3. Go to details page of the client that you've just created and set the following fields as:
  • Redirect Uris: ${your-application-id}:/callback
  • Post Logout Redirect Uris: ${your-application-id}:/callback

Done! Note your 'Client Id' and 'domain' for library configuration later.

Configuration

The entry point of the library is the OIDC object. OIDC object can be created by using the OIDCBuilder.

OIDC oidc = new OIDCBuilder(
		context,
		"your-client-id",
		"your-oidc-domain")
    .build();

Login

By default library uses Authorization Code + PKCE flow for maximum security. Library wraps all steps of auth flow in to a single call:

oidc.login(context, new LoginRequest(), new AuthenticationCallback() {
        @Override
        public void onSuccess(Credentials credentials) {
        	runOnUiThread(()->{
            	// do ui related work
            });
        }

        @Override
        public void onFailure(AuthenticationException e) {
          Log.e("TAG", "Login failed", e);
        }

	});

OIDC will open a browser custom tab(if supported) or browser page showing them your OIDC login page and users will be returned back to the app after they complete the login.

After successful response credentials will be locally stored to skip the OIDC flow at next login. If there are valid credentials in Storage they will be returned instead, skipping OIDC exchange.

This call is asychronous and requires a callback. If you want to do ui related work in callback you must use Activity.runOnUiThread to switch back to main thread since login request is executed in a seperate thread.

Logout

Logout call is similar to login:

oidc.logout(this, new LogoutRequest(), new VoidCallback() {
    @Override
    public void onSuccess(Void aVoid) {
        runOnUiThread(()->{
            // do ui related work
        });
    }

    @Override
    public void onFailure(AuthenticationException e) {
        Log.e("TAG", "Logout failed", e);
});

OIDC will momenrarily open a browser custom tab(if supported) or page of OIDC logout page and users will be immediately returned back to the app. This clears users browser session.

After successful response credentials will be locally removed. This completes the two step logout process. If there aren't valid credentials in Storage request will fail.

If you have them, you can revoke your refresh tokens using the Revoke tokens method from Api.

This call is asychronous and requires a callback. If you want to do ui related work in callback you must use Activity.runOnUiThread to switch back to main thread since login request is executed in a seperate thread.

Api

Api class wraps common OIDC calls and provides easy to use interface. Requests can be called both asynchronously or synchronously. No arg method overloads uses provided storage instance to get required tokens.

Obtain api instance:

Api api = oidc.getApi();

If you create the api instance manually, make sure to set credentials manager so the no arg overloads can be used, otherwise you will get null pointer errors(also could occur if storage does not have credentials).

Get User Info

Get User Profile information using /userinfo endpoint:

api.userInfo().call(new PACallback<UserProfile, AuthenticationException>() {
    @Override
    public void onSuccess(UserProfile userProfile) {
        runOnUiThread(() -> {
            // do ui related work
        });
    }

    @Override
    public void onFailure(AuthenticationException e) {
        Log.e("TAG", "Could not get profile", e);
    }
});

Exchange auth token for credentials

Sends auth token to /token endpoint of the provider in exchange for credentials.

api.token("your-auth-token").call(new AuthenticationCallback() {
    @Override
    public void onSuccess(Credentials credentials) {
        runOnUiThread(() -> {
            // do ui related work
        });
    }

    @Override
    public void onFailure(AuthenticationException e) {
        Log.e("TAG", "Could exchange auth token", e);
    }
});

Renew Credential with a Refresh Token

Renew your credentials using a refresh token. Note that 'offline_access' scope is required to get a refresh refresh token at login, which is added by default.

api.renewAuth().call(new AuthenticationCallback() {
    @Override
    public void onSuccess(Credentials credentials) {
        runOnUiThread(() -> {
            // do ui related work
        });
    }

    @Override
    public void onFailure(AuthenticationException e) {
        Log.e("TAG", "Could not renew auth", e);
    }
});

Revoke a Token

Revoke a token using the revokeToken method. No arg overload only revokes the stored refresh token:

api.revokeToken().call(new VoidCallback() {
    @Override
    public void onSuccess(Void aVoid) {
        runOnUiThread(() -> {
            // do ui related work
        });
    }

    @Override
    public void onFailure(AuthenticationException e) {
        Log.e("TAG", "Could not revoke token", e);
    }
});

Advance Usage

Storage

By default library uses SharedPreferences in Private mode(can only be accessed by this application) for persistence. You are free to implement the Storage interface with your preferred storage backend.

Configure your Storage:

OIDC oidc = new OIDCBuilder(
		context,
		"your-client-id",
		"your-oidc-domain")
        .setStorage(new Storage() {
                        @Override
                        public void write(@NonNull String s, @Nullable String s1) {
                            
                        }

                        @Override
                        public void delete(@NonNull String s) {

                        }

                        @Override
                        public String read(@NonNull String s) {
                            return null;
                        }
                    })
    .build();

Encryption

By default library does not use any encryption when storing credentials. You are free to implement the Encryptor interface with your preferred encryption method. We provide AESEncryptor class for 256 bit AES GCM implementation which can be used from Android Api 23 and up.

Configure your Encryptor:

OIDC oidc = new OIDCBuilder(
		context,
		"your-client-id",
		"your-oidc-domain")
        .setEncryptor(new Encryptor() {
                        @Override
                        public String encrypt(String s) {
                            return null;
                        }

                        @Override
                        public String decrypt(String s) {
                            return null;
                        }
                    })
    .build();

Example App

We built a very simple app demonstrating login/logout and fetching user info. Check it out here.

Acknowledgements

Design of this library was inspired by awesome OSS libraries such as AppAuth.

If you have used OIDC with any Android library, you might have felt overwhelmed. We did too. That is why we built PlusAuth OIDC Library For Android. We hope to lower the entry barrier for OIDC complexity so that all developers could enjoy benefits that it brings.

License

This project is licensed under the MIT license. See the LICENSE file for more info.