diff --git a/articles/quickstart/native/n2w/01-login.md b/articles/quickstart/native/n2w/01-login.md new file mode 100755 index 0000000000..ca3ccb8554 --- /dev/null +++ b/articles/quickstart/native/n2w/01-login.md @@ -0,0 +1,117 @@ +--- +title: Enable Native to Web SSO for iOS and Android Apps +description: Learn how to configure Auth0 Native to Web SSO in your iOS or Android apps using the Auth0 CLI and SDKs. +seo_alias: native-to-web-sso +budicon: 448 +topics: + - quickstarts + - native + - web + - ios + - android +github: + path: native-to-web-sso +contentType: tutorial +useCase: quickstart +--- + + + +## Configure Auth0 + +You will need both a **Native** application (for iOS or Android) and a **Web** or **Single Page Application (SPA)** registered in your Auth0 tenant. If you don’t have them already, create one before continuing. + +### Enable Session Transfer in the Native Application + +Use the Auth0 CLI to allow your native app to create session transfer tokens: + +```bash +auth0 apps session-transfer set ${account.clientId} \ + --can-create-token=true \ + --enforce-device-binding=asn +``` + +### Enable Session Transfer in the Web Application + +Configure your web or SPA app to accept session transfer tokens via cookie or query string: + +```bash +auth0 apps session-transfer set ${account.clientId} \ + --allowed-authentication-methods=cookie,query +``` + +::: note +To support cookie injection, use a WebView that allows setting secure cookies such as WKWebView on iOS or Android WebView. If not supported, you can use the query string method. +::: + +## Exchange a Refresh Token for a Session Transfer Token + +This action should happen right before you launch a WebView or external browser. + +```swift +Auth0 + .authentication() + .ssoExchange(withRefreshToken: refreshToken) + .start { result in + switch result { + case .success(let ssoCredentials): + DispatchQueue.main.async { + let cookie = HTTPCookie(properties: [ + .domain: "${account.namespace}", + .path: "/", + .name: "auth0_session_transfer_token", + .value: ssoCredentials.sessionTransferToken, + .expires: ssoCredentials.expiresIn, + .secure: true + ])! + + let webView = WKWebView() + let store = webView.configuration.websiteDataStore.httpCookieStore + store.setCookie(cookie) { + let url = URL(string: "https://yourWebApplicationLoginURI")! + let request = URLRequest(url: url) + webView.load(request) + + let vc = UIViewController() + vc.view = webView + UIApplication.shared.windows.first?.rootViewController?.present(vc, animated: true) + } + } + case .failure(let error): + print("Failed to get SSO token: \(error)") + } + } +``` + +## Handle Session Transfer in the Web Application + +In cookie-based flows, your app doesn’t need to change. Just make sure your Application Login URI points to a route that redirects to Auth0’s `/authorize` endpoint. + +If using query string method: + +```javascript +const { auth } = require('express-openid-connect'); + +const config = { + authRequired: false, + auth0Logout: true, + authorizationParams: { + response_type: 'code', + scope: 'openid profile email', + } +}; + +app.use((req, res, next) => { + const { session_transfer_token } = req.query; + + if (session_transfer_token) { + config.authorizationParams.session_transfer_token = session_transfer_token; + } + + auth(config)(req, res, next); +}); +``` + +::: note +You can configure your Application Login URI in your application's settings in the Auth0 Dashboard. +::: diff --git a/articles/quickstart/native/n2w/download.md b/articles/quickstart/native/n2w/download.md new file mode 100644 index 0000000000..32124138f3 --- /dev/null +++ b/articles/quickstart/native/n2w/download.md @@ -0,0 +1,20 @@ + + +> On every step, if you have a custom domain, replace the `YOUR_AUTH0_DOMAIN` placeholder with your custom domain instead of the value from the settings page. + +## 1. Configure the associated domain + +> **This requires Xcode 15.3+ and a paid Apple Developer account**. If you do not have a paid Apple Developer account, skip this step, and comment out the two `useHTTPS()` calls in `MainView.swift`. + +Open `SwiftSample.xcodeproj` in Xcode and go to the settings of the app target you want to run. There are two app targets available: **SwiftSample (iOS)** and **SwiftSample (macOS)**. Change the bundle identifier from the default `com.auth0.samples.SwiftSample` to another value of your choosing. Then, make sure the **Automatically manage signing** box is checked, and that your Apple Team is selected. + +Next, go to the **Signing & Capabilities** tab of the app's target settings. Find the `webcredentials:YOUR_AUTH0_DOMAIN` entry under **Associated Domains**, and replace the `YOUR_AUTH0_DOMAIN` placeholder with the domain of your Auth0 application. + +Finally, open the settings page of your Auth0 application, scroll to the end, and open **Advanced Settings > Device Settings**. In the **iOS** section, set **Team ID** to your Apple Team ID, and **App ID** to the app's bundle identifier. + +## 2. Configure the Auth0 application + +Open the settings page of your Auth0 application and add the following URLs to **Allowed Callback URLs** and **Allowed Logout URLs**, depending on the app target you want to run. + +- **SwiftSample (iOS)**: `https://YOUR_AUTH0_DOMAIN/ios/YOUR_BUNDLE_IDENTIFIER/callback,YOUR_BUNDLE_IDENTIFIER://YOUR_AUTH0_DOMAIN/ios/YOUR_BUNDLE_IDENTIFIER/callback` +- **SwiftSample (macOS)**: `https://YOUR_AUTH0_DOMAIN/macos/YOUR_BUNDLE_IDENTIFIER/callback,YOUR_BUNDLE_IDENTIFIER://YOUR_AUTH0_DOMAIN/macos/YOUR_BUNDLE_IDENTIFIER/callback` diff --git a/articles/quickstart/native/n2w/files/NativeApplication_Kotlin.md b/articles/quickstart/native/n2w/files/NativeApplication_Kotlin.md new file mode 100644 index 0000000000..78034352cf --- /dev/null +++ b/articles/quickstart/native/n2w/files/NativeApplication_Kotlin.md @@ -0,0 +1,37 @@ +--- +name: android.kt +language: kotlin +--- + +```kotlin +import android.app.Activity +import android.util.Log +import android.webkit.CookieManager +import android.webkit.WebView + +fun launchWebSSO(context: Activity) { + authentication + .ssoExchange("refresh_token") + .start(object : Callback { + override fun onSuccess(result: SSOCredentials) { + val cookieManager = CookieManager.getInstance() + val cookieValue = "auth0_session_transfer_token=" + result.sessionTransferToken + + "; Path=/; Secure; HttpOnly; SameSite=None" + cookieManager.setAcceptCookie(true) + cookieManager.setCookie("${account.namespace}", cookieValue) + + val webView = WebView(context) + webView.settings.javaScriptEnabled = true + webView.loadUrl("https://yourWebApplicationLoginURI") + + context.runOnUiThread { + context.setContentView(webView) + } + } + + override fun onFailure(exception: AuthenticationException) { + Log.e("Auth0", "Failed to get session transfer token", exception) + } + }) +} +``` diff --git a/articles/quickstart/native/n2w/files/NativeApplication_ReactNative.md b/articles/quickstart/native/n2w/files/NativeApplication_ReactNative.md new file mode 100644 index 0000000000..ec6fc38bc1 --- /dev/null +++ b/articles/quickstart/native/n2w/files/NativeApplication_ReactNative.md @@ -0,0 +1,21 @@ +--- +name: reactivenative.js +language: javascript +--- + +```javascript +// React Native - Placeholder for Native to Web SSO +// SDK support is not available yet. This is a conceptual guide only. + +import { WebView } from 'react-native-webview'; + +/** + * Concept: + * - Use your Auth0 refresh_token to call a backend that performs the session_transfer_token exchange + * - Receive the short-lived session_transfer_token + * - Inject it into a WebView via a cookie header or query param (if cookies aren't supported) + * - Load the web login URI + */ + + +``` diff --git a/articles/quickstart/native/n2w/files/NativeApplication_Swift.md b/articles/quickstart/native/n2w/files/NativeApplication_Swift.md new file mode 100644 index 0000000000..8ae8df89b9 --- /dev/null +++ b/articles/quickstart/native/n2w/files/NativeApplication_Swift.md @@ -0,0 +1,51 @@ +--- +name: swift.swift +language: swift +--- + +```swift +import SwiftUI +import Auth0 +import WebKit + +struct MainView: View { + var body: some View { + Button("Open Web Session", action: self.launchWebSSO) + } + + func launchWebSSO() { + Auth0 + .authentication() + .ssoExchange(withRefreshToken: refreshToken) + .start { result in + switch result { + case .success(let ssoCredentials): + DispatchQueue.main.async { + let cookie = HTTPCookie(properties: [ + .domain: "${account.namespace}", + .path: "/", + .name: "auth0_session_transfer_token", + .value: ssoCredentials.sessionTransferToken, + .expires: ssoCredentials.expiresIn, + .secure: true + ])! + + let webView = WKWebView() + let store = webView.configuration.websiteDataStore.httpCookieStore + store.setCookie(cookie) { + let url = URL(string: "https://yourWebApplicationLoginURI")! + let request = URLRequest(url: url) + webView.load(request) + + let vc = UIViewController() + vc.view = webView + UIApplication.shared.windows.first?.rootViewController?.present(vc, animated: true) + } + } + case .failure(let error): + print("Failed to get SSO token: \(error)") + } + } + } +} +``` diff --git a/articles/quickstart/native/n2w/files/SinglePageApplication_React.md b/articles/quickstart/native/n2w/files/SinglePageApplication_React.md new file mode 100644 index 0000000000..9ce4d17167 --- /dev/null +++ b/articles/quickstart/native/n2w/files/SinglePageApplication_React.md @@ -0,0 +1,32 @@ +--- +name: react.jsx +language: javascript +--- + +```javascript +import { useAuth0 } from "@auth0/auth0-react"; +import React, { useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; + +const LoginButton = () => { + const { loginWithRedirect } = useAuth0(); + const [searchParams] = useSearchParams(); + + useEffect(() => { + const sessionTransferToken = searchParams.get("session_transfer_token"); + + // Automatically trigger the login when receiving session transfer token + if (sessionTransferToken) { + loginWithRedirect({ + authorizationParams: { + session_transfer_token: sessionTransferToken, + }, + }); + } + }, [loginWithRedirect, searchParams]); + + return ; +}; + +export default LoginButton; +``` diff --git a/articles/quickstart/native/n2w/files/WebApplication_Node.md b/articles/quickstart/native/n2w/files/WebApplication_Node.md new file mode 100644 index 0000000000..035cf63132 --- /dev/null +++ b/articles/quickstart/native/n2w/files/WebApplication_Node.md @@ -0,0 +1,28 @@ +--- +name: node.js +language: javascript +--- + +```javascript +const { auth } = require('express-openid-connect'); + +const config = { + authRequired: false, + auth0Logout: true, + authorizationParams: { + response_type: 'code', + scope: 'openid profile email', + } +}; + +// Middleware that supports session_transfer_token via query parameter +app.use((req, res, next) => { + const { session_transfer_token } = req.query; + + if (session_transfer_token) { + config.authorizationParams.session_transfer_token = session_transfer_token; + } + + auth(config)(req, res, next); +}); +``` diff --git a/articles/quickstart/native/n2w/index.yml b/articles/quickstart/native/n2w/index.yml new file mode 100755 index 0000000000..76d29c41eb --- /dev/null +++ b/articles/quickstart/native/n2w/index.yml @@ -0,0 +1,32 @@ +title: Native to Web SSO +# TODO remove 'image' once new QS page is live. Then only use 'logo'. +image: /media/platforms/ios.png +logo: auth0 +alias: + - ios + - macos + - swift +hybrid: false +author: + name: Nelson Matias + email: nelson.matias@auth0.com + community: false +topics: + - quickstart +contentType: tutorial +useCase: quickstart +seo_alias: swift +show_releases: true +show_steps: true +requirements: + - iOS 13+ or macOS 11+ + - Xcode 14.x +default_article: 01-login +articles: + - 01-login +hidden_articles: + - interactive +github: + org: auth0-samples + repo: auth0-ios-swift-sample + branch: master diff --git a/articles/quickstart/native/n2w/interactive.md b/articles/quickstart/native/n2w/interactive.md new file mode 100644 index 0000000000..ae844c8421 --- /dev/null +++ b/articles/quickstart/native/n2w/interactive.md @@ -0,0 +1,157 @@ +--- +title: Enable Native to Web SSO for iOS and Android Apps +description: Learn how to configure Auth0 Native to Web SSO in your iOS or Android apps using the Auth0 CLI and SDKs. +interactive: true +locale: en-US +files: + - files/NativeApplication_Kotlin + - files/NativeApplication_ReactNative + - files/NativeApplication_Swift + - files/WebApplication_Node + - files/SinglePageApplication_React +--- + +# Enable Native to Web SSO for iOS and Android Apps (Beta) + +

