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

Xamarin WebView原生弹窗开发:Xamarin审核默认身份验证实现代码求分享

Xamarin WebView默认身份验证功能实现方案

以下为全平台可直接复用的实现代码,支持默认自动填充身份信息、原生弹窗手动输入两种模式:

共享层自定义WebView控件

using Xamarin.Forms;

namespace YourAppNamespace.Controls
{
    public class AuthenticatedWebView : WebView
    {
        // 默认身份信息绑定属性
        public static readonly BindableProperty DefaultUsernameProperty =
            BindableProperty.Create(nameof(DefaultUsername), typeof(string), typeof(AuthenticatedWebView), string.Empty);

        public static readonly BindableProperty DefaultPasswordProperty =
            BindableProperty.Create(nameof(DefaultPassword), typeof(string), typeof(AuthenticatedWebView), string.Empty);

        public string DefaultUsername
        {
            get => (string)GetValue(DefaultUsernameProperty);
            set => SetValue(DefaultUsernameProperty, value);
        }

        public string DefaultPassword
        {
            get => (string)GetValue(DefaultPasswordProperty);
            set => SetValue(DefaultPasswordProperty, value);
        }
    }
}

Android平台自定义渲染器

using Android.App;
using Android.Content;
using Android.Webkit;
using Android.Widget;
using YourAppNamespace.Controls;
using YourAppNamespace.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(AuthenticatedWebView), typeof(AuthenticatedWebViewRenderer))]
namespace YourAppNamespace.Droid.Renderers
{
    public class AuthenticatedWebViewRenderer : WebViewRenderer
    {
        public AuthenticatedWebViewRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            if (Control == null || e.NewElement == null) return;
            Control.SetWebViewClient(new AuthWebViewClient((AuthenticatedWebView)e.NewElement));
            Control.Settings.JavaScriptEnabled = true;
        }

        private class AuthWebViewClient : WebViewClient
        {
            private readonly AuthenticatedWebView _authWebView;
            public AuthWebViewClient(AuthenticatedWebView webView) => _authWebView = webView;

            public override void OnReceivedHttpAuthRequest(Android.Webkit.WebView view, HttpAuthHandler handler, string host, string realm)
            {
                // 模式1:直接使用默认身份信息完成验证,无需弹窗
                handler.Proceed(_authWebView.DefaultUsername, _authWebView.DefaultPassword);
                
                // 模式2:弹出原生弹窗让用户手动输入,注释上面一行,放开以下代码即可
                /*
                var alertBuilder = new AlertDialog.Builder(view.Context);
                alertBuilder.SetTitle("身份验证");
                var inflater = LayoutInflater.From(view.Context);
                var authLayout = inflater.Inflate(Resource.Layout.AuthDialog, null);
                var userInput = authLayout.FindViewById<EditText>(Resource.Id.et_username);
                var pwdInput = authLayout.FindViewById<EditText>(Resource.Id.et_password);
                alertBuilder.SetView(authLayout);
                alertBuilder.SetPositiveButton("确认", (s, args) => handler.Proceed(userInput.Text, pwdInput.Text));
                alertBuilder.SetNegativeButton("取消", (s, args) => handler.Cancel());
                alertBuilder.Show();
                */
            }
        }
    }
}

iOS平台自定义渲染器

using Foundation;
using UIKit;
using WebKit;
using YourAppNamespace.Controls;
using YourAppNamespace.iOS.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(AuthenticatedWebView), typeof(AuthenticatedWebViewRenderer))]
namespace YourAppNamespace.iOS.Renderers
{
    public class AuthenticatedWebViewRenderer : WkWebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            if (e.NewElement == null) return;
            NavigationDelegate = new AuthNavigationDelegate((AuthenticatedWebView)e.NewElement);
        }

        private class AuthNavigationDelegate : WKNavigationDelegate
        {
            private readonly AuthenticatedWebView _authWebView;
            public AuthNavigationDelegate(AuthenticatedWebView webView) => _authWebView = webView;

            public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, System.Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
            {
                if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodHTTPBasic)
                {
                    // 模式1:直接使用默认身份信息完成验证,无需弹窗
                    var credential = new NSUrlCredential(_authWebView.DefaultUsername, _authWebView.DefaultPassword, NSUrlCredentialPersistence.ForSession);
                    completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
                    
                    // 模式2:弹出原生弹窗让用户手动输入,注释上面两行,放开以下代码即可
                    /*
                    var alert = UIAlertController.Create("身份验证", "请输入访问凭据", UIAlertControllerStyle.Alert);
                    alert.AddTextField(tf => tf.Placeholder = "账号");
                    alert.AddTextField(tf => 
                    {
                        tf.Placeholder = "密码";
                        tf.SecureTextEntry = true;
                    });
                    alert.AddAction(UIAlertAction.Create("确认", UIAlertActionStyle.Default, _ =>
                    {
                        var user = alert.TextFields[0].Text;
                        var pwd = alert.TextFields[1].Text;
                        var inputCred = new NSUrlCredential(user, pwd, NSUrlCredentialPersistence.ForSession);
                        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, inputCred);
                    }));
                    alert.AddAction(UIAlertAction.Create("取消", UIAlertActionStyle.Cancel, _ =>
                    {
                        completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);
                    }));
                    UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
                    */
                    return;
                }
                completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null);
            }
        }
    }
}

页面调用示例

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:YourAppNamespace.Controls"
             x:Class="YourAppNamespace.WebDemoPage">
    <controls:AuthenticatedWebView 
        DefaultUsername="test_account"
        DefaultPassword="test_pwd123"
        Source="https://your-need-auth-target-url.com"
        HorizontalOptions="FillAndExpand"
        VerticalOptions="FillAndExpand"/>
</ContentPage>

注意事项

  • 代码中所有YourAppNamespace需要替换为你项目的实际命名空间
  • Android端如果使用手动输入弹窗模式,需要自行在Resources/layout下添加对应的AuthDialog布局文件
  • 已废弃的UIWebView不兼容当前iOS代码,推荐所有iOS项目统一使用WkWebView

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:54:04