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

UWP下WabBrowser启动前清除缓存及AD认证密码传输异常求助

在UWP中使用WebAuthenticationBroker实现AD认证时清除缓存的方案

我在UWP项目里用基于WebAuthenticationBroker实现的WabBrowser做AD认证,现在遇到输入用户名密码后密码传不到后端的问题,想在打开WabBrowser前清除缓存,该怎么实现?

WabBrowser实现代码

public class WabBrowser : IBrowser
{
    private readonly bool _enableWindowsAuthentication;

    public WabBrowser(bool enableWindowsAuthentication = false)
    {
        _enableWindowsAuthentication = enableWindowsAuthentication;
    }

    private async Task<BrowserResult> InvokeAsyncCore(BrowserOptions options, bool silentMode)
    {
        var wabOptions = WebAuthenticationOptions.None;

        if (_enableWindowsAuthentication)
        {
            wabOptions |= WebAuthenticationOptions.UseCorporateNetwork;
        }
        if (silentMode)
        {
            wabOptions |= WebAuthenticationOptions.SilentMode;
        }

        WebAuthenticationResult wabResult;

        try
        {
            if (string.Equals(options.EndUrl, WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri, StringComparison.Ordinal))
            {
                wabResult = await WebAuthenticationBroker.AuthenticateAsync(
                    wabOptions, new Uri(options.StartUrl));
            }
            else
            {
                if (string.IsNullOrWhiteSpace(options.EndUrl))
                {
                    wabResult = await WebAuthenticationBroker.AuthenticateAsync(
                    wabOptions, new Uri(options.StartUrl), WebAuthenticationBroker.GetCurrentApplicationCallbackUri());
                }
                else
                {
                    wabResult = await WebAuthenticationBroker.AuthenticateAsync(
                    wabOptions, new Uri(options.StartUrl), new Uri(options.EndUrl));
                }
            }
        }
        catch (Exception ex)
        {
            Utility.WriteErrorsToLogViaMessenger("WabBrowser-InvokeAsyncCore", ex);

            return new BrowserResult
            {
                ResultType = BrowserResultType.UnknownError,
                Error = ex.ToString()
            };
        }

        if (wabResult.ResponseStatus == WebAuthenticationStatus.Success)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.Success,
                Response = wabResult.ResponseData
            };
        }
        else if (wabResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.HttpError,
                Error = string.Concat(wabResult.ResponseErrorDetail.ToString())
            };
        }
        else if (wabResult.ResponseStatus == WebAuthenticationStatus.UserCancel)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.UserCancel
            };
        }
        else
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.UnknownError,
                Error = "Invalid response from WebAuthenticationBroker"
            };
        }
    }
    
    public async Task<BrowserResult> InvokeAsync(BrowserOptions options)
    {
        
        if (string.IsNullOrWhiteSpace(options.StartUrl)) throw new ArgumentException("Missing StartUrl", nameof(options));
        //if (string.IsNullOrWhiteSpace(options.EndUrl)) throw new ArgumentException("Missing EndUrl", nameof(options))

        switch (options.DisplayMode)
        {
            case DisplayMode.Visible:
                return await InvokeAsyncCore(options, false);

            case DisplayMode.Hidden:
                var result = await InvokeAsyncCore(options, true);
                if (result.ResultType == BrowserResultType.Success)
                {
                    return result;
                }
                else
                {
                    result.ResultType = BrowserResultType.Timeout;
                    return result;
                }
        }

        throw new ArgumentException("Invalid DisplayMode", nameof(options));
    }

    public Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
    {
        return InvokeAsync(options);
    }
}

调用WabBrowser的代码

private static OidcClientOptions GetOidcOptions(bool isEnableWindowsAuthentication=false)
{
    string logInfo = "OidcClient Options: RedirectUri: " + WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri;
    Utility.WriteErrorsToLogViaMessenger("IdentityManager-GetOidcOptions", new Exception(logInfo));

    string address = Utility.ReplaceLastOccurrence(Global.ServerUrlAuth, "/" + Global.Identifier, string.Empty).TrimEnd('/');
  
    return new OidcClientOptions
    {
        Authority = address, 
        ClientId = "boardpac.openid.windows",
        Scope = ApplicationConstants.ScopeForIdentityManager,
        RedirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri,
        Browser = new WabBrowser(enableWindowsAuthentication: isEnableWindowsAuthentication),
        PostLogoutRedirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri,
    };
}

清除缓存的实现方案

WebAuthenticationBroker没有直接提供清除缓存的API,可通过以下几种方式实现目标:

1. 强制禁用请求缓存

在构造认证请求的StartUrl时,添加随机参数避免加载缓存页面,确保每次从服务器获取最新认证表单:

// 在InvokeAsyncCore方法中修改StartUrl
var startUri = new Uri($"{options.StartUrl}?nocache={DateTime.UtcNow.Ticks}");
// 后续认证请求使用startUri替代原options.StartUrl

2. 启用ForceLogout选项(针对AD认证场景)

如果开启了Windows认证(UseCorporateNetwork),添加ForceLogout选项强制清除会话凭据缓存,确保新输入的用户名密码能正确传递:

if (_enableWindowsAuthentication)
{
    wabOptions |= WebAuthenticationOptions.UseCorporateNetwork;
    // 添加该选项强制清除AD凭据缓存
    wabOptions |= WebAuthenticationOptions.ForceLogout;
}

3. 清除应用WebView缓存(补充方案)

WabBrowser底层依赖WebView组件,可直接清除应用的WebView缓存目录:

using Windows.ApplicationModel.Core;
using Windows.Storage;

// 在打开WabBrowser前调用此方法
public async Task ClearWebCacheAsync()
{
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        try
        {
            var cacheFolder = await ApplicationData.Current.LocalCacheFolder.GetFolderAsync("WebView");
            await cacheFolder.DeleteAsync(StorageDeleteOption.PermanentDelete);
        }
        catch (FileNotFoundException)
        {
            // 缓存目录不存在时忽略
        }
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:34:56