Skip to content
This repository has been archived by the owner on Mar 31, 2023. It is now read-only.

OIDC Android SDK for Asgardio

License

Notifications You must be signed in to change notification settings

wso2-attic/asgardeo-android-oidc-sdk

Repository files navigation

[DEPRECATED] Asgardeo Android OIDC SDK

⚠️ Warning!

Android SDK is no longer encouraged and enriched by Asgardeo and may not work with the latest versions.

You can implement login using Authorization Code flow with PKCE with Asgardeo using OIDC standards.


Build Status Download Stackoverflow Discord License Twitter

Asgardeo Android OIDC SDK is a library that can be used to secure any Android application. This android library currently supports:

Table of Contents

Prerequisite

Install Android SDK Platform 29 or below. https://developer.android.com/studio/releases/platforms#10

Getting started

You can experience the capabilities of Asgardeo Android OIDC SDK by following this small guide which contains main sections listed below.

Configuring the Server

Configuring the Identity Server

  1. Start the WSO2 IS.

  2. Access WSO2 IS management console from https://localhost:9443/carbon/ and create a service provider. Management Console i. Navigate to the Service Providers tab listed under the Identity section in the management console and click Add.
    ii. Provide a name for the Service Provider (ex:- sample-app) and click Register. Now you will be redirected to the Edit Service Provider page.
    iii. Expand the Inbound Authentication Configuration section and click Configure under the OAuth/OpenID Connect Configuration section.
    iv. Provide the following values for the respective fields and click Update while keeping other default settings as it is.

    Callback Url - wso2sample://oauth2
    PKCE Mandatory - True
    Allow authentication without the client secret - True
    

    v. Click Update to save.

  3. Once the service provider is saved, you will be redirected to the Service Provider Details page. Here, expand the Inbound Authentication Configuration section and click the OAuth/OpenID Connect Configuration section. Copy the value of OAuth Client Key shown here. OAuth Client Credentials

Configuring the Asgardeo

  1. Register to Asgardeo and create an organization if you don't already have one.
  2. Register a Mobile Application in Asgardeo to obtain necessary keys to integrate your application with Asgardeo. You will obtain a client_ID from Asgardeo for your application which will need to embed later in your application for the integration.

Configuring the sample

  1. Clone this project by running git clone https://github.com/asgardeo/asgardeo-android-oidc-sdk.git.

  2. Open the cloned project directory via Android Studio.

  3. Add the relevant configs in oidc_config.json file located in res/raw folder.

    • Replace the value of client-id with the value of OAuth Client Key property which you copied in the step 3 when configuring the Identity Server.
    • Update the {HOST_NAME}:{PORT} with the IS server's hostname and port respectively
    {
     "client_id": {client-id},
     "redirect_uri": "wso2sample://oauth2",
     "authorization_scope": "openid",
     "discovery_uri": "https://{HOST_NAME}:{PORT}/oauth2/oidcdiscovery/.well-known/openid-configuration"
    }

    Example:

    {
     "client_id": "rs5ww91iychg9JN0DJGLMaxG2gha",
     "redirect_uri": "wso2sample://oauth2",
     "authorization_scope": "openid",
     "discovery_uri": "https://localhost:9443/oauth2/oidcdiscovery/.well-known/openid-configuration"
    }
  4. Add mavenLocal() under repositories and allProjects in the build.gradle file (This build.gradle file is the top-level build file where you can add configuration options common to all sub-projects/modules).

    repositories {
        google()
        jcenter()
        mavenLocal()
     }
    
    allProjects {
        google()
        jcenter()
        mavenLocal()
     }
    
  5. Run the following commands to build the project.

    • ./gradlew clean assembleRelease
    • ./gradlew publishToMavenLocal

Running the sample

