System.Web.Services Authentication?

B

bugnthecode

Hi,

I am trying to put together a small app that uses one of my company's
web service. Originally I interfaced with this web service using java,
and have the example code. I believe the web service was written with
java. Since this web services uses soap I should have no problems
consuming it from other languages, although I'm having a problem
with .net.

The web service requires authentication. I tried adding the
authentication, but still kept getting an exception with the exception
saying something about "could not process the body of the message". So
I decided to use TcpTrace to figure out what was really going on.

I compared what should be 2 identical calls to the web service, one
from .net, one from java. The only pertinent difference I see is the
parameter "Authorization". The java web service call contains this,
and the .net one does not.

Based on the response message from the server I did some searching and
found that someone else had run into a similar problem and their
solution was to add the authentication information manually to the
request header, but did not leave a description on how to do that.

Is it possible to manually add the authentication information to the
request? Is there something I'm missing to force .net to authenticate?
Why don't the credentials I added to the web service work? Or is it
something else entirely?

Below is the code I used to make the web service call, the request,
the request made from a good java call, and the response from the
server with the .net call.

Thanks for your help,
Will

This is the code I use for .net (in VB):
webservice = New MyCompanysWebService()
Dim creds As System.Net.NetworkCredential = New
System.Net.NetworkCredential()
creds.UserName = "username"
creds.Password = "password"
webservice.Credentials = creds
webservice.PreAuthenticate = True
webserice.MyMethodCall(arguments)

This is the resulting call to the web server:
POST /soap/rpc HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client
Protocol 2.0.50727.42)
VsDebuggerCausalityData: uIDPoyeSbaxKao9EtV5QrGihJU0AAAAALItHCIPp
+E68IP7kjv5l3vhSsn2pM0RKn8cJ9xcdWeEACAAA
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: localhost:6666
Content-Length: 2598
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
.....


This is the call that is made from java:
POST /soap/rpc HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related,
text/*
User-Agent: Axis/1.4
Host: localhost:6666
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 3592
Authorization: Basic
dml0YWxfd2luZG93c19hZF9hcHA6a1FPY2tjR3g4eFhjY2lGT3Y=

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
....


This is the response I get from the .net call:
HTTP/1.0 500 Internal Server Error
Set-Cookie: ssnid=6896yS4Rvrn2IbkQuOnVJ40m|gwmhc-6666173; path=/;
Content-Type: text/xml;charset=utf-8
Connection: Keep-Alive
Content-Length: 844

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>[ISS.0088.9134] Exception occurred while processing
the body of the message</faultstring>
<faultactor>http://localhost:6666/soap/rpc</faultactor>
<detail xmlns:webM="http://www.webMethods.com/2001/10/soap/
encoding">
<webM:exception>
<webM:className>com.wm.app.b2b.server.AccessException</
webM:className>
<webM:message xml:lang="">[ISS.0084.9004] Access Denied</
webM:message>
</webM:exception>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
 
B

bugnthecode

For anyone else who may encounter this issue, or for the curious,
after hours of searching I finally found a definite answer and
example. The link is here: http://mark.michaelis.net/Blog/CallingWebServicesUsingBasicAuthentication.aspx

Basically it's a problem with using .net and a server that's using
webmethods. .net doesn't negotiate the authentication the way web
methods expects it. Check out the link for more detail. The below code
is a partial class which only needs to be included in your project and
you can regenerate your webservice proxy all you want because the
generated code comes out as a partial class. The only requirements are
that you have the Namespace set correctly, along with the class name.

I actually found a small bug in the code provided on the site, and it
was the "Basic " string in the call to GetBytes. If you don't include
the space the converted username/password will be smushed against it
and you will get an error from the server. The server expects
something like:
Authorization: Basic abcdefencodedusernameandpasswordxyz
without the space you get
Authorization: Basicabcdefencodedusernameandpasswordxyz
and an error from the server about a bad string length.

Thanks to anyone who may have been looking into my problem,
Will

I re-wrote the code in VB to fit along with my project, here is the
code:
Namespace MyWebServiceNameSpace
Partial Public Class MyWebServiceClass
Inherits System.Web.Services.Protocols.SoapHttpClientProtocol

Protected Overrides Function GetWebRequest(ByVal myUri As Uri)
As System.Net.WebRequest
Dim request As System.Net.HttpWebRequest
request = CType(MyBase.GetWebRequest(myUri),
System.Net.HttpWebRequest)

If Me.PreAuthenticate Then
Dim creds As System.Net.NetworkCredential =
Me.Credentials.GetCredential(myUri, "Basic")
If Not creds Is Nothing Then
Dim credentialBuffer() As Byte = New
System.Text.UTF8Encoding().GetBytes( _
creds.UserName & ":" & creds.Password)
request.Headers("Authorization") = "Basic " &
Convert.ToBase64String(credentialBuffer)
Else
Throw New ApplicationException("No network
credentials")
End If
End If
Return request
End Function
End Class
End Namespace
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top