I am helping to speak in Global AI Bootcamp 2022 (Hong Kong) on 14 January 2022. This event’s objective is to give younger generations more ideas and passion for AI. Speakers of this event include Eason Lai (Global Technology Strategist @ Microsoft; Microsoft AI MVP), Ricky Shiu (Data Scientist @ AIA Hong Kong and Macau), and Ken Lin (Senior Technical Consultant (APAC) @ Willis Towers Watson; Microsoft Dev rMVP). Please feel free to register and circulate.
The Transport Layer Security (TLS) 1.2 is a stadnard that provides security improvements over previous versions. More and more thrid-party APIs were configured to disable any requests from clients that were using TLS 1.0/1.1. So if your ASP.NET Web App or WebAPI Services Web Site will need to update to TLS 1.2 as well if your ASP.NET Web App or WebAPI Services Web Site has some calls to the third-party APIs, otherwise they will only return empty responses.
You could disable TLS 1.0/1.1 and only enable TLS 1.2 in your Web Server or in Azure, so that your hosting environments will no longer accept requests from earlier version of TLS.
But what happens on your application (ASP.NET Web App or WebAPI Services)? Depend on what version of .NET framework your project usrs will dicate the possible solutions available to you.
- If your project compiles against .NET Framework 4.7 or above, then you don’t have to do anything.
- If your project has been developed in a earlier version of .NET Framework, then you could either
- Recompile your project using .NET Framework 4.7 or above
- If recompiling is not an option, then you will have to update your .config file as below,
<configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"/> </runtime> <system.web> <compilation targetFramework="x.y.z" /> <httpRuntime targetFramework="x.y.z" /> </system.web> </configuration>
It is preferred that x.y.z are the same. So if your application is 4.6.2, then replacing x.y.z into 4.6.2.
Microsoft also has post a useful document on describing the best pratices to TLS 1.2. It will be great if you could read them all and understand them in order to fully secure your application(ASP.NET Web App or WebAPI Services).
In my last post, I showed how to enable CORS in ASP.NET WebAPI. I then found out that I have another issue when hosting it in Azure. Azure has a great supporting on the CORS. You could watch a video about how great it is, here
First, I would like to show you how to enable CORS in Azure.
1) Go to Azure portal, click into the App Service of your WebAPI.
2) Then under API Tag, click CORS.
3) Enter “*” or any specified website that you would like to allow CORS.
DONE! That is easy, isn’t it.
But then if you start running your mobile or website, and fire any jQuery to the WebAPI, you will find this error,
“SEC7128: Multiple Access-Control-Allow-Origin headers are not allowed for CORS response.”
If you check in Fiddler, you will find this,
This is because that Azure has enable the CORS and your app also enabled it. So it has more than one entries on “Access-Control-Allow-Origin” which the preflight request does not allow it. Now we could make some changes to the web.config under Azure,
- Go into Azure portal, Under “development Tools” tag and click “Advanced Tools”. In the Detail panel, click “GO”.
- A new browser will pop up and it is showing on the Kudu page.
- Now you have to click “Debug console” –> “CMD”
- An Azure command prompt shows with a window in upper area like a windows explorer which allowing us to browse into different directory in Azure.
- Now browse into “site” –> “wwwroot”, you could found your web.config here.
- In the left hand side, you could then click on the “Edit” (a pencil icon) to edit the web.config of the WebAPI in browser.
- Now you could comment both of the “Access-Control-Allow-Origin” and “Access-control-Allow-Methods”. And then click Save button in the upper area to save your changes.
DONE again. now your website will have only one entry of the “Access-control-Allow-Origin” and “Access-Control-Allow-Methods” and your client app now can fire any jQuery to the WebAPI without any error.
P.S., Azure has improved the handling of the CORS on the “OPTION” issue that I found from the last post.
You could also check here to learn more about the Kudu
If you read the Web API tutorials from docs.microsoft.com, all of them are teaching you to create the server app (Web API) and the client app (ASp.NET MVC) in the same solution. In fact, we usually separate the server and client application into separate applications. You will then find out the client application cannot call any Web API method in server application. It is because of the CORS.
Cross Origin Resource Sharing (CORS) is a W3C standard that allows a server to relax the same-origin policy. Using CORS, a server can explicitly allow some cross-origin requests while rejecting others. CORS is safer and more flexible than earlier techniques such as JSONP. This tutorial shows how to enable CORS in your Web API application.
If you application is ASP.NET Web API 2, now you could do the following to enable CORS
install Microsoft.AspNet.WebApi.Cors from Nuget
Open file App_Start/WebApiConfig.cs. In Register method, add this code config.EnableCors();
You can then adding “[EnableCors(origins: “https://localhost:8080”, headers: “*”, methods: “*”)]” to any method that you want to enable CORS
You could also add the following into Web.config, so that CORS will be enabled to all methods
<!-- Allow Web API to be called from a different domain. -->
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
Now your server application Web API is ready to serve other client applications’ calling. You could read more here, Enabling Cross-Origin Requests in ASP.NET Web API 2
Support HTTP Method ‘OPTIONS’
The requested resource does not support http method ‘OPTIONS’.
Most of the browser will send a Preflight Request before it sends the actual request. One of the conditions to skip the Preflight Request is “The request method is GET, HEAD, or POST”. if you search to solve it, you will find that most of the result are stating that you could add and remove some handler in web.config could help.
Someone reported that it really solve the problem, but it does not work in my environment. I then also found out that there is another work around and it really works for me. (This is also the main reason why I blog it down and share with you now.) We now adding some handling to the HTTP OPTIONS verb in BeginRequest method.
protected void Application_BeginRequest(object sender, EventArgs e)
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
If you check in Fiddler, now the Server Application Web API is accepting the OPTIONS method and response to your client app that the is now ready to receive your PUT/DELETE call.