This guide demonstrates how to integrate Auth0 Native to Web Single Sign-On (SSO) with existing iOS or Android applications using the Auth0 CLI and supported SDKs.

+ +

We recommend that you log in to follow this quickstart with examples configured for your Auth0 tenant.

+ +## Prerequisites + +

To continue with this quickstart, we recommend completing the iOS Swift Quickstart or Android Quickstart.

+ +

To successfully enable Native to Web SSO, your mobile application must:

+ + +
+

This quickstart uses the Auth0 CLI to configure your Auth0 tenant. You may also use the Auth0 Management API. For more details, see Configure Native to Web SSO.

+
+ +## Configure Auth0 CLI + +

Start by authenticating to your Auth0 tenant using the Auth0 CLI:

+ +
auth0 login
+ +

When prompted:

+ +
How would you like to authenticate?
+> As a user
+  As a machine
+
+ +

Choose As a user and follow the login flow. Select the Auth0 tenant where you want to enable Native to Web SSO.

+ +## Configure Auth0 + +### Enable Session Transfer Token in the Native Application + +

Native to Web SSO uses a session_transfer_token to establish SSO from a native app to a web app.

+ +

This token allows Auth0 to identify the user, the native origin app, and additional context securely. For more details, refer to the Native to Web SSO documentation.

