Symptom #
When testing the connection to a web service it complains that you are using Anonymous instead of Basic. i.e. WSCT is not using the right authentication. The following error occurs:
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Anonymous'.
The authentication header received from the server was 'Basic Realm="webservices4.autotask.net"'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized. at System.Net.HttpWebRequest.GetResponse()
Cause #
By default the Web Service Connector Tool uses Negotiation to first try Anonymous login and then waits for a response from the web service as to whether this is enough, or to change to use Basic Authentication instead. However, some web services (like the one here) are more strict, and deny access if you do not explicitly begin the connection with Basic Authentication
Solution #
A custom HTTP header that uses Basic Authentication instead of the default Negotiated Anonymous/Basic Authentication needs to be written. This is achieved by first creating the following 3 global functions:
Function 1 Script #
Function HTTPBasicAuth(Username, Password) Dim AuthString, AuthEncoded, AuthHeader AuthString = Username & ":" & Password AuthEncoded = EncodeBase64(StringToBytes(AuthString)) AuthHeader = "Basic " & AuthEncoded HTTPBasicAuth = AuthHeader End Function
Function 2 Script #
Function StringToBytes(inString) Const adTypeBinary = 1 Const adTypeText = 2 Dim byteStream Set byteStream = CreateObject("ADODB.Stream") byteStream.Type = adTypeText byteStream.CharSet = "ascii" byteStream.Open byteStream.WriteText inString byteStream.Position = 0 byteStream.Type = adTypeBinary StringToBytes = byteStream.Read End Function
Function 3 Script #
Function EncodeBase64(inBytes) Dim dom, element, result Set dom = CreateObject("Microsoft.XMLDOM") Set element = dom.createElement("temp") element.DataType = "bin.base64" element.NodeTypedValue = inBytes result = Replace(element.Text, vbLf, vbNullString) EncodeBase64 = result End Function
Make sure to create the parameters that each function accepts.
WSCT Global Configuration #
After the global functions have been created we need to use them in lieu of the default Authentication.
- In the global configuration settings for the WSCT, pick a method you want to apply custom headers to and click Edit –> Request Headers –>Input. Create a header called Authorization and set Allow Mapping to True by ticking the tick box. (See Figure 1)Important: Ensure the spelling of ‘Authorization‘ is spelt with a ‘z‘ otherwise the web service call will fail.
Figure 1. Request Headers in Global Config for WSCT
- In the Authentication tab, set the authentication method to Not required. (See Figure 2)
Figure 2. Authentication tab showing the option ‘Not required’ selected under the heading ‘Authentication Details’
Web Service Connector Tool task step #
- Within the WSCT step inside a task, pick that same method you set a Request Header on (or click another one, then the original one to refresh the mappings, and click ‘No’ when asked if you want to clear mappings).You will now see Authorization as a mappable field within the Tool Input pane on the right. (See Figure 3)
Figure 3. Shows the mappable HttpHeaders field in the WSCT step - You need to map the Authorization field to a Fixed/Dynamic data function whose value is the result of calling the global function BasicHTTPAuth. This is achieved as follows:Select Functions which is a tab located down the right-hand side of the Tool Input pane, then drag the Fixed/Dynamic data element onto the Transformation Mappings area.
Figure 4. Locating the Fixed/Dynamic data function - Right-click and edit the Fixed/Dynamicdata function.Under the Value tab drag the HTTPBasicAuth global function, created earlier, from the task browser and into the Output Text field. The text field will then display: {=HTTPBasicAuth()}
Figure 5. Editing the Fixed/Dynamic function
- Within the brackets of the function enter the required username and password, for example:{=HTTPBasicAuth(“USERNAME”,”PASSWORD”)}
- Select OK then drag the Fixed/Dynamic function icon onto the Authorization field to complete the mapping.
Figure 6. Mapping the function to the ‘Authorization’ field
This completes the creation of a custom HTTP header using Basic Authentication. Check it is all working by using a web proxy such as Fiddler: How to use a web proxy to view HTTP traffic through the TaskCentre Web Service Connector