Running in an Android Emulator

  1. Create a suitable Android Virtual Device in the Android Studio.

  2. If the WSO2 IS is hosted in the local machine, change the domain of the endpoints in the io.asgardeo.android.oidc.sdk.sample/res/raw/oidc_config.json file to “10.0.2.2”. Refer the documentation on emulator-networking

  3. By default IS uses a self-signed certificate. If you are using the default pack without changing to a CA signed certificate, follow this guide to get rid of SSL issues.

  4. Change the hostname of IS as 10.0.2.2 in the <IS_HOME>/deployment.toml.
    i. Create a new keystore with CN as localhost and SAN as 10.0.2.2

    keytool -genkey -alias wso2carbon -keyalg RSA -keystore wso2carbon.jks -keysize 2048 -ext SAN=IP:10.0.2.2
    

    ii. Export the public certificate (name it as wso2carbon.pem)to add into the truststore.

    keytool -exportcert -alias wso2carbon -keystore wso2carbon.jks -rfc -file wso2carbon.pem
    

    iii. Import the certificate in the client-truststore.jks file located in <IS_HOME>/repository/resources/security/

    keytool -import -alias wso2is -file wso2carbon.pem -keystore client-truststore.jks -storepass wso2carbon
    

    iv. Now copy this public certificate (wso2carbon.pem) into the io.asgardeo.android.oidc.sdk.sample/res/raw folder.

  5. Select the Virtual Device to run the application.

  6. Run the the module io.asgardeo.android.oidc.sdk.sample on the selected Virtual Device.

Running in an Android Device

  1. Enable USB Debugging in the Developer Options in the Android Device. Refer documentation on Run your App.

  2. If the WSO2 IS is hosted in the local machine, change the domain of the endpoints in the io.asgardeo.android.oidc.sdk.sample/res/raw/oidc_config.json file and the hostnames specified under hostname config in the <IS_HOME>/repository/conf/deployment.toml file to the IP Address of local machine. Make sure that both the Android Device and the local machine is connected to the same WIFI network.

  3. Connect the Android Device to the machine through a USB cable.

  4. Select the Android Device as the Deployment Target.

  5. Run the the module io.asgardeo.android.oidc.sdk.sample on the selected Android Device.

Integrating OIDC SDK to your Android application

This section will guide you on integrating OIDC into your Android application with the Asgardeo Android OIDC SDK. This allows an Android application (i.e. Service Provider) to connect with an IDP using OpenID protocol. This guide consist with the following sections.

Introduction

The structure of a sample Android application would be as follows:

Sample Structure

Throughout this section we will refer to the Identity Server installation directory as IS_HOME.

Installing the SDK

  1. Add latest released SDK in the build.gradle file of your Android application.
dependencies {
    implementation 'io.asgardeo.android.oidc.sdk:io.asgardeo.android.oidc.sdk:0.1.34'
}
  1. Add a redirect scheme in the Android application. You need to add the appAuthRedirectScheme in the build.gradle file of your Android application.
    This should be consistent with the CallBack Url of the Service Provider that you configured in the WSO2 Identity Server and in the oidc_config.json file. Refer the configuration section for further information.

    For example, if you have configured the callBackUrl as wso2sample://oauth2, then the appAuthRedirectScheme should be wso2sample

    android.defaultConfig.manifestPlaceholders = [
           'appAuthRedirectScheme': 'wso2sample'
    ]
  2. Create the oidc_config.json file with the following configuration inside the res/raw folder of your Android application.

    {
    "client_id": "rs5ww91iychg9JN0DJGLMaxG2gha",
     "redirect_uri": "wso2sample://oauth2",
     "authorization_scope": "openid",
     "discovery_uri": "https://localhost:9443/oauth2/oidcdiscovery/.well-known/openid-configuration"
    }

Login

  1. First, you need to initialize the SDK object in an Activity that you are using to log users into your app. For the purpose of this sample, we will call it LoginActivity.
  2. We need to create another activity which after successful authentication, the user will be redirected to. Let's name it as UserInfoActivity.
    LoginService mLoginService = new DefaultLoginService(this);
  1. Add a button inside LoginActivity. Here the button id is referred as login.

  2. We need to attach an event listener to login button to initiate the Authentication Request to WSO2 IS.

        LoginService mLoginService = new DefaultLoginService(this);
        findViewById(R.id.login).setOnClickListener(v ->
                       doLogin()
        );
    private void doLogin() {
    
          Intent completionIntent = new Intent(this, UserInfoActivity.class);
          Intent cancelIntent = new Intent(this, LoginActivity.class);
          cancelIntent.putExtra("failed", true);
          cancelIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
          PendingIntent successIntent = PendingIntent.getActivity(this, 0, completionIntent, 0);
          PendingIntent failureIntent = PendingIntent.getActivity(this, 0, cancelIntent, 0);
    
          mLoginService.authorize(successIntent, failureIntent, true);
       }
    • ThedoLogin() method will be called when the login button is clicked to initiate authentication with WSO2 Identity Server.

    • You need to create completionIntent and cancelIntent while calling the authorize method of LoginService.

    • You can pass either true or false for the callUserInfo parameter. If callUserInfo value is true, then userinfo request will be made to the IdentityServer after successful token exchange. Else, if callUserInfo value is false, SDK will not make any request to UserInfo Endpoint after token flow.

      Now you will be able to authenticate the user with Identity Server.