+ +

Use the Auth0 CLI to enable your native application to generate session transfer tokens:

+ +
auth0 apps session-transfer set ${account.clientId} \
+  --can-create-token=true \
+  --enforce-device-binding=asn
+ +### Enable Session Transfer Authentication in the Web Application + +

Configure the web application to accept the session_transfer_token for authentication using either cookie or URL parameter:

+ +
auth0 apps session-transfer set ${account.clientId} \
+  --allowed-authentication-methods=cookie,query
+ +

This enables the native application to inject the token into a WebView using a cookie or append it as a URL parameter.

+ +
+

To test Native to Web SSO on mobile, use a WebView that supports cookie injection (e.g., Android WebView or iOS WKWebView) or append the token as a query string to the login URI if your WebView don't support cookie injection.

+
+ +## Configure the Native Application {{{ data-action="code" data-code="android" }}} + +

Once your native app has obtained a refresh_token, it must exchange it for a session_transfer_token immediately before launching the web session. This token is short-lived (60 seconds), so it should be generated as close as possible to when the WebView or browser is opened.

+ +

We recommend placing the session transfer exchange and WebView launch logic inside the same event handler — such as a button’s onClick method. This ensures the token is valid and avoids timing issues.

+ +

The code demonstrates how to pass the session_transfer_token to your web application using a cookie. This method requires WebViews or browsers that support cookie injection. If your platform or WebView does not support cookies, you can instead append the token as a query parameter to the login URL.

