Mobile Web SSO

Mobile Web SSO

Advanced Security
QualityAvailability
Download on GitHub
On this page

It used to be a common practice for companies to implement part of their mobile app by reusing existing views from a web application. The end user would navigate to a web view at a particular URL, to use that location's functionality. This prevented additional Android and iOS work, and also ensured that web-based screens were upgraded immediately for all users, when a new feature was released or a bug was fixed.

These days it is preferred to migrate web views to native views. One of the reasons for this is that single sign-on (SSO) cookies may be stored in different cookie jars for mobile and web applications. When a user navigates to the web app, they may experience a second login, even if they have only recently authenticated in the mobile app. This code example demonstrates an alternative technique for achieving web and mobile SSO.

Download Resources

The code example consists of a number of components, which provide an end-to-end solution that can be run on a standalone computer:

Components

Clone the GitHub repo from the link at the top of this page. This provides small Android and iOS apps, and a minimal single page application (SPA). Working configuration for the Curity Identity Server is also provided.

resources

Nonce Authenticator Application Flow

The security design for the code example is explained in the Nonce Authenticator Pattern article. This enables secure navigation with good usability, and no dependency on SSO cookies. The flow begins with a user signing in to either an Android or iOS application:

Android App
iOS App

The example mobile apps use the AppAuth pattern for Android and iOS, to implement OpenID Connect. The user authenticates in a secure browser window that overlays the mobile app. A pre-shipped credential of demouser / Password1 can be used in the demo setup.

Android Login
iOS Login

Next, the user is presented with options for navigating to a single page application (SPA), which uses the token handler pattern for its own OpenID Connect flow. When one of the Run SPA options is chosen, the mobile app sends its ID token to a nonce issuing endpoint and retrieves a one-time token:

Android Navigation
iOS Navigation

This nonce is then sent to the SPA as a query parameter in the load URL. The SPA can then perform an OpenID Connect authentication request with the nonce in an login_hint_token field, and with the acr_values field set to the nonce authenticator, to achieve SSO.

Android SSO
iOS SSO

Code Example Deployment

To run the end-to-end flow, first ensure that the following components are installed. Also copy a license.json file for the Curity Identity Server into the idsvr folder of the downloaded repo.

Next, run the following scripts, which build the SPA code, and also a nonce authenticator plugin for the Curity Identity Server. All components are then deployed to a small docker compose network:

bash
12
./build.sh
./deploy.sh

The following backend components are hosted within the Docker network, behind a Kong open source reverse proxy, which is exposed to port 80 of the local computer. The same domain is used for the web host and OAuth agent, so that HTTP-only cookies issued to the SPA are first-party.

yaml
12345678910111213141516171819202122232425
_format_version: '2.1'
_transform: true
services:
- name: idsvr
url: http://identityserver:8443
routes:
- name: idsvr-runtime-route
paths:
- /
- name: webhost
url: http://webhost:3000/spa
routes:
- name: webhost-route
paths:
- /spa
- name: oauth-agent
url: http://oauthagent:3001/oauth-agent
routes:
- name: oauth-agent-route
paths:
- /oauth-agent

The deployment then exposes port 80 to mobile devices and emulators, using the ngrok tool. This provides a single base URL, similar to the following value. You can then simply start the Android app from Android Studio, or the iOS app from Xcode, to run the end-to-end flow.

text
1
https://4b1c-2-26-218-1.eu.ngrok.io

Once the deployment is understood, you can adapt it to your own environments, by configuring different base URLs. To do so, export IDSVR_BASE_URL and WEB_BASE_URL environent variables before running the deploy.sh script.

Nonce Authenticator Plugin

The example deploys a Nonce Authenticator Plugin with the Curity Identity Server. The plugin is built to JAR files using the mvn package command, and requires the following configuration settings. See the README for deployment instructions, and the getting started with plugins tutorial if your are new to Curity Identity Server plugins.

PropertyDescription
ValidityA time to live in seconds for nonces issued, which defaults to 2 minutes
IssuerThe expected issuer of ID tokens, which is that of the token service in the example deployment
AudienceThe expected audience of ID tokens, which should be set to the nonce issuing endpoint
JWKS EndpointThe JWKS URI used to get the token signing public key, for validating the signature of ID tokens

The plugin implementation requires only a little code, to use the Nonce Token Issuer from the Java plugin SDK. This enables the the mobile app to issue a nonce and for it to be introspected during the SPA flow.

Curity Identity Server Settings

After deploying the system, sign in to the Admin UI at https://localhost:6749/admin, with credentials admin / Password1. Navigate to the authentication service, where an instance of the nonce authenticator has been created. The following configuration has been applied:

Nonce Settings

The endpoint that issues nonces is configured in the audience value above. This is a subpath of the anonymous endpoint of the authentication service:

Anonymous Endpoint

The nonce authenticator is only used when requested via the acr_values query parameter, and is not shown in authentication selection screens. This is managed by a script-filter under the authentication service, with the following simple logic:

javascript
123456789101112
function result(context) {
if (context.authenticator.id === 'nonce1') {
var acr = context.request.getQueryParameter("acr");
if (acr !== 'urn:se:curity:authentication:nonce:nonce1') {
return false;
}
}
return true;
}

Finally, client applications are only allowed to use the nonce issuing endpoint when they opt into doing so. This is managed by extending their audience array claim, to include the HTTPS nonce issuing endpoint.

Mobile Client Settings

Conclusion

It can be difficult to integrate mobile and web applications both securely and with good usability. When SSO does not work due to environmental limitations, another option is to use the nonce authenticator pattern. The mobile app can then swap its ID token for a nonce. The nonce can then be used to bootstrap single sign-on for the web app.