SOAP Message from WSE

P

Patrick

I have played around a bit with the Signing/Encrypting example with the Web
Service Enhancement examples at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwse/html/wssecdrill.asp

I have the following queries
1) How could I read the actual SOAP request sent by the client?
2) How could I read the actual SOAP response sent by the server?
3) what controls whether the webservice is called in a synchronous or
asynchronous mode?
4.1)
http://msdn.microsoft.com/library/en-us/dnwse/html/wssecdrill.asp?frame=true#ws-securitydrill_topic4
indicates a sample SOAP request as something like
<wsse:BinarySecurityToken

ValueType="http://schemas.xmlsoap.org/ws/2003/12/kerberos/Kerberosv5ST""
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="..."
wsu:Id="SecurityToken-de1c75eb">
YYIFezCCBX...FYxRDU24iu
</wsse:BinarySecurityToken>
4.2) What in the client side code controls what get sets in the ValueType
and EncodingType property? In particular, I want the following to be sent
intead:
<wsse:BinarySecurityToken

ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-toke
n-profile-1.0#X509v3"

EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-m
essage-security-1.0#Base64Binary"

xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurit
y-utility-1.0.xsd"
wsu:Id="SecurityToken-26801369-cb9b-43b8-84a0-7d811a494a5d">
YYIFezCCBX...FYxRDU24iu
</wsse:BinarySecurityToken>

5) Similar to question 4, how could I control what XML are sent (using
schemas from Oasis instead of xmlsoap.org) when encrypting messages?
 
P

Patrick

More interestingly, I have combined the encryption example into the signing
example as follows:

Would be nice really if I could tell really it is signing/encrypting as
expected!!!


private void SubmitButton_Click(object sender, System.EventArgs e)
{

SecurityToken authToken = null;
SecurityToken encrToken = GetX509TokenForEncrypting();
EncryptedData encryptedData = null;

string targetPrinciple;

// Create an instance of the proxy
WeblogProxy proxy = new WeblogProxy();

string hostname = System.Environment.MachineName;
//string hostname = new Uri( proxy.Url ).Host; // more realistic
string domainname = System.Environment.UserDomainName;

//targetPrinciple = "host/" + hostname + "@" + domainname;

// or this is okay if sender and receiver machines are members of the
same domain
targetPrinciple = "host/" + hostname;

// Create the weblog object
NewWeblogEntry newEntry = new NewWeblogEntry();
newEntry.title = TitleTextBox.Text;
newEntry.author = AuthorTextBox.Text;
newEntry.issued = DateTime.Now;
newEntry.content = ContentTextBox.Text;

// Create a KerberosSecurityauthToken
authToken = new KerberosToken( targetPrinciple );
encryptedData = new EncryptedData( encrToken );


// Add the SecurityauthToken to the Request Context
proxy.RequestSoapContext.Security.Tokens.Add( authToken );


// Encrypt the message with an EncryptedData object
proxy.RequestSoapContext.Security.Elements.Add( encryptedData );

// Sign the message with a signature object
proxy.RequestSoapContext.Security.Elements.Add( new MessageSignature(
authToken ) );

ConfirmedWeblogEntry confirmed = null;

try
{
// Send the request
confirmed = proxy.AddEntry( newEntry );
}
catch( Exception ex )
{
MessageBox.Show( ex.ToString() );
return;
}

// Re-populate the form
TitleTextBox.Text = confirmed.title;
AuthorTextBox.Text = confirmed.author;
ContentTextBox.Text = confirmed.content;
LinkTextBox.Text = confirmed.link;

}
 
M

[MSFT]

Hello Patrick,

Q 1&2: If you just want to know the plain text of a Soap message, I suggest
you may install Soap Toolkit, there is a tool named "Trace" in it. It can
log all in/out soup message. Here is the link to download it:
http://www.microsoft.com/downloads/details.aspx?FamilyId=C943C0DD-CEEC-4088-
9753-86F052EC8450&displaylang=en

