MaikuB / MaikuB/flutter_appauth

[FeatureRequest]: Support proxy redirect URLs for providers that require HTTPS redirect URLs

Open
#651 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Objective-C
Stars
308
Forks
301
Avg merge
2d 11h
Merged PRs (30d)
5

Description

## Summary

Add a `proxyRedirectUrl` parameter to authorization and token exchange requests so that apps can work with OAuth providers that only allow HTTPS redirect URIs.

## Background

Native mobile apps traditionally use custom-scheme deep links (e.g. `com.example.myapp://oauth2redirect`) as redirect URIs. These are registered with the OS so that the browser hands the OAuth callback back to the app. However, some identity providers enforce a strict policy that only HTTPS redirect URIs are permitted. As a result, apps using custom schemes are rejected at the authorization request stage.

At first glance, Universal Links (iOS) and App Links (Android) appear to be a natural solution since they use HTTPS URLs that the OS can route to the app. However, they are not a reliable alternative in this context:

- On iOS and macOS, `ASWebAuthenticationSession` — the mechanism AppAuth uses to present the authorization flow — only terminates and returns a result when the browser navigates to a URL matching a registered **custom scheme**. Its `callbackURLScheme` parameter does not accept `https`, so a Universal Link used as the redirect URI will not be intercepted by the session; the flow stalls or opens in the browser instead.
- On Android, App Links require hosting a `assetlinks.json` file and passing an OS-level domain verification process that can fail silently, be delayed, or be bypassed by the user choosing to open the link in a browser. AppAuth's `RedirectUriReceiverActivity` is also designed around custom-scheme intent filters rather than App Links.

A well-known workaround is to host a lightweight HTTPS endpoint that acts as a proxy: the provider redirects to the HTTPS URL, which immediately issues a redirect to the app's custom scheme. The OAuth flow then completes as normal.

## Problem

Currently the plugin only accepts a single `redirectUrl`. There is no way to tell the plugin to send a different URL to the provider while still intercepting the callback on-device via a custom scheme. Developers who need to integrate with strict providers (e.g. certain enterprise identity providers, government OAuth servers, or providers with hardcoded HTTPS-only validation) cannot use the plugin without a workaround outside of AppAuth's control.

## Proposed solution

Add an optional `proxyRedirectUrl` parameter to `AuthorizationRequest`, `AuthorizationTokenRequest`, and `TokenRequest`:

- When `proxyRedirectUrl` is set, it is sent to the identity provider as the `redirect_uri` parameter in the authorization request, satisfying the HTTPS requirement.
- `redirectUrl` (the custom scheme) continues to be used by AppAuth on-device to intercept the browser callback.
- When performing a token exchange (either as a separate `token()` call or automatically via `authorizeAndExchangeCode()`), `proxyRedirectUrl` is also sent as `redirect_uri` so it matches what was used in the authorization request — a requirement of the OAuth 2.0 spec.

## Example use case

A developer integrating with an enterprise identity provider that rejects `com.example.myapp://oauth2redirect` with the error `redirect_uri_mismatch` because it is not an HTTPS URI. They host `https://myapp.example.com/oauth2redirect` which redirects to `com.example.myapp://oauth2redirect`. With `proxyRedirectUrl` they can pass both URLs:

```dart
await appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
'',
'com.example.myapp://oauth2redirect',
proxyRedirectUrl: 'https://myapp.example.com/oauth2redirect',
discoveryUrl: '',
scopes: ['openid', 'profile', 'email', 'offline_access'],
),
);
```

## Platforms affected

Android, iOS, macOS

Contributor guide

Open the contributing guide

Research direction

Start by locating AuthorizationRequest, AuthorizationTokenRequest, and TokenRequest, then trace authorizeAndExchangeCode() and token() across the Android, iOS, and macOS implementations. Add optional proxyRedirectUrl handling so authorization and token exchange use it while redirectUrl remains the on-device callback; done means all three request types and both exchange paths preserve matching redirect_uri values.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, dart, flutter, ios, macos
Domain
authentication, mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.