Author: Daniel Passos (dpassos@redhat.com, daniel@passos.me)
Level: Intermediate
Technologies: Java, Android, RHMAP, SAML
Summary: A demonstration of how to integrate with the FeedHenry SAML PoC
Community Project : Feed Henry
Target Product: RedHat Mobile Application Platform aka RHMAP
Product Versions: RHMAP 3.8.0+
Source: https://github.com/feedhenry-templates/pushstarter-android-app
Prerequisites: fh-android-sdk : 3.0.+, Android Studio : 1.4.0 or newer, Android SDK : 22+ or newer
This application will subscribe to a push service running in a RHMAP instance. The user can send messages to the device using RHMAP and view them on the device.
If you do not have access to a RHMAP instance, you can sign up for a free instance at https://openshift.feedhenry.com/.
You can import this project as a client app inside of RHMAP Studio. First you will need to create a project based on the "SAML Example Project" template. In this project you will add a new client app by importing an existing app. Select "Native Android" as your app type and import from this git repository.
If you wish to contribute to this template, the following information may be helpful; otherwise, RHMAP and its build facilities are the preferred solution.
- Edit
app/src/main/assets/fhconfig.properties
to include the relevant information from RHMAP. - Attach running Android Device with API 16+ running
- ./gradlew installDebug
This project will use the device's native ID and negotiate a SAML session with the remote server. The SAML related logic can be viewed in app/src/main/java/org/feedhenry/saml/SAMLActivity.java
In order to log in with SAML, the application retrieve's a SSO URL from the cloud application. This URL is loaded in a webview which negotiates the SAML session between the IdP and the cloud application.
The relevant block of code may be found in app/src/main/java/org/feedhenry/saml/SAMLActivity.java
public void retrieveSSOUrl() {
displayLoading();
try {
JSONObject params = new JSONObject();
params.put(TOKEN, Device.getDeviceId(getApplicationContext()));
FHCloudRequest request = FH.buildCloudRequest(
"sso/session/login_host", "POST", null, params);
request.executeAsync(new FHActCallback() {
@Override
public void success(FHResponse res) {
Log.d(TAG, "FHCloudRequest (login_host) - success");
String ssoStringURL = res.getJson().getString("sso");
Log.d(TAG, "SSO URL = " + ssoStringURL);
SAMLActivity.this.displayWebView(ssoStringURL);
}
@Override
public void fail(FHResponse res) {
Log.d(TAG, "FHCloudRequest (login_host) - fail");
Log.e(TAG, res.getErrorMessage(), res.getError());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
After the user is logged in with SAML, the SAML identity will be associated with the device's ID. In the cloud app the "sso/session/valid" endpoint returns the user information of the current logged in user.
public void retrieveUserData() {
displayLoading();
try {
JSONObject params = new JSONObject();
params.put(TOKEN, Device.getDeviceId(getApplicationContext()));
FHCloudRequest request = FH.buildCloudRequest(
"sso/session/valid", "POST", null, params);
request.executeAsync(new FHActCallback() {
@Override
public void success(FHResponse res) {
Log.d(TAG, "FHCloudRequest (valid) - success");
User user = new User();
user.setFirstName(res.getJson().getString("first_name"));
user.setLastName(res.getJson().getString("last_name"));
user.setEmail(res.getJson().getString("email"));
user.setExpires(res.getJson().getString("expires"));
Log.d(TAG, user.toString());
SAMLActivity.this.displayUserData(user);
}
@Override
public void fail(FHResponse res) {
Log.d(TAG, "FHCloudRequest (valid) - fail");
Log.e(TAG, res.getErrorMessage(), res.getError());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}