Q 3: Synchronous or asynchronous Call depneds on client side. We can call
the web service proxy's BeginXXXX to start an asynchronous Call.

Q4 & Q5: The ValueType attribute indicates what the security token is; The
EncodingType tells how the security token is encoded. For more information
, you can refer to this article:

http://www-106.ibm.com/developerworks/webservices/library/ws-secure/

Luke
 
P

Patrick

I tried using the SOAP Trace Utility from the SOAP Toolkit Version 3.

It is set by default to :
1) listen to local port 8080
2) Forward to :
2.1) Destination Host: localhost
2.2) Destination Port: 80

With my "combined" signing & Encryption taken from the signing & encyprtion
example from the Web Service Enhancements Drilldown at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwse/html/wssecdrill.asp :
1) First of all, I had to update the constructor in WeblogProxy.cs of the
client to this.Url =
"http://localhost:8080/SigningSample/weblogservice.asmx"; (it was set to
this.Url = "http://localhost/SigningSample/weblogservice.asmx";

1.1) But now, I get the following returned:
<soap:Fault>
<faultcode
xmlns:q0="http://schemas.xmlsoap.org/ws/2004/03/addressing">q0:DestinationUn
reachable</faultcode>
<faultstring>Microsoft.Web.Services2.Addressing.AddressingFault:
Destination Unreachable ---> System.Exception: WSE816: The <To> header must
match the value of an incoming message's HTTP Request Url if the soap
receiver does not have an actor name. The <To> header received contained
"http://localhost:8080/SigningSample/weblogservice.asmx" while the HTTP
Request Url was "http://localhost/SigningSample/weblogservice.asmx". --- End
of inner exception stack trace --- at
Microsoft.Web.Services2.WebServicesExtension.AfterDeserialize(SoapMessage
message) at
Microsoft.Web.Services2.WebServicesExtension.ProcessMessage(SoapMessage
message) at
System.Web.Services.Protocols.SoapMessage.RunExtensions(SoapExtension[]
extensions) at
System.Web.Services.Protocols.SoapServerProtocol.CreateServerInstance() at
System.Web.Services.Protocols.WebServiceHandler.Invoke() at
System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faults
tring>
</soap:Fault>

**********
I have the following queries:
1) What property of WeblogProxy which inherits
Microsoft.Web.Services2.WebServicesClientProtocol could I update to get the
URL and the "To" matching up? (There isn't a TO Property)

2) What property of what .NET object could I change to get the outgoing
message to send the <wsse:BinarySecurityToken/> tag the way I want it.
Namely:
2.1) ValueType set to
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-
1.0#X509v3" instead of
"http://schemas.xmlsoap.org/ws/2003/12/kerberos/Kerberosv5ST"
 
M

[MSFT]

Hi Patrick,

I think we don't need to change the url in proxy class. Just set the web
reference to dynamic and change its URL before call a web method.

For other questions, you may refer to Christoph's answer. I think his
message is very helpful to understand the issue.

Regards,

Luke
 
P

Patrick

Re: SOAP Message from WSESeems like a good idea to use policy instead of
code!

But I have the problems, working with the examples from
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwse/html/wssecdrill.asp :
1) With the SecurityPolicy example:
I have commented out the following:
//token = new UsernameToken( Username, Password,
PasswordOption.SendPlainText );
//PolicyEnforcementSecurityTokenCache.GlobalCache.Add( token );
1.1.1) if I set the WSE2.0 Property of SecurityPolicyClient to use
PolicyX509.config
1.1.2) Unset WSE2.0 Property of SecurityPolicyService to not use any
policies
1.1.3) I get the following returned from the server
--------------Start of Error Returned from Server-------------------------
<soap:Fault>
<faultcode
xmlns:code="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecuri
ty-secext-1.0.xsd">code:SecurityTokenUnavailable</faultcode>
<faultstring>Microsoft.Web.Services2.Security.SecurityFault:
Referenced security token could not be retrieved
at Microsoft.Web.Services2.Security.EncryptedKey.LoadXml(XmlElement
element)
at Microsoft.Web.Services2.Security.EncryptedKey..ctor(XmlElement
element)
at Microsoft.Web.Services2.Security.Security.LoadXml(XmlElement element)
at
Microsoft.Web.Services2.Security.SecurityInputFilter.ProcessMessage(SoapEnve
lope envelope)
at Microsoft.Web.Services2.Pipeline.ProcessInputMessage(SoapEnvelope
envelope)
at
Microsoft.Web.Services2.WebServicesExtension.BeforeDeserializeServer(SoapSer
verMessage message)</faultstring>

