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.
Asgardeo Android OIDC SDK is a library that can be used to secure any Android application. This android library currently supports:
- Prerequisite
- Getting started
- Integrating OIDC SDK to your Android application
- Authentication SPI
- Contributing
- License
Install Android SDK Platform 29 or below. https://developer.android.com/studio/releases/platforms#10
You can experience the capabilities of Asgardeo Android OIDC SDK by following this small guide which contains main sections listed below.
-
Start the WSO2 IS.
-
Access WSO2 IS management console from https://localhost:9443/carbon/ and create a service provider.
i. Navigate to the
Service Providers
tab listed under theIdentity
section in the management console and clickAdd
.
ii. Provide a name for the Service Provider (ex:- sample-app) and clickRegister
. Now you will be redirected to theEdit Service Provider
page.
iii. Expand theInbound Authentication Configuration
section and clickConfigure
under theOAuth/OpenID Connect Configuration
section.
iv. Provide the following values for the respective fields and clickUpdate
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. -
Once the service provider is saved, you will be redirected to the
Service Provider Details
page. Here, expand theInbound Authentication Configuration
section and click theOAuth/OpenID Connect Configuration
section. Copy the value ofOAuth Client Key
shown here.
- Register to Asgardeo and create an organization if you don't already have one.
- 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.
-
Clone this project by running
git clone https://github.com/asgardeo/asgardeo-android-oidc-sdk.git
. -
Open the cloned project directory via Android Studio.
-
Add the relevant configs in oidc_config.json file located in
res/raw
folder.- Replace the value of
client-id
with the value ofOAuth Client Key
property which you copied in the step 3 when configuring the Identity Server. - Update the
{HOST_NAME}:{PORT
} with the IS server'shostname
andport
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" }
- Replace the value of
-
Add
mavenLocal()
underrepositories
andallProjects
in thebuild.gradle
file (Thisbuild.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() }
-
Run the following commands to build the project.
./gradlew clean assembleRelease
./gradlew publishToMavenLocal
-
Create a suitable Android Virtual Device in the Android Studio.
-
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 -
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.
-
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.2keytool -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. -
Select the Virtual Device to run the application.
-
Run the the module
io.asgardeo.android.oidc.sdk.sample
on the selected Virtual Device.
-
Enable USB Debugging in the Developer Options in the Android Device. Refer documentation on Run your App.
-
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 underhostname
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. -
Connect the Android Device to the machine through a USB cable.
-
Select the Android Device as the Deployment Target.
-
Run the the module
io.asgardeo.android.oidc.sdk.sample
on the selected Android Device.
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.
The structure of a sample Android application would be as follows:
Throughout this section we will refer to the Identity Server installation directory as IS_HOME.
- 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'
}
-
Add a redirect scheme in the Android application. You need to add the
appAuthRedirectScheme
in thebuild.gradle
file of your Android application.
This should be consistent with theCallBack Url
of the Service Provider that you configured in the WSO2 Identity Server and in theoidc_config.json
file. Refer the configuration section for further information.For example, if you have configured the callBackUrl as
wso2sample://oauth2
, then theappAuthRedirectScheme
should bewso2sample
android.defaultConfig.manifestPlaceholders = [ 'appAuthRedirectScheme': 'wso2sample' ]
-
Create the
oidc_config.json
file with the following configuration inside theres/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" }
- 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 itLoginActivity
. - 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);
-
Add a
button
insideLoginActivity
. Here the button id is referred aslogin
. -
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); }
-
The
doLogin()
method will be called when thelogin button
is clicked to initiate authentication with WSO2 Identity Server. -
You need to create
completionIntent
andcancelIntent
while calling theauthorize
method ofLoginService
. -
You can pass either
true
orfalse
for thecallUserInfo
parameter. IfcallUserInfo
value istrue
, thenuserinfo request
will be made to the IdentityServer after successful token exchange. Else, ifcallUserInfo
value isfalse
, SDK will not make any request to UserInfo Endpoint after token flow.Now you will be able to authenticate the user with Identity Server.
-
-
After successful authentication,
AuthenticationContext
object will be returned in the Intent. ThisAuthenticationContext
object is used to store all the context related to that authentication flow. -
From the
onCreate()
method of theUserInfoActivity
, get theAuthenticationContext
object. -
Authentication context object has
User
,OidcDiscovery response
,TokenResponse
, andUserInfoResponse
.
@Override
protected void create() {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_info);
mLoginService = new DefaultLoginService(this);
mAuthenticationContext = (AuthenticationContext) getIntent().getSerializableExtra("context");
}
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();
-
To get information related to token response, first you need to get
OAuth2TokenResponse
fromAuthenticationContext
. 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();
-
To get information from idToken , first you need to get
IDTokenResponse
fromOAuth2TokenResponse
. 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)
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
fromAuthenticationContext
,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();
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();
}
}
-
Create a button with id logout
LoginActivity
. -
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(); }
Please read Contributing to the Code Base for details on our code of conduct, and the process for submitting pull requests to us.
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.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.