You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中MSAL Azure OAuth触发localhost重定向循环的求助

解决iOS Azure OAuth登录后重定向循环问题

问题核心

你当前的配置混淆了两种回调模式:使用Supabase的Web回调URI时,Supabase完成OAuth授权后会默认重定向到http://localhost:3000,而应用内浏览器无法处理该本地地址,导致循环跳转;尝试深度链接时因配置不完整报错,未解决根本问题。

分步修复方案

1. 统一采用APP深度链接作为回调目标

放弃Supabase的Web回调,全程使用APP自定义URL Scheme作为MSAL、Microsoft Entra ID、Supabase的统一回调地址:

  • Microsoft Entra ID配置:在应用注册的「移动和桌面应用」分类下添加重定向URI,格式为msauth.<你的Bundle ID>://auth(例如msauth.com.yourteam.yourapp://auth)。
  • Info.plist配置:添加URL类型与查询白名单,确保系统能识别你的深度链接:
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>msauth.com.yourteam.yourapp</string>
            </array>
            <key>CFBundleURLName</key>
            <string>com.yourteam.yourapp</string>
        </dict>
    </array>
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>msauthv2</string>
        <string>msauthv3</string>
    </array>
    

2. 修正MSAL配置

将MSAL的重定向URI改为你的深度链接,确保与Entra ID配置一致:

private func getMSALConfiguration() -> MSALPublicClientApplicationConfig {
    let kClientID = "********-****-****-****-********ea7a5"
    // 替换为你的深度链接
    let kRedirectUri = "msauth.com.yourteam.yourapp://auth"
    let kAuthority = "https://login.microsoftonline.com/organizations"
    
    guard let authorityURL = URL(string: kAuthority) else {
        fatalError("无法创建Authority URL")
    }
    
    do {
        let msalAuthority = try MSALAADAuthority(url: authorityURL)
        return MSALPublicClientApplicationConfig(
            clientId: kClientID,
            redirectUri: kRedirectUri,
            authority: msalAuthority
        )
    } catch {
        fatalError("创建MSAL配置失败: \(error)")
    }
}

3. 同步Supabase Auth配置

在Supabase控制台的Azure OAuth设置中,将Redirect URI设置为同一个深度链接,确保Supabase授权完成后能正确跳转回APP。

4. 完善APP的URL回调处理

确保APP能同时处理MSAL和Supabase的回调请求:

@main
struct MyApp: App {
    @State private var authManager = AuthViewModel()
    @State private var client = SupabaseClient(
        supabaseURL: URL(string: "你的Supabase URL")!,
        supabaseKey: "你的Supabase匿名密钥"
    )
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(authManager)
                .onOpenURL { url in
                    // 先让MSAL处理回调
                    MSALPublicClientApplication.handleMSALResponse(url)
                    // 再让Supabase完成Auth流程
                    Task {
                        try await client.auth.handle(url)
                    }
                }
        }
    }
}

5. 简化登录流程(可选但推荐)

避免手动获取Token后调用Supabase接口,直接使用Supabase的OAuth跳转流程,减少手动处理的出错概率:

func signInWithAzure() async {
    do {
        let authURL = try await client.auth.signInWithOAuth(
            provider: .azure,
            redirectTo: URL(string: "msauth.com.yourteam.yourapp://auth")!
        )
        
        let session = ASWebAuthenticationSession(
            url: authURL,
            callbackURLScheme: "msauth.com.yourteam.yourapp"
        ) { callbackURL, error in
            guard let callbackURL = callbackURL else { return }
            Task {
                try await client.auth.handle(callbackURL)
                // 登录成功后的业务逻辑
            }
        }
        session.presentationContextProvider = self
        session.start()
    } catch {
        dump(error)
    }
}

// 实现ASWebAuthenticationPresentationContextProviding协议
extension AuthViewModel: ASWebAuthenticationPresentationContextProviding {
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return UIApplication.shared.windows.first ?? ASPresentationAnchor()
    }
}

额外验证项

  • 确认Entra ID应用注册的API权限已添加User.Read(必填,否则无法获取用户基本信息)
  • Supabase的Azure配置中,Tenant ID填写organizations或你的实际租户ID(不要留空)
  • 测试前清理APP缓存,重启模拟器/物理设备

内容的提问来源于stack exchange,提问作者cyril

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:53:15