The Nonce Authenticator Pattern
On this page
In some OAuth application scenarios, there may be technical barriers that prevent a Single Sign-On (SSO) solution from working as intended. This can lead to end users having to perform an initial login, then being prompted very soon afterwards to sign in again. When software companies consider this a blocking issue and need a workaround, the nonce authenticator pattern can be used.
Mobile Web Use Case
Single Sign-On may not work reliably when different applications use different cookie jars. This is often the case for a web view, which uses a private browser session. Another example is on iOS, where a mobile app uses an ASWebAuthenticationSession window, and a web app usually uses the Safari browser. Cookies are not shared between these browsers, which can prevent SSO from working.
Insecure Solutions
One attempt to work around the problem might involve passing a token in a URL, as in the following example. In scenarios where mobile web views are used, it is also possible to use a Javascript Interface, to call from the web view and pull a token from the mobile app.
https://www.example.com/mylocation?token=abc123...
These solutions will not work when the web app uses HTTP-only cookies. They are also not secure designs, since tokens should not be passed in URLs. Doing so could reveal them in the browser history or server logs. Different apps should not share tokens, since this can lead to escalation of privileges in some cases. Instead, each client application must receive tokens issued to itself, with the expected scopes and claims.
One-time Tokens
Whenever you need to pass tokens in URLs, use a nonce
as a one-time token. Your authorization server should provide a flow for issuing these to applications. A nonce is safe to use in a URL because it is a number that can only be used once, and is very short lived. So even if a nonce is revealed in the browser history or server logs, it cannot be exploited.
Traditionally, a client makes use of SSO to seamlessly authenticate and obtain tokens. However, SSO commonly relies on cookies and if for some reason these are not sent or accessible, the user will be reprompted for authentication. To avoid this, pass a one-time (authentication) token, the nonce.
Creating a One-time Token
To create a nonce, the source application sends its ID token as a proof, to the nonce issuing endpoint of the authorization server. The ID token must also include the nonce endpoint in its configured audiences, as in this example ID token payload:
{"exp": 1670844872,"nbf": 1670841272,"jti": "d86bc4a8-9107-4d49-89ef-7ed6b6551b10","iss": "https://login.example.com/oauth/v2/oauth-anonymous","aud": ["mobile-client","https://login.example.com/authn/anonymous/nonce1"],"sub": "demouser","auth_time": 1670841272,"iat": 1670841272,"purpose": "id","at_hash": "Q3ej554syBcZfy89CWd8wA","acr": "urn:se:curity:authentication:html-form:htmlform1","delegation_id": "7b5f9257-031e-44b4-b2a8-344810fb03dc","s_hash": "oOe-4pj1BjluIopExD-dwA","azp": "mobile-client","amr": "urn:se:curity:authentication:html-form:htmlform1","nonce": "B_lOPl85v4y_BRfTY-FK7T5xVPqY4cZ6ixgnoWNzRag","sid": "bSziokYTJRNHvbn4"}
The following POST shows the input in an example request to get a nonce:
curl -X POST 'https://login.example.com/authn/anonymous/nonce1' \-H 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'token=eyJraWQi...'
The nonce issuing endpoint will cryptographically verify the signature of the ID token, then check its issuer, audience and expiry. The required audience will be the HTTPS URL of the nonce issuing endpoint. If all checks pass, a nonce will be issued and returned to the source application:
{"nonce": "OFiicYQJYY2phWnD5nFMflid5Du82ycW"}
The source application can then navigate to the target application and supply the nonce as a query parameter:
https://www.example.com/mylocation?nonce=OFiicYQJYY2phWnD5nFMflid5Du82ycW
Authenticating with a One-time Token
The target application then needs to run an OpenID Connect flow that includes the nonce. The authentication request will use the acr_values
field to ensure that the nonce authenticator is used. It will also send the nonce in the login_hint_token
field, and prompt=login
to ensure that the nonce is used:
GET /oauth/v2/oauth-authorize HTTP/1.1Host: login.example.comContent-Type: application/x-www-form-urlencodedclient_id=web-client&redirect_uri=http%3A%2F%2Fwww.example.com%2F&response_type=code&code_challenge=l9QIPE4TFgW2y7STZDSWQ4Y4CQpO8W6VtELopzYHdNg&code_challenge_method=S256&state=NlAoISfdL1DxPdNGFBljlVuB1GDjgGARmqDcxtHhV8iKNYu6ECS2KOavDHpI3eLN&scope=openid%20profile&login_hint_token=OFiicYQJYY2phWnD5nFMflid5Du82ycW&acr_values=urn:se:curity:authentication:nonce:nonce1&prompt=login
This redirect will be to the authorization endpoint of the authorization server, after which a temporary cookie is set and there is a second redirect to the nonce authenticator.
iframe redirects
Running this redirect on a hidden iframe in a web client will not work as expected, unless the web app shares the same parent domain as the authorization server. This is due to recent browser restrictions on third party sites, that cause the temporary cookie to be dropped.
Mobile Web Code Example
The Mobile Web SSO code example provides an end-to-end solution that you can run from a development computer, to demonstrate the use of the nonce authenticator pattern. Basic Android and iOS mobile clients are provided, along with a minimal web application that can be run in a web view or system browser.
Conclusion
The nonce authenticator pattern enables Single Sign-On navigation from a source application to a target application. It does so by creating a short-lived one-time token, using the ID token of the source application as a proof. This nonce is then used to bootstrap a session in the target application. Usage should be restricted to specific clients, who opt into allowing the nonce authenticator, by including it in their audience restrictions.
Gary Archer
Product Marketing Engineer at Curity
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial