Receive (and send) XML through POST using ASP.NET

I need to configure an XML "web service" that receives a POST, where the Content-type header will indicate "text / xml".

What is the easiest way to get XML in XDocument for VB.NET axis access?

I do not believe that the web service is guaranteed to follow any protocol (for example, SOAP, etc.); only certain tags and subtags for various requests, and it will use basic authentication, so I will have to handle the headers.

(If it matters:
* live version will use HTTPS, and
* the answer will also be XML.)

+4
source share
3 answers

Given Stevenโ€™s warning, the answer might be to parse Request.InputStream first with the Tom Holland test and then XDocument.Load in Page_Load .

A Google search that started before I asked a question, but only checked it, found this one , also suggesting that I be on the right track.

In addition, I was about to ask the question, implied by my point of view, that the answer should have been XML too, regarding what is best for this, but I found the answer.

So the final code is:

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Request.ContentType <> "text/xml" Then _ Throw New HttpException(500, "Unexpected Content-Type") Dim id = CheckBasicAuthentication Dim textReader = New IO.StreamReader(Request.InputStream) CheckXmlValidity(textReader) ' Reset the stream & reader Request.InputStream.Seek(0, IO.SeekOrigin.Begin) textReader.DiscardBufferedData() Dim xmlIn = XDocument.Load(textReader) ' process XML in xmlIn Dim xmlOut = <?xml version="1.0" encoding="UTF-8" ?> <someresult> <header> <id><%= id.ToString() %></id> <datestamp>To be inserted</datestamp> </header> <result/> </someresult> ' Further generation of XML for output xmlOut.<someresult>.<header>.<datestamp>.Value = Date.UtcNow.ToString(xmlDateFormat) xmlText.Text = xmlOut.ToString End Sub Private Function CheckBasicAuthentication() As Integer Dim httpAuthorisation = Request.Headers("Authorization") If Left(httpAuthorisation, 6).ToUpperInvariant <> "BASIC " Then _ Throw New HttpException(401, "Basic Authentication Required") Dim authorization = Convert.FromBase64String(Mid(httpAuthorisation, 7)) Dim credentials = Text.Encoding.UTF8.GetString(authorization).Split(":"c) Dim username = credentials(0) Dim password = credentials(1) Return ConfirmValidUser(username, password) End Function Private Shared Sub CheckXmlValidity(ByVal textReader As System.IO.StreamReader) Try ' Check for "interesting" xml documents. Dim settings = New System.Xml.XmlReaderSettings() settings.XmlResolver = Nothing settings.MaxCharactersInDocument = 655360 ' Successfully parse the file, otherwise an XmlException is to be thrown. ' Dim reader = System.Xml.XmlReader.Create(textReader, settings) Try While reader.Read() 'Just checking. End While Finally reader.Close() End Try Catch ex As Exception Throw New HttpException(500, "Invalid Xml data", ex) End Try End Sub 

and ASP.NET webpage.aspx:

 <%@ Page Language="VB" AutoEventWireup="false" CodeFile="webpage.aspx.vb" Inherits="WebPage" ContentType="text/xml" %> <asp:Literal ID="xmlText" runat="server" Mode="PassThrough"></asp:Literal> 

NB Throwing HTTPException not a valid definitive solution for unwanted scenarios.

+8
source

I want to apologize in advance for not answering your question here, but I want to give a small warning. Perhaps this is already something that you take into account, but if you do not take appropriate counter measures, your system can be easily disabled using a denial of service attack when processing XML from an unknown source (both over HTTP and over HTTPS )

There is technology such as XML Entity Expansion attacks. Look for an example in this innocent looking XML world that will make your server kneel when it tries to process it:

 <!DOCTYPE foo [ <!ENTITY a "1234567890" > <!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;" > <!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;" > <!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;" > <!ENTITY e "&d;&d;&d;&d;&d;&d;&d;&d;" > <!ENTITY f "&e;&e;&e;&e;&e;&e;&e;&e;" > <!ENTITY g "&f;&f;&f;&f;&f;&f;&f;&f;" > <!ENTITY h "&g;&g;&g;&g;&g;&g;&g;&g;" > <!ENTITY i "&h;&h;&h;&h;&h;&h;&h;&h;" > <!ENTITY j "&i;&i;&i;&i;&i;&i;&i;&i;" > <!ENTITY l "&k;&k;&k;&k;&k;&k;&k;&k;" > <!ENTITY m "&l;&l;&l;&l;&l;&l;&l;&l;" > ]> <foo>&m;</foo> 

This small XML document of less than 500 bytes will make your server attempt to allocate at least 160 GB of memory.

You can protect yourself from this by checking the incoming XML (with DTD) before processing it.

You can read more about this attack here .

Good luck.

+3
source

When you create a web service, you define the XML format that you will receive, and the sender must match your format.

I usually mock up the information that my web service will receive as DataTables in a DataSet (since this exactly simulates how I can store them in a database), then do DataSet.getXML() in my mocked DataSet (itโ€™s also possible to get a schema for by default) for use as a template for XML, which I expect will be "sent" to my web service.

Then, when my web service receives the message, I can just send the sent XML and use DataSet.readXML() in the published XML ... and process the information sent to the DataSet .

Most of the return value values โ€‹โ€‹for the web service are the results of queries based on the information posted, so I do the same to format the return values โ€‹โ€‹... get the results of my query for the returned data in DataSet , DataSet.getXML() .. and return it.

0
source

Source: https://habr.com/ru/post/1309513/


All Articles