<faultactor>http://localhost/SecurityPolicySample/WeblogService.asmx</faulta
ctor>
</soap:Fault>
--------------End of Error Returned from Server-------------------------

1.2.1) If I remove the <wssp:Confidentiality/> tags and subtags from
PolicyX509.config and server return unencrypted response.
1.3) Note that I have installed the Server Key using
MsdnWse2SecuritySamplesServer.pfx, on Internet explorer 6.0SP1 under
Tools->Internet Options->Content->Certificates, this
MsdnWse2SecuritySamplesServer certificate is listed under "Personal".
Additionally, I have added the "Root Agency" certificate to "Trusted Root
Certification Authorities".
1.4) Note that I also have a different test SSL certificate installed on the
IIS on the machine.

2) With my "combined signing and encryption" example taken from the WSE
Drill Down:
2.1) I have commented out all signing and encryption code, added
proxy.RequestSoapContext.Security.Timestamp.TtlInSeconds = 60000;
2.2) Under WSE Settings for the project I have:
2.2.1) Under Security Tab, ticked "Allow test roots" and select
"CurrentUser" as Store Location"
2.2.2) Under policy,
2.2.2.1) enabled Policy
2.2.2.2) Policy set to point to ..\SecurityPolicy\Client\PolicyX509.config
(same file as the example above which works for signing but not encryption)
2.2.3) Under Token Issuing, replicate the same setting as for SecurityPolicy
example:
2.2.3.1) Set ServerToken KeyInfo to
<wsse:SecurityTokenReference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecuri
ty-secext-1.0.xsd"><wsse:KeyIdentifier
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-toke
n-profile-1.0#X509SubjectKeyIdentifier">kRdbDi6QWTlyMpB7xNN65c0vTN4=</wsse:K
eyIdentifier></wsse:SecurityTokenReference>
2.2.3.2) Ticked "Auto Issue Security Context Token"
2.3) When I run this, I get the following error returned (even when
<wssp:Confidentiality/> tags and sub-tags removed from the XML policy file):
--------------Start of Error Returned from Server-------------------------
<faultstring>Microsoft.Web.Services2.Security.SecurityFault: The
security token could not be authenticated or authorized ---&gt;
System.Security.SecurityException: WSE537: The certificate's trust chain
could not be verified with the following reason: A certificate chain
processed, but terminated in a root certificate which is not trusted by the
trust provider.
..
at Microsoft.Web.Services2.Security.X509.X509CertificateChain.Verify()
at
Microsoft.Web.Services2.Security.Tokens.X509SecurityToken.VerifyTrust()
at Microsoft.Web.Services2.Security.Tokens.X509SecurityToken.Verify()
at
Microsoft.Web.Services2.Security.Tokens.X509SecurityTokenManager.VerifyToken
(SecurityToken securityToken)
at
Microsoft.Web.Services2.Security.Tokens.SecurityTokenManager.LoadBinarySecur
ityToken(XmlElement element)
--- End of inner exception stack trace ---
at
Microsoft.Web.Services2.Security.Tokens.SecurityTokenManager.LoadBinarySecur
ityToken(XmlElement element)
at
Microsoft.Web.Services2.Security.Tokens.SecurityTokenManager.GetTokenFromXml
(XmlElement element)
at Microsoft.Web.Services2.Security.Security.LoadToken(XmlElement
element, SecurityConfiguration configuration, Int32&amp; tokenCount)
at Microsoft.Web.Services2.Security.Security.LoadXml(XmlElement element)
at
Microsoft.Web.Services2.Security.SecurityInputFilter.ProcessMessage(SoapEnve
lope envelope)
at Microsoft.Web.Services2.Pipeline.ProcessInputMessage(SoapEnvelope
envelope)
at
Microsoft.Web.Services2.WebServicesExtension.BeforeDeserializeServer(SoapSer
verMessage message)</faultstring>

