Adding Authorization Header in Web View

So, this is my second post about web view. Still from my last project, I had to deal with some problems regarding web view. One of them was adding authorization header in web view. When I look up on net, there were so many answers, but most of them didn’t work for me. So, I thought I should share which method that works for me.

Android Web View Renderer

In Android, I simply put the Authorization header on web view renderer. In some forums, there’re some different opinions about where we should put this header, like put it in web chrome client, but those methods didn’t work in my case. So, this is how I added the authorization header in my project.

public class HybridWebViewRenderer : WebViewRenderer
{
    public HybridWebViewRenderer(Context context) : base(context)
    { }
    public HybridWebViewRenderer(){ }

    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        var webView = Control as Android.Webkit.WebView;
        var Token = Settings.AccessToken;

        Dictionary headers = new Dictionary()
        {
            {"Authorization", "Bearer " + Token }
        };
        this.Control.LoadUrl(Control.Url, headers);
    }

}

I put it on OnElementChanged method, as a result, whenever the user navigate to other page in web view, causing the url changed, this method will be fired. So, the header will be added whenever user make new request in web view.

iOS Web View Delegate

Different from it’s Android counter part, we can’t add the Authorization header on web view renderer in iOS, we have to put it on web view delegate. In iOS web view delegate, there’s a method called ShouldStartLoad

Just like its name, this method is fired whenever the web view load new page. So, it’s actually pretty similar with the Android, but the way this method works is little bit different. In Nutshell, what we gonna do in this method are :

  1. Checking if the request has Authorization Header
  2.  If not, Copy the request and then add the header to the copied request.
  3. Cancel the original request without Authorization Header
  4. If the request already has the header, just let it through

So, this how it looks like in real code.

public class HybridWebViewRenderer : WebViewRenderer
{
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        Delegate = new HybridUiWebViewDelegate(this);

        this.ScrollView.DecelerationRate = UIScrollView.DecelerationRateNormal;
        var webView = e.NewElement as HybridWebView;
    }

}

public class HybridUiWebViewDelegate : UIWebViewDelegate
{
    public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
    {
        if (!request.Headers.ContainsKey(new NSString("Authorization")))
        {
            var copy = request.MutableCopy() as NSMutableUrlRequest;
            var token = Settings.AccessToken;

            NSMutableDictionary dic = new NSMutableDictionary();
            dic.Add(new NSString("Authorization"), new NSString("Bearer " + token));
            copy.Headers = dic;

           string currentUrl = request.Url.ToString();

           if (currentUrl.ToLower() != StaticVariables.CurrentUrl.ToLower())
           {
               StaticVariables.CurrentUrl = currentUrl;
               StaticVariables.NavigationStack.Add(currentUrl);
           }

           webView.LoadRequest(copy);

           return false;
      }
      return true;
    }
}

Hope this method also works for you.

Advertisements

