.NET MAUI iOS客户端中Duende IdentityServer PostLogoutRedirectUri始终为空
问题:MAUI iOS应用登出时IdentityServer的PostLogoutRedirectUri为空,无法跳转回应用
我使用Duende IdentityServer 7作为身份提供商,基于.NET MAUI开发iOS应用。已在IdentityServer中为客户端注册了RedirectUri和PostLogoutRedirectUri,登录流程正常,但登出流程存在问题:IdentityServer中的PostLogoutRedirectUri始终为空,导致无法跳转回应用,卡在浏览器界面。
.NET MAUI客户端配置代码
private static void AddService(this IServiceCollection services) { services.AddTransient<WebAuthenticatorBrowser>(); services.AddTransient<OidcClient>(sp => new OidcClient(new OidcClientOptions { Authority = "https://identity-url", ClientId = "CLientId", RedirectUri = "myapp://", PostLogoutRedirectUri = "myapp://", Scope = "scope1 scope2", Browser = sp.GetRequiredService<WebAuthenticatorBrowser>(), DisablePushedAuthorization = false }) ); }
登出调用代码
最初的调用方式:
LogoutRequest logoutRequest = new LogoutRequest(); LogoutResult? logoutResult = await OidcClient.LogoutAsync(logoutRequest);
尝试过添加IdTokenHint,但无效果:
LogoutRequest logoutRequest = new LogoutRequest { IdTokenHint = token }; LogoutResult? logoutResult = await OidcClient.LogoutAsync(logoutRequest);
IdentityServer端LoggedOut页面代码
[SecurityHeaders] [AllowAnonymous] public class LoggedOut : PageModel { private readonly IIdentityServerInteractionService _interactionService; public LoggedOutViewModel View { get; set; } = new(); public LoggedOut(IIdentityServerInteractionService interactionService) { _interactionService = interactionService; } public async Task OnGet(string logoutId) { LogoutRequest logout = await _interactionService.GetLogoutContextAsync(logoutId); View = new LoggedOutViewModel { AutomaticRedirectAfterSignOut = LogoutOptions.AutomaticRedirectAfterSignOut, PostLogoutRedirectUri = logout.PostLogoutRedirectUri ?? "", ClientName = string.IsNullOrEmpty(logout.ClientName) ? logout.ClientId ?? string.Empty : logout.ClientName, SignOutIframeUrl = logout.SignOutIFrameUrl ?? string.Empty, }; } }
问题排查与修复方案
1. 显式指定登出请求的PostLogoutRedirectUri
OidcClient默认可能不会自动传递PostLogoutRedirectUri,需要在登出请求中显式声明:
var logoutRequest = new LogoutRequest { IdTokenHint = token, PostLogoutRedirectUri = "myapp://" // 与OidcClientOptions中的配置保持一致 }; var logoutResult = await OidcClient.LogoutAsync(logoutRequest);
2. 验证IdentityServer客户端注册配置
确保客户端的PostLogoutRedirectUris集合中确实包含myapp://,同时注意ClientId的大小写与MAUI端一致:
new Client { ClientId = "CLientId", // 必须与MAUI端配置完全匹配 // 其他配置项... RedirectUris = { "myapp://" }, PostLogoutRedirectUris = { "myapp://" }, // ... }
3. 检查WebAuthenticatorBrowser实现
如果自定义了浏览器实现,需确保它正确传递所有回调参数。标准实现示例:
public class WebAuthenticatorBrowser : IBrowser { public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default) { var authResult = await WebAuthenticator.Default.AuthenticateAsync( new Uri(options.StartUrl), new Uri(options.EndUrl)); var result = new BrowserResult { Response = authResult.Properties.Select(p => $"{p.Key}={Uri.EscapeDataString(p.Value)}") .Aggregate((a, b) => $"{a}&{b}") }; return result; } }
4. 确认iOS URL Scheme配置
在MAUI项目的Platforms/iOS/Info.plist中添加URL Scheme注册:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array>
5. 启用IdentityServer自动跳转
确保LogoutOptions.AutomaticRedirectAfterSignOut设置为true,同时在LoggedOut页面视图(如LoggedOut.cshtml)中添加自动跳转逻辑:
@if (Model.AutomaticRedirectAfterSignOut && !string.IsNullOrEmpty(Model.PostLogoutRedirectUri)) { <script> window.location.href = '@Model.PostLogoutRedirectUri'; </script> }
内容的提问来源于stack exchange,提问作者Sara Mannings
相关产品推荐
相关产品推荐

