Revert to AppAuth SDK v1.7.6 Due to Apple App Review Rejection on v2.0.0
Describe the bug After updating our app to use AppAuth SDK version 2.0.0, our submission was rejected by Apple during App Review. The reviewer indicated that the app redirects users to the default browser (Safari) to sign in or register, which violates Apple’s user experience guidelines.
The rejection note stated: “We noticed that the user is taken to the default web browser to sign in or register for an account, which provides a poor user experience.”
However, we did not change our integration logic between versions. The only difference was upgrading the SDK from 1.7.6 to 2.0.0.
After reverting back to 1.7.6, the app was approved without issue.
This suggests there may have been internal changes in the SDK behavior related to how the authentication flow is handled or presented.
To Reproduce Steps to reproduce the issue with AppAuth iOS SDK v2.0.0: 1. Integrate AppAuth SDK v2.0.0 into an iOS app. 2. Launch the app and trigger the login flow using the standard AppAuth OIDAuthorizationService. 3. Observe the behavior when Safari View Controller is presented. 4. Submit the app to Apple for review. 5. Review feedback reports app rejection due to using a default browser.
Expected behavior
- The Safari View Controller should be used to present the authorization flow within the app, not redirect users to the external Safari browser.
- The sign-in experience should meet Apple’s guidelines and be consistent with previous SDK behavior (as in v1.7.6).
Environment
- Device: iPhone 16 Pro Max
- OS: iOS 16.0+
- Browser (in-app): Safari View Controller (SFSafariViewController)
- AppAuth SDK Versions:
- Working: 1.7.6
- Rejected: 2.0.0
Additional context We have not changed our implementation across SDK versions—only the library version itself. The login is initiated through OIDAuthorizationService.present() using the standard flow with SFSafariViewController.
After reverting to version 1.7.6, our app passed Apple Review with no issues. This raises concern that there may be a breaking behavioral change in how AppAuth 2.0.0 handles the authorization UI, possibly falling back to an external Safari browser under certain conditions.
Request: Could someone from the maintainers clarify if anything has changed in 2.0.0 that would result in a fallback to the default browser or change how Safari View Controller is handled?
If this is unintended, we would appreciate insights or a possible patch. Otherwise, we may need to pin to 1.7.6 indefinitely.
Are you able to reproduce the default browser opening? This PR (https://github.com/openid/AppAuth-iOS/pull/911) seems most likely but nothing immediately stands out to me as it would effect iOS 16+.
Unfortunately, our team has not been able to reproduce the default browser opening issue. However, Apple’s app reviewer flagged the app for not using the Safari View Controller API. We explicitly clarified in our response that the SDK does in fact use Safari View Controller, but the rejection persisted.
It’s worth noting that this issue only occurred after upgrading to AppAuth iOS SDK v2.0.0 — the exact same implementation with v1.7.6 was approved without issue. This suggests there may be a behavioral change in v2.0.0 (possibly related to PR #911) that is causing the reviewer to believe a default browser is being used.
@chauyong To try and help us debug, would you be able to share how you've integrated with AppAuth? Is a pretty standard integration like outlined in the repo's README, or are you performing the authorization request manually?
Here’s the function responsible for presenting the modal Safari View Controller. Please note that this integration has remained unchanged since we first launched the app using version 1.6.0.
@MainActor
public func authenticateRedirect(
viewController: UIViewController,
type: AuthenticatedType
) async throws -> OIDAuthorizationResponse? {
try await withCheckedThrowingContinuation { [weak self] continuation in
guard
let self = self,
let configuration = self.authState.configuration,
let redirectURI = URL(string: self.authConfig.redirectUri),
let userAgent = OIDExternalUserAgentIOS(presenting: viewController)
else {
continuation.resume(returning: nil)
return
}
let additionalParameters: [String: String]?
switch type {
case .login:
additionalParameters = nil
case .signup:
additionalParameters = ["prompt": "signup"]
}
let request = OIDAuthorizationRequest(
configuration: configuration,
clientId: self.authConfig.clientId,
clientSecret: nil,
scope: self.authConfig.scope,
redirectURL: redirectURI,
responseType: OIDResponseTypeCode,
state: nil,
nonce: nil,
codeVerifier: nil,
codeChallenge: nil,
codeChallengeMethod: nil,
additionalParameters: additionalParameters
)
self.userAgentSession = OIDAuthorizationService.present(request, externalUserAgent: userAgent) { [weak self] response, error in
if let self, let response {
self.userAgentSession = nil
continuation.resume(returning: response)
}
if let self, let error {
if self.isUserCancellation(error: error as NSError) {
self.userAgentSession = nil
continuation.resume(returning: nil)
} else {
self.userAgentSession = nil
continuation.resume(throwing: error)
}
}
}
}
}
@chauyong Having investigated more closely, I believe that the user shouldn't be directed to the default web browser, and remains in the app since AppAuth uses ASWebAuthenticationSession whenever possible (https://github.com/openid/AppAuth-iOS/blob/master/Sources/AppAuth/iOS/OIDExternalUserAgentIOS.m#L100), which on iOS, uses a "secure, embedded web view" (via Apple's docs). To clarify, there is actually no explicit usage of SFSafariViewController in >= iOS 12.0; ASWebAuthenticationSession is used instead.
Given the inability to repro and lack of code changes that seem relevant between v.1.7.6 and v2.0.0, would you/your team be able to retry an App Store submission with v2.0.0 of AppAuth? We've had no other reports of iOS apps being rejected, and v2.0.0 of AppAuth has been out since April.
Although our app has not been rejected, the issue we're experiencing is related to the same code and possibly explains why the local browser is used.
If calling ASWebAuthenticationSession start errors OIDExternalUserAgentIOS.m line #133, the code then continues (despite the error) and attempts to open the local browser line #139
Our solution was to modify the pod file to check that ASWebAuthenticationSession can actually start.
if (authenticationVC.canStart) {
openedUserAgent = [authenticationVC start];
}
Unfortunately this won't fix @chauyong issue, but it got us going because react-native-app-auth was able to resume the authentication session after redirecting from the browser.
Hi @ywsang and @camden-king . Im not sure if the issue that im having is related to this post. Im also facing suddenly this default web browser redirects, we haven't changed the implementation but suddenly on iOS 18 we notice that the agent was not opening a Safari controller, instead they are being redirected to the default browser, this provokes unwanted browser openings. To solve our issues for the moment, we created a custom user agent based on Safari Controller. I share you the agent that was provoking the issue: `guard let externalUserAgent = OIDExternalUserAgentIOS(presenting: presentingViewController, prefersEphemeralSession: true) else { return }
self.userAgentSession = OIDAuthorizationService.present(endSessionRequest,
externalUserAgent: externalUserAgent) { (response, error) in
if (error == nil) {
completion?(true)
}else {
completion?(false)
}
}`
Thanks.
@CarlosMerinoBHN are you able to consistently reproduce the default web browser opening?