maui
maui copied to clipboard
Allow mixed-content in MauiBlazorWebView
Description
I would like to start with that I've already read the responses about mixed-content and why not to allow it ... I do however disagree with the argumentation about security, it is too general to make decision about disallowing it at all. In fact I have a production case which supports the request to allow it for strictly specified URLs. The case: A sophisticated video analysis service provides output using http://127.0.0.1/video-stream/args?... for display. The video output is intended for display on the GUI but putting leads to error on the page: Mixed Content: The page at 'https://0.0.0.0/' was loaded over HTTPS, but requested an insecure element 'http://127.0.0.1:8100/video-stream/Z'. This request was automatically upgraded to HTTPS, For more information see https://blog.chromium.org/2019/10/no-more-mixed-messages-about-https.html Argumentation:
- The service is as is. Closed solution, black-box. So, no way I can modify it.
- For Android I see clearly here: https://docs.microsoft.com/en-us/dotnet/maui/android/platform-specifics/webview-mixed-content that some exceptions are allowed, why not for Windows?
- The approach with DotNetStreamReference does not work for infinite streams does it?
- Wrapping the service increases CPU bandwidth for SSL (especially for video) and adds certificate handling problems. Please consider it serious problem.
Public API Changes
It will be handy to have the ability to either add optional parameters to this call and provide some configuration: builder.Services.AddMauiBlazorWebView(); or, alternatively, by extending WebView interface so that exceptions can be added during application configuration phase. The seconds might be more useful in cases where the actual video data source is remote and the fact is known after handshake with external system (which fortunately can be made using httpclient)
Intended Use-Case
My intention is to use it in large scale integration where GUI developed in .net MAUI is intended to be used for operating a system with existing expensive video analysis hardware. Security of the system is assured with other means, while video source considered here is not source of threat. Summarizing: I see the blockage of plain HTTP as a serious showstopper for using .net MAUI as replacement for older GUI solutions and the platform for future development especially for integration projects.
@Eilon do you have any thoughts about this one? Looks like the ask here is to allow mixing both http and https content in WebView.
Hi @michal-puczynski , can you share an example of what exactly you'd like to enable for mixed-content? Is it a feature that's supported on each platform's WebView, but you're not sure how to enable it? If so, we provide fairly easy access to the platform-specific WebView that BlazorWebView internally creates so that you can customize it for your needs.
Please let us know if something like this would work for you:
In a default .NET MAUI Blazor app you can edit MainPage.xaml to wire up a new event handler that gets called when BlazorWebView is starting:
<BlazorWebView HostPage="wwwroot/index.html" BlazorWebViewInitialized="Bwv_BlazorWebViewInitialized">
...
Then, in the new event handler in MainPage.xaml.cs you can write code that enables any platform-specific features you need on that webview:
private void Bwv_BlazorWebViewInitialized(object sender, Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs e)
{
#if WINDOWS
e.WebView.CoreWebView2.Settings.Whatever = some_windows_value;
#elif ANDROID
e.WebView.SomeAndroidSetting = some_android_value;
#endif
}
Hi @michal-puczynski. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
Hi, The code you gave me as sample works, I mean I can modify settings, but indeed my request was about mixed-content and I do not see the way to enable it using the way provided. So, yes, I do not know how to enable it. I've reviewed all 7 setting interfaces of WebView and nearly entire WebView documentation, but still I do not know how to allow particular URI/URL or http entirely. I am hoping on adding the exceptions in runtime based on some configuration, but if that is not possible adding single URL pointing to local http proxy http://127.0.0.1:PORT/* will be good enough although a bit inconvenient. Thanks
Hi @michal-puczynski , I tested out this code on Android emulator and it worked. (Conversely, without the extra setting, it did not work.)
First, I added some <img> tags to one of the .razor files of the app (such as Counter.razor): I added one HTTPS image (should always work), and one HTTP image (won't work with default settings):
<img width="100" height="100" src="http://neverssl.com/favicon.ico" />
<img width="100" height="100" src="https://pngimg.com/uploads/pokemon/pokemon_PNG15.png" />
And if I run that in Android, I get this "failed image load" for the HTTP image:

To make this work, I changed two things:
- I configured the WebView on Android to support mixed content:
- In MainPage.xaml change the
<BlazorWebView>tag to register aBlazorWebViewInitializedevent handler:<BlazorWebView HostPage="wwwroot/index.html" BlazorWebViewInitialized="Bwv_BlazorWebViewInitialized"> - In MainPage.xaml.cs add code to configure the Android web view instance:
private void Bwv_BlazorWebViewInitialized(object sender, Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs e) { #if ANDROID e.WebView.Settings.MixedContentMode = Android.Webkit.MixedContentHandling.AlwaysAllow; #endif }
- In MainPage.xaml change the
- In
Platforms\Android\AndroidManifest.xmladd support for cleartext (non-HTTPS) traffic by settingandroid:usesCleartextTraffic="true":<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:usesCleartextTraffic="true"></application>
And then when I run the app, I get both the HTTP and HTTPS images displayed:

Please let us know if you can try this out and it works for your scenario.
Hi @michal-puczynski. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
Hi, Well, maybe it does for Android, but I need solution for Windows target. Android Emulator is not, neither bare Android device is my target. This I why I pointed out that there is a solution for Android listed in documentation, while there is no complementary solution for Windows.
@michal-puczynski on Windows it seemed to just work for me without anything. Were you seeing otherwise?
Hi @michal-puczynski. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
Well, let's see...
For the test I made a simple host running nginx and two servers, http and https. The certificate is from my own CA and added as trusted root to the machine. Chrome, Edge opens both URLs (screenshot, left side). Then, I run the fresh MAUI project, add the img tags with reference to these URLs (http://172.16.88.6:8080/testImage.png, https://172.16.88.6:8084/testImage.png) and the result is as on the screenshot. The https sourced image appears, while for http the WebView complains about mixed content and automatic upgrade of request to https, which fails.
Now, I've tried the same with Android emulator adding the MixedContent setting, and to my surprise it is even worse and much more complicated to potentially integrate external devices with Android, because Chromium engine that runs from the MAUI project does not listen to CA store of the device and, the opposite to Windows, https sourced image does not appear in the application.

Hi @michal-puczynski , I'm not sure why, but I simply couldn't get .NET MAUI BlazorWebView on Windows (WebView2) to refuse to load an HTTP image in any default scenario. I even set up a local ASP.NET Core web server that has HTTP only, so HTTPS would definitely fail, and even though I can see a mixed mode warning that says it upgraded to HTTPS, it still works!
But, I have looked into this further, and I wonder if you could use Content Security Policy (CSP) to set that you want to allow HTTP for certain hosts. You can set CSP either in an HTTP header (not really possible in BlazorWebView as far as I know), or you can do it in a <meta> tag in your app's index.html:
<head>
...
<meta http-equiv="Content-Security-Policy" content="img-src https: http://localhost:5088/" />
...
</head>
That CSP tag says that for <img src="..." /> to allow all HTTPS requests, and also the http://localhost:5088/ prefix. That seems to make things just as good as they were previously, and I also tested it on a pair of static web sites (one was HTTPS only, and referenced a separate site that was HTTP only).
Would you be able to test this and see it it helps?
Here are a few more CSP resources:
- CSP general content: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- Content-Security-Policy HTTP header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
- CSP img-src: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src
Hi Eilon,
Thanks for the hint, it explains some, but still does not lead to solution, because there is inconsistency in WebView behavior.
The CSP overrides default policy, which seems to be "allow localhost and 127.0.0.1".
If I add anything to img-src, then this source is allowed but only when it is https, except if this is localhost.
Example:
<meta http-equiv="Content-Security-Policy" content="img-src https: http://10.91.61.64:8080/ http://127.0.0.1:8080/ http://localhost:8080/" />
The above allows me to display images from:
- any https source
- the second does not work, because browser upgrades http to https which as a result does not exist
- any 127.0.0.1:8080 (localhost by IP) over http. although warning about upgrade to https appears
- any localhost:8080 over http, same with warning about upgrade to https
The inconsistency is about the http to https upgrade, warning is always present, but the actual upgrade does not take place for 127.0.0.1 and localhost.
The result of the inconsistency below:


@michal-puczynski I would suggest also asking on https://github.com/MicrosoftEdge/WebView2Feedback/issues/ because this is most likely an issue specific to WebView2, as opposed to what BlazorWebView is doing. But please let me know if you think BlazorWebView is doing something unusual or incorrect.
Hi, asking this to WebView2 was a good idea and let me make a step forward. There is "but" unfortunately.
If you add what they suggested using ENV, like this for example:
System.Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--unsafely-treat-insecure-origin-as-secure=http://192.168.0.1:8100");
It works, but has to be added before call to:
builder.Services.AddMauiBlazorWebView();
so, at very early stage, before anything else is initialized.
When I try to add this argument the more official way via "initializing" handler:
<b:BlazorWebView HostPage="wwwroot/index.html" BlazorWebViewInitialized="BlazorWebView_BlazorWebViewInitialized" BlazorWebViewInitializing="BlazorWebView_BlazorWebViewInitializing">
private void BlazorWebView_BlazorWebViewInitializing(object sender, BlazorWebViewInitializingEventArgs e) { #if WINDOWS e.EnvironmentOptions = new Microsoft.Web.WebView2.Core.CoreWebView2EnvironmentOptions { AdditionalBrowserArguments = "--unsafely-treat-insecure-origin-as-secure=http://192.168.0.1:8100" }; #endif }
then it does not work. Any idea why it fails then?
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I have a workaround - at least on Windows. No <meta> tags or special headers required.
In your MauiProgram.cs, before calling AddMauiBlazorWebView():
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--disable-features=AutoupgradeMixedContent");
I found this feature switch here: https://niek.github.io/chrome-features/
This prevents WebView2 from trying to upgrade mixed content urls.
PS: BlazorWebView_BlazorWebViewInitializing is too late.
Indeed. The --disable-features=AutoupgradeMixedContent combined with --unsafely-treat-insecure-origin-as-secure gets rid of most security warnings in webview's console. That probably solves my problems. I just wonder how long will these switches last in webview/chrome.
hi my problem is different. i have a video tag and android app works in local intranet. my server is ubuntu and using for hls streaming. when trying with hls.js stream http://192.168.195.176:8080/hls/stream.m3u8 because of http , blazorwebview does not allow it to load.
then i installed letsencrypt certificate with dns challenge and got certificates for ex: xxx.xyz domain
now when i hls stream in blazorwebview with: https://192.168.195.176/hls/stream.m3u8 certificates are untrusted.. so i again cant stream it..
i tried network_security_config.xml and applied it to android manifest as: android:usesCleartextTraffic="true" android:networkSecurityConfig="@xml/network_security_config"
and the xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.195.176</domain>
</domain-config>
<base-config>
<trust-anchors>
<!-- Trust preinstalled CAs -->
<certificates src="system" />
<!-- Additionaly trusted user added CAs -->
<certificates src="user"/>
</trust-anchors>
</base-config>
</network-security-config>
not worked.. then i tried
private void blazorWebView_BlazorWebViewInitialized(object sender, Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs e)
{
#if ANDROID
if(e.WebView.Settings.MixedContentMode != Android.Webkit.MixedContentHandling.AlwaysAllow)
{
e.WebView.Settings.MixedContentMode = Android.Webkit.MixedContentHandling.AlwaysAllow;
}
#endif
}
again not worked for both http and https. so there are 400 android clients in local network which does not have access to internet. i have to serve hls streaming.. help needed
I think you've landed exactly where I was months ago. BlazorWebViewInitialized seems to be far too late for security settings modifications, nothing actually works there. In my case the only thing that worked was applying environment modifications before WebView was created. I have no clue where it should be for android app (could be that somewhere else than for Windows), but for me setting mentioned in earlier posts WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS with --disable-features=AutoupgradeMixedContent to disable upgrading http to https and adding --unsafely-treat-insecure-origin-as-secure={spec}, where spec is the list of hosts to allow, like this: http://192.168.195.176/. Try adding the entire subnets.
I faced a similar issue with Blazor Maui on Android. I can't load images from my development server at home, followed the solutions in this issue and others, but it didn't work for me. After searching and struggling with this problem, I applied the solution in this link and the problem has been solved for me, the main difference is I'm using mkcert instead of Openssl. I mention this solution may help someone in the future.
I had the similar issue, fetching from http (localhost without ssl) in javascript will fail by default on Android. I am not sure about it on iOS.
And Eilon's approach works like a charm. Thanks @Eilon.
And off the topic, I echo michal's point of view on the over-rigid mixed-content security. http is much but not all about the internet. In my case I use http for cross-process communication within localhost.
We've discussed this a bit more in the team and have decided that there isn't a one solution fits all approach to take here. To enable mixed content the configuration that some of you have already came across are very specific to the application that you're developing and apps are the best place to have that configured. We don't think that this is something we should bake into the framework.