23 thoughts on “Adding Authorization Header in Web View

    1. Hi Ben, sorry for late reply. The source code above is all you need. I think I already explain it step by step, but if there’s any part you don’t understand, feel free to ask. As for UWP, I’m sorry but I never done any UWP project so I’m afraid I could be misleading if try to answer that. Thank you.

      Like

    1. Hi Stefano,
      I declared Static Variables in shared project. So, I have one dedicated class for static variables that works as Global Variables that can be accessed from anywhere. Thank you.

      Like

  1. HI Wisnu WH
    Thanks for your shared code. 🙏🏻🌹
    I’m new in Xamarin.forms

    i get this error: ElementChangedEventArgs requried 1 types argument.
    and i have an webview in my contentpage. this header automatically add to tthe webview or i have to add another class in my shared project?

    Could you please help me?
    Best Regards

    Like

    1. Dear Wisnu WH
      I add WebView as paramenter for ElementChangedEventArgs

      In my Share Project Xaml page:

      In my Android project:
      namespace MyProject.Droid.Renderers
      {
      public class HybridWebViewRenderer : WebViewRenderer
      {
      public HybridWebViewRenderer(Context context) : base(context)
      { }
      public HybridWebViewRenderer() { }

      protected override void OnElementChanged(ElementChangedEventArgs e)
      {
      base.OnElementChanged(e);
      var webView = Control as Android.Webkit.WebView;
      var Token = Settings.AccessToken;

      var headers = new Dictionary { { “Authorization”, “Bearer ” + Token } };
      this.Control.LoadUrl(Control.Url, headers);
      }

      }
      }

      But it doesn’t work. Please me how can i authorize my webview.
      Best Regards

      Like

    1. Hi Mehdinuke,

      I’m not sure why you get that error, but try change onElementChanged method into this

      protected override void OnElementChanged(ElementChangedEventArgs < Xamarin.Forms.WebView > e){}

      Hope this can solve the problem.

      Cheers,
      Wisnu

      Like

      1. Dear Wisnu WH

        Thanks alot for your reply. 🌹🌹🌹

        Could you please help me how can i do this? : 🌹🌹
        When my xaml page loaded, My WebView source is null. I set that when a button have been clicked, my url would be assign to my WebView source.
        I checked the class HybridWebViewRenderer and it didn’t invoke.

        Best Regards

        Like

      2. Dear Wisnu
        Thanks alot for your reply.
        i added webview after click programtically, but the HybridWebViewRenderer has not been invoked. Could you please help me, what is my issue?
        Best Regards

        Like

      3. In the button click handler (Shared Project):
        WebView webView = new WebView();
        webView.HorizontalOptions = LayoutOptions.FillAndExpand;
        webView.VerticalOptions = LayoutOptions.FillAndExpand;
        webView.Source = “http://google.com”;
        var st = ((sender as Button)?.Parent) as StackLayout;
        st.Children.Add(webView);

        In the my android project class:
        public class HybridWebViewRenderer : WebViewRenderer
        {
        public HybridWebViewRenderer(Context context) : base(context)
        { }
        public HybridWebViewRenderer() { }

        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
        base.OnElementChanged(e);
        var webView = Control as Android.Webkit.WebView;
        var Token = Settings.AccessToken;

        var headers = new Dictionary { { “Authorization”, “Bearer ” + Token } };
        webView.LoadUrl(Control.Url, headers);
        }

        }

        Like

  2. Hi Mehdinuke,

    I recommend you to read Xamarin documentation about custom renderer so you can get a grip how this is works. Let me summarize the steps you need to follow :

    1. Create custom class in shared project by inherited Xamarin element you want to render. In your case is WebView. The class will looks like this

    public class HybridWebView : WebView {}

    In that class you add properties or method, like reload, if you want to, but for now let it be empty class.

    2. Create renderer in you Android/iOS project and connect it to your custom class.

    [assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
    namespace YourProject.Droid.YourFolders
    {
    public class HybridWebViewRenderer : WebViewRenderer
    {
    public HybridWebViewRenderer(Context context) : base(context)
    {

    }
    public HybridWebViewRenderer() { }
    }
    }

    Look at the keyword assembly above the namespace, that’s how you do it.

    3. Use you custom class, it can be in XAML on in your case, in code behind.

    HybridWebView webView = new HybridWebView();
    webView.HorizontalOptions = LayoutOptions.FillAndExpand;
    webView.VerticalOptions = LayoutOptions.FillAndExpand;
    webView.Source = “http://google.com”;
    var st = ((sender as Button)?.Parent) as StackLayout;
    st.Children.Add(webView);

    Hope this works for you.

    Cheers,
    Wisnu

    Like

    1. Dear Wisnu
      Thank you soooooooooooooooooooo much 🌹🌹🌹🙏🏻🙏🏻🙏🏻🌹🌹🌹🙏🏻🙏🏻🙏🏻🌹🌹🌹🙏🏻🙏🏻🙏🏻

      Best Reagrds,
      Mehdi

      Like

    2. Dear Wisnu
      I fixed my code according to your great guide. 🌹🌹🙏🏻🙏🏻
      I have an issue. I dont know how can i fix it. 😦
      I get error of Unauthorize (Access is denided).
      Could you please help me, how can i fix it?

      protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
      {
      if (e.PropertyName != “Source”) return;
      base.OnElementPropertyChanged(sender, e);
      var webView = sender as Android.Webkit.WebView;
      var token = Settings.AccessToken;

      var headers = new Dictionary { { “Authorization”, “Bearer” + token } };
      webView?.LoadUrl(Control.Url, headers);
      }

      token has correct value. 👆🏻

      Best Regards

      Like

      1. Hi Mehdi,

        So you’ve successfully called OnPropertyChanged? And Unauthorized error is from the web page you try to load right? Try add space after the word Bearer, so it would look like this “Bearer “ + token

        Hopefully this helps.

        Wisnu

        Like

  3. Dear Wisnu
    Thank you soooooooooooo much for you reply 🌹🌹🌹🌹🌹🌹🌹🌹
    It was my mistake!! I had used source property!!!!
    I defined uri property in my shared project class and used it in the xaml and renderer class.

    Thank you sooooooo much for your complete explaining. 🌹🌹😘😘😘😘

    Best Reagrds
    Mehdi

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s