+ +```swift + + Auth0 + .authentication() + .ssoExchange(withRefreshToken: refreshToken) + .start { result in + switch result { + case .success(let ssoCredentials): + DispatchQueue.main.async { + let cookie = HTTPCookie(properties: [ + .domain: "${account.namespace}", + .path: "/", + .name: "auth0_session_transfer_token", + .value: ssoCredentials.sessionTransferToken, + .expires: ssoCredentials.expiresIn, + .secure: true + ])! + + let webView = WKWebView() + let store = webView.configuration.websiteDataStore.httpCookieStore + store.setCookie(cookie) { + let url = URL(string: "https://yourWebApplicationLoginURI")! + let request = URLRequest(url: url) + webView.load(request) + + let vc = UIViewController() + vc.view = webView + UIApplication.shared.windows.first?.rootViewController?.present(vc, animated: true) + } + } + case .failure(let error): + print("Failed to get SSO token: \(error)") + } + } + +``` + +## Configure the Web Application {{{ data-action="code" data-code="react" }}} + +

To support Native to Web SSO, your web application must be prepared to handle a session_transfer_token received via either a cookie or a URL parameter.

+ +

If the token is injected into the browser via a cookie—as shown in the native app examples—then no changes to your web application are required. The only requirement is that the browser navigates to your Application Login URI, which should handle redirecting the user to your Auth0 tenant’s /authorize endpoint.

+ +
+

You can configure the Application Login URI in your application's settings within the Auth0 Dashboard. This is the route Auth0 will redirect users to when initiating login from external sources.

+
+ +

In the sample below, we show how to handle URL-based session transfer tokens. This is not needed for cookie-based flows, but it helps illustrate how URL-based SSO would be handled as well.

+ +```js + +const { auth } = require('express-openid-connect'); + +const config = { + authRequired: false, + auth0Logout: true, + authorizationParams: { + response_type: 'code', + scope: 'openid profile email', + } +}; + +// Middleware that supports session_transfer_token via query parameter +app.use((req, res, next) => { + const { session_transfer_token } = req.query; + + if (session_transfer_token) { + config.authorizationParams.session_transfer_token = session_transfer_token; + } + + auth(config)(req, res, next); +}); + +```