|
|
|
date: Mon, 7 Apr 2008 12:51:40 -0500,
group: microsoft.public.exchange.development
back
Re: Exchange Web Services Problem
Here is the code. It is a simple sample from the book "Inside Microsoft Exchange Server 2007 Web Services".
The URL is correct, and I am able to access other files in the ews directory from the same machine via my web browser, so the certificate on the server seems to be correct.
Thanks for looking at this.
Mike
--------------------------------------------------------------------
static void Main(string[] args)
{
// Build up our request (Listing 1-11)
//
StringBuilder request = new StringBuilder();
request.AppendLine("<GetFolder>");
request.AppendLine(" <FolderShape>");
request.AppendLine(" <t:BaseShape>AllProperties</t:BaseShape>");
request.AppendLine(" </FolderShape>");
request.AppendLine(" <FolderIds>");
request.AppendLine(" <t:DistinguishedFolderId Id=\"inbox\"/>");
request.AppendLine(" </FolderIds>");
request.AppendLine("</GetFolder>");
// Make the request using our helper method
//
XmlDocument doc = MakeRawSoapRequest(
@"https://plcm-siptest4.siptest4.austin.plcm.com/ews/Exchange.asmx",
"administrator",
"harvey",
"siptest4.austin.plcm.com",
request.ToString());
// Write out the response to the console
//
Console.WriteLine(doc.OuterXml);
}
/// <summary>
/// Makes a raw soap request (Listing 1-10)
/// </summary>
/// <param name="url">URL of server to talk to</param>
/// <param name="userName">UserName</param>
/// <param name="password">Password</param>
/// <param name="domain">User's domain</param>
/// <param name="EWSRequestString">The contents of the soap body (minus the body element)</param>
/// <param name="headers">PARAMS any soap headers to add</param>
/// <returns>DOM wrapper around the response</returns>
///
static XmlDocument MakeRawSoapRequest(
string url,
string userName,
string password,
string domain,
string EWSRequestString,
params string[] headers)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml;utf-8";
request.Credentials = new NetworkCredential(userName, password, domain);
StringBuilder builder = new StringBuilder();
builder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
builder.AppendLine("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
builder.AppendLine(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");
builder.AppendLine(" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"");
builder.AppendLine(" xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\"" builder.AppendLine(" xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"
// Add the soap headers if present
//
if ((headers != null) && (headers.Length > 0))
{
builder.AppendLine("<soap:Header>");
foreach (string header in headers)
{
builder.Append(header);
}
builder.AppendLine("</soap:Header>");
}
builder.AppendLine("<soap:Body>");
// Add the passed request
//
builder.Append(EWSRequestString);
builder.AppendLine("</soap:Body>");
builder.AppendLine("</soap:Envelope>");
// Grab the request as a byte array
//
byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes(builder.ToString());
request.ContentLength = requestBytes.Length;
// Write our request bytes to the web request
//
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Flush();
requestStream.Close();
}
HttpWebResponse response;
try
{
// Try to get the response
//
response = request.GetResponse() as HttpWebResponse;
}
catch (WebException webException)
{
HttpWebResponse httpResponse = webException.Response as HttpWebResponse;
using (Stream responseStream = httpResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
throw new Exception(reader.ReadToEnd());
}
}
}
// Read the response stream
//
string responseString;
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
responseString = reader.ReadToEnd();
}
}
// Now we have our response. Load it into the DOM
//
XmlDocument doc = new XmlDocument();
int xmlStartIndex = responseString.IndexOf("<?xml");
doc.LoadXml(responseString.Substring(xmlStartIndex));
return doc;
}
}
}
"Michael" wrote in message news:u2VMJgNmIHA.4332@TK2MSFTNGP05.phx.gbl...
>I cannot seem to access Exchange web services. I have a proper certificate
> assigned to my EWS directory and through my browser, I can access all the
> files in the web services directory (such as services.wsdl, types.xsd, > messages.xsd), but when I try to make a web services call using the same
> credentials, I get a 401 "unauthorized".
>
> Can anyone please help!
>
> Thanks,
>
> Mike
>
>
date: Mon, 7 Apr 2008 14:31:59 -0500
author: Michael
Re: Exchange Web Services Problem
Hello Michael,
your code works on my machine. A little offtopic, but do you have a reason
to construct the soap request by yourself? It's far less complicated to work
with an auto-generated webservice proxy...
To troubleshoot your issue here I would suggest you install Fiddler on your
development machne (http://www.fiddlertool.com/fiddler/) and examine the
requests and responses.
Have a look at the 401 errors being generated and look at the HTTP headers:
What authenticate-headers do you receive?
Kind regards,
Henning Krause
"Michael" wrote in message
news:%23XCGQYOmIHA.2504@TK2MSFTNGP05.phx.gbl...
Here is the code. It is a simple sample from the book "Inside Microsoft
Exchange Server 2007 Web Services".
The URL is correct, and I am able to access other files in the ews directory
from the same machine via my web browser, so the certificate on the server
seems to be correct.
Thanks for looking at this.
Mike
--------------------------------------------------------------------
static void Main(string[] args)
{
// Build up our request (Listing 1-11)
//
StringBuilder request = new StringBuilder();
request.AppendLine("<GetFolder>");
request.AppendLine(" <FolderShape>");
request.AppendLine(" <t:BaseShape>AllProperties</t:BaseShape>");
request.AppendLine(" </FolderShape>");
request.AppendLine(" <FolderIds>");
request.AppendLine(" <t:DistinguishedFolderId Id=\"inbox\"/>");
request.AppendLine(" </FolderIds>");
request.AppendLine("</GetFolder>");
// Make the request using our helper method
//
XmlDocument doc = MakeRawSoapRequest(
@"https://plcm-siptest4.siptest4.austin.plcm.com/ews/Exchange.asmx",
"administrator",
"harvey",
"siptest4.austin.plcm.com",
request.ToString());
// Write out the response to the console
//
Console.WriteLine(doc.OuterXml);
}
/// <summary>
/// Makes a raw soap request (Listing 1-10)
/// </summary>
/// <param name="url">URL of server to talk to</param>
/// <param name="userName">UserName</param>
/// <param name="password">Password</param>
/// <param name="domain">User's domain</param>
/// <param name="EWSRequestString">The contents of the soap body (minus the
body element)</param>
/// <param name="headers">PARAMS any soap headers to add</param>
/// <returns>DOM wrapper around the response</returns>
///
static XmlDocument MakeRawSoapRequest(
string url,
string userName,
string password,
string domain,
string EWSRequestString,
params string[] headers)
{
HttpWebRequest request =
(HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml;utf-8";
request.Credentials = new NetworkCredential(userName, password,
domain);
StringBuilder builder = new StringBuilder();
builder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
builder.AppendLine("<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
builder.AppendLine("
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");
builder.AppendLine("
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"");
builder.AppendLine("
xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\"");
builder.AppendLine("
xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">");
// Add the soap headers if present
//
if ((headers != null) && (headers.Length > 0))
{
builder.AppendLine("<soap:Header>");
foreach (string header in headers)
{
builder.Append(header);
}
builder.AppendLine("</soap:Header>");
}
builder.AppendLine("<soap:Body>");
// Add the passed request
//
builder.Append(EWSRequestString);
builder.AppendLine("</soap:Body>");
builder.AppendLine("</soap:Envelope>");
// Grab the request as a byte array
//
byte[] requestBytes =
System.Text.Encoding.UTF8.GetBytes(builder.ToString());
request.ContentLength = requestBytes.Length;
// Write our request bytes to the web request
//
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestBytes, 0,
requestBytes.Length);
requestStream.Flush();
requestStream.Close();
}
HttpWebResponse response;
try
{
// Try to get the response
//
response = request.GetResponse() as HttpWebResponse;
}
catch (WebException webException)
{
HttpWebResponse httpResponse = webException.Response as
HttpWebResponse;
using (Stream responseStream =
httpResponse.GetResponseStream())
{
using (StreamReader reader = new
StreamReader(responseStream))
{
throw new Exception(reader.ReadToEnd());
}
}
}
// Read the response stream
//
string responseString;
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new
StreamReader(responseStream))
{
responseString = reader.ReadToEnd();
}
}
// Now we have our response. Load it into the DOM
//
XmlDocument doc = new XmlDocument();
int xmlStartIndex = responseString.IndexOf("<?xml");
doc.LoadXml(responseString.Substring(xmlStartIndex));
return doc;
}
}
}
"Michael" wrote in message
news:u2VMJgNmIHA.4332@TK2MSFTNGP05.phx.gbl...
>I cannot seem to access Exchange web services. I have a proper certificate
> assigned to my EWS directory and through my browser, I can access all the
> files in the web services directory (such as services.wsdl, types.xsd,
> messages.xsd), but when I try to make a web services call using the same
> credentials, I get a 401 "unauthorized".
>
> Can anyone please help!
>
> Thanks,
>
> Mike
>
>
date: Mon, 7 Apr 2008 23:05:58 +0200
author: Henning Krause [MVP - Exchange]
Re: Exchange Web Services Problem
Henning,
Here is a decrypted trace. The application seems to send a proper NTLM
response after the challenge, but then the server sends the 302 response. I
am not sure why. The exchange.asmx file is in the EWS directory on my
server.
POST /ews/Exchange.asmx HTTP/1.1
Content-Type: text/xml;utf-8
Authorization: Negotiate
TlRMTVNTUAABAAAAt4II4gAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw==
Host: plcm-siptest4.siptest4.austin.polycom.com
Content-Length: 0
HTTP/1.1 401 Unauthorized
Content-Length: 1539
Content-Type: text/html
Server: Microsoft-IIS/6.0
WWW-Authenticate: Negotiate
TlRMTVNTUAACAAAAEAAQADgAAAA1goni5TERvHdV8P4AAAAAAAAAAAABAAFIAAAABQLODgAAAA9TAEkAUABUAEUAUwBUADQAAgAQAFMASQBQAFQARQBTAFQANAABABoAUABMAEMATQAtAFMASQBQAFQARQBTAFQANAAEADYAcwBpAHAAdABlAHMAdAA0AC4AYQB1AHMAdABpAG4ALgBwAG8AbAB5AGMAbwBtAC4AYwBvAG0AAwBSAHAAbABjAG0ALQBzAGkAcAB0AGUAcwB0ADQALgBzAGkAcAB0AGUAcwB0ADQALgBhAHUAcwB0AGkAbgAuAHAAbwBsAHkAYwBvAG0ALgBjAG8AbQAFADYAcwBpAHAAdABlAHMAdAA0AC4AYQB1AHMAdABpAG4ALgBwAG8AbAB5AGMAbwBtAC4AYwBvAG0AAAAAAA==
X-Powered-By: ASP.NET
Date: Tue, 08 Apr 2008 15:12:12 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252">
<STYLE type="text/css">
BODY { font: 8pt/12pt verdana }
H1 { font: 13pt/15pt verdana }
H2 { font: 8pt/12pt verdana }
A:link { color: red }
A:visited { color: maroon }
</STYLE>
</HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>
<h1>You are not authorized to view this page</h1>
You do not have permission to view this directory or page using the
credentials that you supplied.
<hr>
<p>Please try the following:</p>
<ul>
<li>Contact the Web site administrator if you believe you should be able to
view this directory or page.</li>
<li>Click the <a href="javascript:location.reload()">Refresh</a> button to
try again with different credentials.</li>
</ul>
<h2>HTTP Error 401.1 - Unauthorized: Access is denied due to invalid
credentials.<br>Internet Information Services (IIS)</h2>
<hr>
<p>Technical Information (for support personnel)</p>
<ul>
<li>Go to <a href="http://go.microsoft.com/fwlink/?linkid=8180">Microsoft
Product Support Services</a> and perform a title search for the words
<b>HTTP</b> and <b>401</b>.</li>
<li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr),
and search for topics titled <b>Authentication</b>, <b>Access Control</b>,
and <b>About Custom Error Messages</b>.</li>
</ul>
</TD></TR></TABLE></BODY></HTML>
POST /ews/Exchange.asmx HTTP/1.1
Content-Type: text/xml;utf-8
Authorization: Negotiate
TlRMTVNTUAADAAAAGAAYALQAAAAYABgAzAAAADYANgBIAAAAGgAaAH4AAAAcABwAmAAAABAAEADkAAAANYKI4gUBKAoAAAAPcwBpAHAAdABlAHMAdAA0AC4AYQB1AHMAdABpAG4ALgBwAG8AbAB5AGMAbwBtAC4AYwBvAG0AYQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBNAFQAVQBDAEsARQBSAF8AVABQAFQANAAyAFAAC/Phfezo5q0AAAAAAAAAAAAAAAAAAAAAx8xZ343LplJkbDSdsDbatQZ5wcs2m8Ia42zNKvXnw2oQreE0MRhZ+A==
Host: plcm-siptest4.siptest4.austin.polycom.com
Content-Length: 655
Expect: 100-continue
HTTP/1.1 100 Continue
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Body>
<GetFolder>
<FolderShape>
<t:BaseShape>AllProperties</t:BaseShape>
</FolderShape>
<FolderIds>
<t:DistinguishedFolderId Id="inbox"/>
</FolderIds>
</GetFolder>
</soap:Body>
</soap:Envelope>
HTTP/1.1 302 Found
Date: Tue, 08 Apr 2008 15:12:12 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Location: /ews/GenericErrorPage.htm?aspxerrorpath=/ews/Exchange.asmx
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 175
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a
href="/ews/GenericErrorPage.htm?aspxerrorpath=/ews/Exchange.asmx">here</a>.</h2>
</body></html>
"Henning Krause [MVP - Exchange]"
wrote in message news:u6SzwMPmIHA.5368@TK2MSFTNGP04.phx.gbl...
> Hello Michael,
>
> your code works on my machine. A little offtopic, but do you have a reason
> to construct the soap request by yourself? It's far less complicated to
> work with an auto-generated webservice proxy...
>
> To troubleshoot your issue here I would suggest you install Fiddler on
> your development machne (http://www.fiddlertool.com/fiddler/) and examine
> the requests and responses.
>
> Have a look at the 401 errors being generated and look at the HTTP
> headers: What authenticate-headers do you receive?
>
> Kind regards,
> Henning Krause
>
> "Michael" wrote in message
> news:%23XCGQYOmIHA.2504@TK2MSFTNGP05.phx.gbl...
> Here is the code. It is a simple sample from the book "Inside Microsoft
> Exchange Server 2007 Web Services".
>
> The URL is correct, and I am able to access other files in the ews
> directory from the same machine via my web browser, so the certificate on
> the server seems to be correct.
>
> Thanks for looking at this.
>
> Mike
>
> --------------------------------------------------------------------
>
> static void Main(string[] args)
> {
> // Build up our request (Listing 1-11)
> //
> StringBuilder request = new StringBuilder();
> request.AppendLine("<GetFolder>");
> request.AppendLine(" <FolderShape>");
> request.AppendLine(" <t:BaseShape>AllProperties</t:BaseShape>");
> request.AppendLine(" </FolderShape>");
> request.AppendLine(" <FolderIds>");
> request.AppendLine(" <t:DistinguishedFolderId Id=\"inbox\"/>");
> request.AppendLine(" </FolderIds>");
> request.AppendLine("</GetFolder>");
>
> // Make the request using our helper method
> //
>
> XmlDocument doc = MakeRawSoapRequest(
>
> @"https://plcm-siptest4.siptest4.austin.plcm.com/ews/Exchange.asmx",
> "administrator",
> "harvey",
> "siptest4.austin.plcm.com",
> request.ToString());
> // Write out the response to the console
> //
> Console.WriteLine(doc.OuterXml);
> }
>
> /// <summary>
> /// Makes a raw soap request (Listing 1-10)
> /// </summary>
> /// <param name="url">URL of server to talk to</param>
> /// <param name="userName">UserName</param>
> /// <param name="password">Password</param>
> /// <param name="domain">User's domain</param>
> /// <param name="EWSRequestString">The contents of the soap body (minus
> the body element)</param>
> /// <param name="headers">PARAMS any soap headers to add</param>
> /// <returns>DOM wrapper around the response</returns>
> ///
>
> static XmlDocument MakeRawSoapRequest(
> string url,
> string userName,
> string password,
> string domain,
> string EWSRequestString,
> params string[] headers)
> {
> HttpWebRequest request =
> (HttpWebRequest)HttpWebRequest.Create(url);
> request.Method = "POST";
> request.ContentType = "text/xml;utf-8";
> request.Credentials = new NetworkCredential(userName, password,
> domain);
> StringBuilder builder = new StringBuilder();
> builder.AppendLine("<?xml version=\"1.0\"
> encoding=\"utf-8\"?>");
> builder.AppendLine("<soap:Envelope
> xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
> builder.AppendLine("
> xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");
> builder.AppendLine("
> xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"");
> builder.AppendLine("
> xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\"");
> builder.AppendLine("
> xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">");
>
> // Add the soap headers if present
> //
>
> if ((headers != null) && (headers.Length > 0))
> {
> builder.AppendLine("<soap:Header>");
> foreach (string header in headers)
> {
> builder.Append(header);
> }
> builder.AppendLine("</soap:Header>");
> }
>
> builder.AppendLine("<soap:Body>");
>
> // Add the passed request
> //
>
> builder.Append(EWSRequestString);
> builder.AppendLine("</soap:Body>");
> builder.AppendLine("</soap:Envelope>");
>
> // Grab the request as a byte array
> //
>
> byte[] requestBytes =
> System.Text.Encoding.UTF8.GetBytes(builder.ToString());
> request.ContentLength = requestBytes.Length;
>
> // Write our request bytes to the web request
> //
>
> using (Stream requestStream = request.GetRequestStream())
> {
> requestStream.Write(requestBytes, 0,
> requestBytes.Length);
> requestStream.Flush();
> requestStream.Close();
> }
>
> HttpWebResponse response;
>
> try
> {
>
> // Try to get the response
> //
>
> response = request.GetResponse() as HttpWebResponse;
> }
> catch (WebException webException)
> {
> HttpWebResponse httpResponse = webException.Response as
> HttpWebResponse;
> using (Stream responseStream =
> httpResponse.GetResponseStream())
> {
> using (StreamReader reader = new
> StreamReader(responseStream))
> {
> throw new Exception(reader.ReadToEnd());
> }
> }
> }
>
> // Read the response stream
> //
>
> string responseString;
> using (Stream responseStream = response.GetResponseStream())
> {
> using (StreamReader reader = new
> StreamReader(responseStream))
> {
> responseString = reader.ReadToEnd();
> }
> }
>
> // Now we have our response. Load it into the DOM
> //
>
> XmlDocument doc = new XmlDocument();
> int xmlStartIndex = responseString.IndexOf("<?xml");
> doc.LoadXml(responseString.Substring(xmlStartIndex));
> return doc;
> }
> }
> }
>
>
> "Michael" wrote in message
> news:u2VMJgNmIHA.4332@TK2MSFTNGP05.phx.gbl...
>>I cannot seem to access Exchange web services. I have a proper
>>certificate
>> assigned to my EWS directory and through my browser, I can access all the
>> files in the web services directory (such as services.wsdl, types.xsd,
>> messages.xsd), but when I try to make a web services call using the same
>> credentials, I get a 401 "unauthorized".
>>
>> Can anyone please help!
>>
>> Thanks,
>>
>> Mike
>>
>>
date: Tue, 8 Apr 2008 10:43:40 -0500
author: Michael
|
|