使用WebAuthenticator.AuthenticateAsync移动端重定向失败问题
问题分析与解决方案
核心问题
你使用的https://myapps.microsoft.com/signin/...是微软企业应用门户的登录入口,该流程仅适用于Web端或已完成SSO配置的企业应用跳转,并非Azure AD OAuth2的标准授权端点。Azure AD无法识别此流程下的自定义移动端回调URI,因此出现「Undefined Sign-on URL for app 'Mobile SSO'」错误,导致回调无法触发。
修复步骤
1. 切换到Azure AD标准OAuth2授权端点
替换原有的authRequestUrl为Azure AD官方授权端点,格式如下:
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize? client_id={clientId} &response_type=code &redirect_uri={urlEncodedCallbackUrl} &response_mode=fragment &scope=openid%20profile%20offline_access &state=12345
参数说明:
tenantId:你的Azure AD租户ID(示例值:ab12ac17-4321-acbd-1234-72aae60ed1ca6)clientId:Azure AD中注册的移动端应用客户端ID(注意:不是企业应用的ID)urlEncodedCallbackUrl:对mobile://myapp进行URL编码后的结果(即mobile%3A%2F%2Fmyapp)
修改后的ViewModel代码:
async Task<bool> SSOLogin() { ErrorMessage = string.Empty; try { var tenantId = "ab12ac17-4321-acbd-1234-72aae60ed1ca6"; var clientId = "2borno2-1234-abcd-baba-42aaa70ab1da"; // 确保是移动端应用的clientId var callbackUrl = "mobile://myapp"; var encodedCallback = Uri.EscapeDataString(callbackUrl); var authRequestUrl = new Uri($"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&redirect_uri={encodedCallback}&response_mode=fragment&scope=openid%20profile%20offline_access&state=randomState123"); var authResult = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions { Url = authRequestUrl, CallbackUrl = new Uri(callbackUrl), PrefersEphemeralWebBrowserSession = true }); // 用授权码换取access_token(需补充Token交换逻辑) var accessToken = await ExchangeCodeForToken(authResult.Code, callbackUrl, clientId, tenantId); return true; } catch(Exception e) { var msg = e.Message; } finally { IsBusy = false; } return false; }
2. 确认Azure AD应用配置
- 在Azure AD中注册移动/桌面应用(而非Web应用),在「身份验证」页面添加重定向URI,类型选择「移动和桌面应用」,值为
mobile://myapp。 - 核对客户端ID:必须是注册的移动端应用ID,而非企业应用的ID(原myapps链接中的ID是企业应用ID,属于错误配置)。
3. 补充授权码换Token逻辑
由于使用response_type=code,WebAuthenticator返回的authResult.Code需要调用Azure AD的Token端点换取最终的access_token,示例代码:
async Task<string> ExchangeCodeForToken(string code, string callbackUrl, string clientId, string tenantId) { var tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token"; var formContent = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("grant_type", "authorization_code"), new KeyValuePair<string, string>("client_id", clientId), new KeyValuePair<string, string>("code", code), new KeyValuePair<string, string>("redirect_uri", callbackUrl), new KeyValuePair<string, string>("scope", "openid profile offline_access") }); using var client = new HttpClient(); var response = await client.PostAsync(tokenEndpoint, formContent); response.EnsureSuccessStatusCode(); var tokenResponse = await response.Content.ReadFromJsonAsync<TokenResponse>(); return tokenResponse.AccessToken; } // 定义Token响应模型 public class TokenResponse { [JsonPropertyName("access_token")] public string AccessToken { get; set; } [JsonPropertyName("refresh_token")] public string RefreshToken { get; set; } [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } }
4. 验证回调Activity配置
你当前的WebAuthenticationCallbackActivity配置是正确的,Exported=true和DataScheme="mobile"的IntentFilter已满足要求,无需修改。
内容的提问来源于stack exchange,提问作者Dizzy
相关产品推荐
相关产品推荐