<faultactor>http://localhost/SigningSample/weblogservice.asmx</faultactor>
</soap:Fault>
--------------End of Error Returned from Server-------------------------


Any idea why and how I could resolve this?



Your token type question:
Well .... your other post shows that you are programmatically creating a
Kerberos token and then you attach it to the message. You need to attach an
X509SecurityToken instead.
The WSE docs feature a whole section on using X.509 certificates (
ms-help://MS.WSE20.1033/wse/html/gxaconX509Certificate.htm ).
In general, have you looked at using policies rather than code to configure
security for you web service calls?
HTH,
Christoph Schittko
MVP XML
http://weblogs.asp.net/cschittko

-----Original Message-----
From: Patrick [mailto:p[email protected]]
Posted At: Tuesday, September 21, 2004 4:05 AM
Posted To: microsoft.public.dotnet.framework.aspnet.webservices
Conversation: SOAP Message from WSE
Subject: Re: SOAP Message from WSE

I tried using the SOAP Trace Utility from the SOAP Toolkit Version 3.

It is set by default to :
1) listen to local port 8080
2) Forward to :
2.1) Destination Host: localhost
2.2) Destination Port: 80

With my "combined" signing & Encryption taken from the signing &
encyprtion
example from the Web Service Enhancements Drilldown at
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnwse/html/wssecdrill.asp :
1) First of all, I had to update the constructor in WeblogProxy.cs of the
client to this.Url =
"http://localhost:8080/SigningSample/weblogservice.asmx"; (it was set to
this.Url = "http://localhost/SigningSample/weblogservice.asmx";

1.1) But now, I get the following returned:
<soap:Fault>
<faultcode
xmlns:q0="http://schemas.xmlsoap.org/ws/2004/03/addressing">q0:Destination
Un
reachable</faultcode>
<faultstring>Microsoft.Web.Services2.Addressing.AddressingFault:
Destination Unreachable ---> System.Exception: WSE816: The <To> header
must
match the value of an incoming message's HTTP Request Url if the soap
receiver does not have an actor name. The <To> header received contained
"http://localhost:8080/SigningSample/weblogservice.asmx" while the HTTP
Request Url was "http://localhost/SigningSample/weblogservice.asmx". ---
End
of inner exception stack trace --- at
Microsoft.Web.Services2.WebServicesExtension.AfterDeserialize(SoapMessage
message) at
Microsoft.Web.Services2.WebServicesExtension.ProcessMessage(SoapMessage
message) at
System.Web.Services.Protocols.SoapMessage.RunExtensions(SoapExtension[]
extensions) at
System.Web.Services.Protocols.SoapServerProtocol.CreateServerInstance() at
System.Web.Services.Protocols.WebServiceHandler.Invoke() at
System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faul
ts
tring>
</soap:Fault>

**********
I have the following queries:
1) What property of WeblogProxy which inherits
Microsoft.Web.Services2.WebServicesClientProtocol could I update to get
the
URL and the "To" matching up? (There isn't a TO Property)

2) What property of what .NET object could I change to get the outgoing
message to send the <wsse:BinarySecurityToken/> tag the way I want it.
Namely:
2.1) ValueType set to
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-
profile-
1.0#X509v3" instead of
"http://schemas.xmlsoap.org/ws/2003/12/kerberos/Kerberosv5ST"



Hello Patrick,

