Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the HTTPS redirect URLs feature [SDK-4755] #418

Merged
merged 8 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ UIAutomator interacts with device emulators, ensure an emulator for Android is r
The above tests rely on a couple of environment variables that can be defined in **/auth0_flutter/example/.env**:

- `AUTH0_DOMAIN`: Auth0 Domain
- `AUTH0_CLIENT_ID`: Auth0 Client Id
- `USER_EMAIL`: Email to log into the configured Auth0 Domain and Client Id
- `USER_PASSWORD`: Password to log into the configured Auth0 Domain and Client Id
- `AUTH0_CLIENT_ID`: Auth0 Client ID
- `USER_EMAIL`: Email to log into the configured Auth0 Domain and Client ID
- `USER_PASSWORD`: Password to log into the configured Auth0 Domain and Client ID

### Running the tests

Expand Down
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@ For general support or usage questions, use the [Auth0 Community](https://commun

**Do not report security vulnerabilities on the public GitHub issue tracker.** The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.

## What is Auth0?
---

Auth0 helps you to:
<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150">
<img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
</picture>
</p>

- Add authentication with [multiple sources](https://auth0.com/docs/authenticate/identity-providers), either social identity providers such as **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce** (amongst others), or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS, or any SAML identity provider**.
- Add authentication through more traditional **[username/password databases](https://auth0.com/docs/authenticate/database-connections/custom-db)**.
- Add support for **[linking different user accounts](https://auth0.com/docs/manage-users/user-accounts/user-account-linking)** with the same user.
- Support for generating signed [JSON web tokens](https://auth0.com/docs/secure/tokens/json-web-tokens) to call your APIs and **flow the user identity** securely.
- Analytics of how, when, and where users are logging in.
- Pull data from other sources and add it to the user profile through [JavaScript Actions](https://auth0.com/docs/customize/actions).
<p align="center">Auth0 is an easy-to-implement, adaptable authentication and authorization platform. To learn more check out <a href="https://auth0.com/why-auth0">Why Auth0?</a></p>

**Why Auth0?** Because you should save time, be happy, and focus on what really matters: building your product.

## License

This project is licensed under Apache License 2.0. See the [LICENSE](LICENSE) file for more information.
<p align="center">This project is licensed under the MIT license. See the <a href="./LICENSE"> LICENSE</a> file for more info.</p>
92 changes: 91 additions & 1 deletion auth0_flutter/EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
- [Adding scopes](#adding-scopes)
- [Adding custom parameters](#adding-custom-parameters)
- [ID token validation](#id-token-validation)
- [Using `SFSafariViewController` (iOS only)](#using-sfsafariviewcontroller-ios-only)
- [1. Configure a custom URL scheme](#1-configure-a-custom-url-scheme)
- [2. Capture the callback URL](#2-capture-the-callback-url)
- [Errors](#errors)
- [Android: Custom schemes](#android-custom-schemes)
- [📱 Credentials Manager](#-credentials-manager)
Expand Down Expand Up @@ -38,6 +41,9 @@
- [Adding scopes](#adding-scopes)
- [Adding custom parameters](#adding-custom-parameters)
- [ID token validation](#id-token-validation)
- [Using `SFSafariViewController` (iOS only)](#using-sfsafariviewcontroller-ios-only)
- [1. Configure a custom URL scheme](#1-configure-a-custom-url-scheme)
- [2. Capture the callback URL](#2-capture-the-callback-url)
- [Errors](#errors)
- [Android: Custom schemes](#android-custom-schemes)

Expand All @@ -55,7 +61,9 @@ Call the `logout()` method in the `onPressed` callback of your **Logout** button
If you're using your own credentials storage, make sure to delete the credentials afterward.

```dart
await auth0.webAuthentication().logout();
// Use a Universal Link logout URL on iOS 17.4+ / macOS 14.4+
// useHTTPS is ignored on Android
await auth0.webAuthentication().logout(useHTTPS: true);
```

</details>
Expand Down Expand Up @@ -239,6 +247,88 @@ await auth0Web.loginWithRedirect(

</details>

### Using `SFSafariViewController` (iOS only)

auth0_flutter supports using `SFSafariViewController` as the browser instead of `ASWebAuthenticationSession`. Note that it can only be used for login, not for logout. According to its docs, `SFSafariViewController` must be used "to visibly present information to users":

![Screenshot of SFSafariViewController's documentation](https://github.com/auth0/auth0-flutter/assets/5055789/952aa669-f229-4e6e-bb7e-527b701bdea6)

This is the case for login, but not for logout. Instead of calling `logout()`, you can delete the stored credentials –using the Credentials Manager's `clearCredentials()` method– and use `'prompt': 'login'` to force the login page even if the session cookie is still present. Since the cookies stored by `SFSafariViewController` are scoped to your app, this should not pose an issue.

```dart
await auth0.webAuthentication().login(
safariViewController: const SafariViewController(),
parameters: {'prompt': 'login'}); // Ignore the cookie (if present) and show the login page
```

> 💡 `SFSafariViewController` does not support using a Universal Link as callback URL. See https://auth0.github.io/Auth0.swift/documentation/auth0/useragents to learn more about the differences between `ASWebAuthenticationSession` and `SFSafariViewController`.

If you choose to use `SFSafariViewController`, you need to perform an additional bit of setup. Unlike `ASWebAuthenticationSession`, `SFSafariViewController` will not automatically capture the callback URL when Auth0 redirects back to your app, so it is necessary to manually resume the login operation.

#### 1. Configure a custom URL scheme

There is an `Info.plist` file in the `ios/Runner` (or `macos/Runner`, for macOS) directory of your app. Open it and add the following snippet inside the top-level `<dict>` tag. This registers your iOS/macOS bundle identifier as a custom URL scheme, so the callback URL can reach your app.

```xml
<!-- Info.plist -->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ... -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>CFBundleURLName</key>
<string>auth0</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
</dict>
</array>
<!-- ... -->
</dict>
</plist>
```

> 💡 If you're opening the `Info.plist` file in Xcode and it is not being shown in this format, you can **Right Click** on `Info.plist` in the Xcode [project navigator](https://developer.apple.com/documentation/bundleresources/information_property_list/managing_your_app_s_information_property_list) and then select **Open As > Source Code**.

#### 2. Capture the callback URL

<details>
<summary>Using the UIKit app lifecycle</summary>

```swift
// AppDelegate.swift

override func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
WebAuthentication.resume(with: url)
return super.application(application, open: url, options: options);
}
```

</details>

<details>
<summary>Using the UIKit app lifecycle with Scenes</summary>

```swift
// SceneDelegate.swift

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
WebAuthentication.resume(with: url)
}
```

</details>

### Errors

<details>
Expand Down
55 changes: 6 additions & 49 deletions auth0_flutter/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,13 @@ Alternatively, you can re-declare the `RedirectActivity` in the `android/app/src

### 2. How can I disable the iOS _login_ alert box?

![ios-sso-alert](https://user-images.githubusercontent.com/5055789/198689762-8f3459a7-fdde-4c14-a13b-68933ef675e6.png)
![Screenshot of the SSO alert box](https://user-images.githubusercontent.com/5055789/198689762-8f3459a7-fdde-4c14-a13b-68933ef675e6.png)

Auth0.swift uses `ASWebAuthenticationSession` to perform web-based authentication, which is the [API provided by Apple](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession) for such purpose.

That alert box is displayed and managed by `ASWebAuthenticationSession`, not by Auth0.swift, because by default this API will store the session cookie in the shared Safari cookie jar. This makes Single Sign-On (SSO) possible. According to Apple, that requires user consent.

> **Note**
> See [this blog post](https://developer.okta.com/blog/2022/01/13/mobile-sso) for a detailed overview of SSO on iOS.
> 💡 See [this blog post](https://developer.okta.com/blog/2022/01/13/mobile-sso) for a detailed overview of SSO on iOS.

#### Use ephemeral sessions

Expand All @@ -83,56 +82,15 @@ Note that with `useEphemeralSession: true` you don't need to call `logout()` at

You still need to call `logout()` on Android, though, as `useEphemeralSession` is iOS/macOS only.

> **Warning** > `useEphemeralSession` relies on the `prefersEphemeralWebBrowserSession` configuration option of `ASWebAuthenticationSession`.
> ⚠️ `useEphemeralSession` relies on the `prefersEphemeralWebBrowserSession` configuration option of `ASWebAuthenticationSession`.

#### Use `SFSafariViewController`

An alternative is to use `SFSafariViewController` instead of `ASWebAuthenticationSession`. You can do so by setting the `safariViewController` property during login:

```dart
await auth0
.webAuthentication()
.login(safariViewController: const SafariViewController());
```

> **Note**
> Since `SFSafariViewController` does not share cookies with the Safari app, SSO will not work either. But it will keep its own cookies, so you can use it to perform SSO between your app and your website as long as you open it inside your app using `SFSafariViewController`. This also means that any feature that relies on the persistence of cookies will work as expected.

If you choose to use `SFSafariViewController`, you need to perform an additional bit of setup. Unlike `ASWebAuthenticationSession`, `SFSafariViewController` will not automatically capture the callback URL when Auth0 redirects back to your app, so it's necessary to manually resume the Web Auth operation.

<details>
<summary>Using the UIKit app lifecycle</summary>

```swift
// AppDelegate.swift

override func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
WebAuthentication.resume(with: url)
return super.application(application, open: url, options: options);
}
```

</details>

<details>
<summary>Using the UIKit app lifecycle with Scenes</summary>

```swift
// SceneDelegate.swift

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
WebAuthentication.resume(with: url)
}
```

</details>
An alternative is to use `SFSafariViewController` instead of `ASWebAuthenticationSession`. See [EXAMPLES.md](./EXAMPLES.md#using-sfsafariviewcontroller-ios-only) to learn more.

### 3. How can I disable the iOS _logout_ alert box?

![ios-sso-alert](https://user-images.githubusercontent.com/5055789/198689762-8f3459a7-fdde-4c14-a13b-68933ef675e6.png)
![Screenshot of the SSO alert box](https://user-images.githubusercontent.com/5055789/198689762-8f3459a7-fdde-4c14-a13b-68933ef675e6.png)

Since `logout()` on iOS also needs to use `ASWebAuthenticationSession` to clear the shared session cookie, the same alert box will be displayed.

Expand All @@ -148,8 +106,7 @@ final credentials = await auth0.webAuthentication().login(

Otherwise, the browser modal will close right away and the user will be automatically logged in again, as the cookie will still be there.

> **Warning**
> Keeping the shared session cookie may not be an option if you have strong privacy and/or security requirements, for example in the case of a banking app.
> ⚠️ Keeping the shared session cookie may not be an option if you have strong privacy and/or security requirements, for example in the case of a banking app.

### 4. How can I change the message in the iOS alert box?

Expand Down
Loading
Loading