Authentication context.

  • After successful authentication, AuthenticationContext object will be returned in the Intent. This AuthenticationContext object is used to store all the context related to that authentication flow.

  • From the onCreate() method of the UserInfoActivity, get the AuthenticationContext object.

  • Authentication context object has User, OidcDiscovery response, TokenResponse, and UserInfoResponse.

@Override
    protected void create() {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);
        mLoginService = new DefaultLoginService(this);
        mAuthenticationContext = (AuthenticationContext) getIntent().getSerializableExtra("context");
    }

Get user details.

In order to get user-related information, we can use the following APIs.

String userName = mAuthenticationContext.getUser().getUserName();
Map<String, Object> userAttributes = mAuthenticationContext.getUser().getAttributes();

Authentication SPI

Get information related to token response

  • To get information related to token response, first you need to get OAuth2TokenResponse from AuthenticationContext. You can use the following code blocks.

    OAuth2TokenResponse oAuth2TokenResponse = mAuthenticationContext.getOAuth2TokenResponse();

  • To get AccessToken and IDToken from OAuth2TokenResponse

    String idToken = oAuth2TokenResponse.getIdToken();
    String accessToken = oAuth2TokenResponse.getAccessToken();
    Long accessTokenExpTime = oAuth2TokenResponse.getAccessTokenExpirationTime();
    String tokenType = oAuth2TokenResponse.getTokenType();
    String refreshToken = oAuth2TokenResponse.getRefreshToken();
    

Get claims from ID Token

  • To get information from idToken , first you need to get IDTokenResponse from OAuth2TokenResponse. You can use the following code blocks.

    OAuth2TokenResponse.IDTokenResponse idTokenResponse = mAuthenticationContext
                    .getOAuth2TokenResponse().getIdTokenResponse();
    
  • To get server specific claims from idToken:

    String iss = idTokenResponse.getIssuer();
    String sub = idTokenResponse.getSubject();
    String iat = idTokenResponse.getIssueTime();
    String exp = idTokenResponse.getExpiryTime();
    List<String> audience = idTokenResponse.getAudience()
    
    
  • To get the map of all claims

    Map<String, Object> claims = idTokenResponse.getClaims();

  • To get a specific String claim

    String claimValue = idTokenResponse.getClaim(claimName)

Get userinfo response

Get userinfo response from authentication context

If you called LoginService.authorize(PendingIntent successIntent, PendingIntent failureIntent , Boolean callUserInfo) with callUserInfo parameter as true, then UserInfoResponse will be stored in the AuthenticationContext object.

  • To get UserInfoResponse from AuthenticationContext,

    UserInfoResponse userInfoResponse = mAuthenticationContext.getUserInfoResponse();

  • To get the subject,

    String subject = userInfoResponse.getSubject();

  • To get some specific claim,

    String email = userInfoResponse.getUserInfoProperty("email");

  • To get all claims,

    JSONObject userClaims = userInfoResponse.getUserInfoProperties();

Call UserInfo explicitly.

You can get userclaims by calling getUserInfo(..) method in the LoginService.

private void getUserInfo(){
   mLoginService.getUserInfo(mAuthenticationContext,
                  new UserInfoRequestHandler.UserInfoResponseCallback() {
               @Override
               public void onUserInfoRequestCompleted(UserInfoResponse userInfoResponse,
                       ServerException e) {
                   if (userInfoResponse != null) {
                       mSubject = userInfoResponse.getSubject();
                       mEmail = userInfoResponse.getUserInfoProperty("email");
                       JSONObject userInfoProperties = userInfoResponse.getUserInfoProperties();
                   }
    }

Logout

  1. Create a button with id logout LoginActivity.

  2. Call the logout method when logout button is clicked.

    findViewById(R.id.logout).setOnClickListener(v -> logout());
    • Call the logout method of LoginService instance.
    private void logout() {
            mLoginService.logout(this, mAuthenticationContext);
            finish();
        }

Contributing

Please read Contributing to the Code Base for details on our code of conduct, and the process for submitting pull requests to us.

Reporting issues

We encourage you to report issues, improvements, and feature requests creating git Issues.

Important: And please be advised that security issues must be reported to security@wso2.com, not as GitHub issues, in order to reach the proper audience. We strongly advise following the WSO2 Security Vulnerability Reporting Guidelines when reporting the security issues.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.