Q 1&2: If you just want to know the plain text of a Soap message, I suggest
you may install Soap Toolkit, there is a tool named "Trace" in it. It can
log all in/out soup message. Here is the link to download it:
http://www.microsoft.com/downloads/details.aspx?FamilyId=C943C0DD-CEEC-
4088-
9753-86F052EC8450&displaylang=en

Q 3: Synchronous or asynchronous Call depneds on client side. We can call
the web service proxy's BeginXXXX to start an asynchronous Call.

Q4 & Q5: The ValueType attribute indicates what the security token is; The
EncodingType tells how the security token is encoded. For more information
, you can refer to this article:

http://www-106.ibm.com/developerworks/webservices/library/ws-secure/

Luke
 
M

[MSFT]

Hi Patrick,

In WSE 2.0 quick start samples, there is one about X.509 sign policy, You
may refer to it to see if it will help.

Regards,

Luke
 
P

Patrick

As stated in my last post, I couldn't get the SecurityPolicy examples
working for encryption (only works when I take out <wssp:Confidentiality/>).

If I take the policy and put it in another example, as stated in my last
post, error is returned from the server "...security token could not be
authenticated or authorized..."
 
P

Patrick

Certificates doesn't seem to be working properly. Could someone tell me
where the certificate need to reside for signing and encryption where
1) client is on same machine as server
2) client is on different machine as server

I have modified the "signing" example from the WSE Drill down
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwse/html/wssecdrill.asp
as follows:
----------------------------start of code
snippet----------------------------
public static string ClientBase64KeyId = "QRUS1q1qRz5XmIhZ1ZiAIvqPszk=";
public static string ServerBase64KeyId = "Xl4VAkKzv3lf4kjtZ/UySA5cfw8=";

private void SubmitButton_Click(object sender, System.EventArgs e)
{

SecurityToken authToken = GetX509TokenForSigning();
SecurityToken encrToken = GetX509TokenForEncrypting();
EncryptedData encryptedData = null;

string targetPrinciple;

// Create an instance of the proxy
WeblogProxy proxy = new WeblogProxy();



// Create the weblog object
NewWeblogEntry newEntry = new NewWeblogEntry();
newEntry.title = TitleTextBox.Text;
newEntry.author = AuthorTextBox.Text;
newEntry.issued = DateTime.Now;
newEntry.content = ContentTextBox.Text;

// Create a KerberosSecurityauthToken
//authToken = new KerberosToken( targetPrinciple );
encryptedData = new EncryptedData( encrToken );


// Add the SecurityauthToken to the Request Context
proxy.RequestSoapContext.Security.Tokens.Add( authToken );


// Encrypt the message with an EncryptedData object
proxy.RequestSoapContext.Security.Elements.Add( encryptedData );

// Sign the message with a signature object
proxy.RequestSoapContext.Security.Elements.Add( new MessageSignature(
authToken ) );

ConfirmedWeblogEntry confirmed = null;

try
{
// Send the request
confirmed = proxy.AddEntry( newEntry );
}
catch( Exception ex )
{
MessageBox.Show( ex.ToString() );
return;
}

// Re-populate the form
TitleTextBox.Text = confirmed.title;
AuthorTextBox.Text = confirmed.author;
ContentTextBox.Text = confirmed.content;
LinkTextBox.Text = confirmed.link;

}

private X509SecurityToken GetX509TokenForEncrypting()
{
X509SecurityToken token = null;

// Open the CurrentUser Certificate Store
X509CertificateStore store;
store = X509CertificateStore.CurrentUserStore(
X509CertificateStore.MyStore);
if( !store.OpenRead() ) return null;

// Get the x509 for the server's public key since we're encrypting
X509CertificateCollection certs = store.FindCertificateByKeyIdentifier(
Convert.FromBase64String( ServerBase64KeyId ) );

if (certs.Count > 0)
{
// Get the first certificate in the collection (should only be 1)
token = new X509SecurityToken( ((X509Certificate) certs[0]) );
}

return token;
}

private X509SecurityToken GetX509TokenForSigning()
{
X509SecurityToken token = null;

// Open the CurrentUser Certificate Store
X509CertificateStore store;
store = X509CertificateStore.CurrentUserStore(
X509CertificateStore.MyStore);
if( !store.OpenRead() ) return null;

// Get the x509 for the server's public key since we're encrypting
X509CertificateCollection certs = store.FindCertificateByKeyIdentifier(
Convert.FromBase64String( ClientBase64KeyId ) );

if (certs.Count > 0)
{
// Get the first certificate in the collection (should only be 1)
token = new X509SecurityToken( ((X509Certificate) certs[0]) );
}

return token;
}
----------------------------end of code snippet----------------------------

3) The client and server certificates are both issued by a CA on another
machine running windows 2003 on the same domain (whose certifcate was added
to be trusted root authorities under IE6 on the client/server machine)

The Server certificate was added to IIS as well (and so also appear in the
"Local Machine" store. I couldn't figure out how else I could get a cert
installed in the "Local Machine" as opposed to "user" store

------------------------------start of
error----------------------------------------
SecurityToken authToken = GetX509TokenForSigning();
SecurityToken encrToken = GetX509TokenForEncrypting();
EncryptedData encryptedData = null;

string targetPrinciple;

// Create an instance of the proxy
WeblogProxy proxy = new WeblogProxy();

//string hostname = System.Environment.MachineName;
//string hostname = new Uri( proxy.Url ).Host; // more realistic
//string domainname = System.Environment.UserDomainName;

//targetPrinciple = "host/" + hostname + "@" + domainname;

// or this is okay if sender and receiver machines are members of the
same domain
//targetPrinciple = "host/" + hostname;

// Create the weblog object
NewWeblogEntry newEntry = new NewWeblogEntry();
newEntry.title = TitleTextBox.Text;
newEntry.author = AuthorTextBox.Text;
newEntry.issued = DateTime.Now;
newEntry.content = ContentTextBox.Text;

// Create a KerberosSecurityauthToken
//authToken = new KerberosToken( targetPrinciple );
encryptedData = new EncryptedData( encrToken );


// Add the SecurityauthToken to the Request Context
proxy.RequestSoapContext.Security.Tokens.Add( authToken );


// Encrypt the message with an EncryptedData object
proxy.RequestSoapContext.Security.Elements.Add( encryptedData );

// Sign the message with a signature object
proxy.RequestSoapContext.Security.Elements.Add( new MessageSignature(
authToken ) );

ConfirmedWeblogEntry confirmed = null;

try
{
// Send the request
confirmed = proxy.AddEntry( newEntry );
}
catch( Exception ex )
{
MessageBox.Show( ex.ToString() );
return;
}

// Re-populate the form
TitleTextBox.Text = confirmed.title;
AuthorTextBox.Text = confirmed.author;
ContentTextBox.Text = confirmed.content;
LinkTextBox.Text = confirmed.link;
------------------------------end of
error----------------------------------------

4) Note that with the I still could not get the SecurityPolicy example
working, even after I use the WSE2 Certitifcate Tool to grant ASPNET user
modify permission on the Cert's private key (I use the default MSDN test
cert on that example and installed the cert using the *.pfx file)

Patrick said:
As stated in my last post, I couldn't get the SecurityPolicy examples
working for encryption (only works when I take out
 
M

[MSFT]

Hi Patrick,

It seems the certificatres haven't been installed well on your computer. On
my computer (Server and Client are same), I installed the two certificates
in "Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates":

Client Private.pfx
Server Private.pfx

Their location is Current User/personal and Computer/personal.

And the sample runs well.

For more informtion about the certificates installation and how to run the
samples, you may refer to the document in:

Program Files\Microsoft WSE\v2.0\Samples\readme.htm

Luke
 
M

[MSFT]

Hi Patrick,

Did the problem get resolved after install the certificate? If you need
more assistance on this issue, please feel free to let me know.

Luke
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top