Sign custom SOAP Header on outbound call with WCF

  • Thread starter Thread starter Mike Logan
  • Start date Start date
M

Mike Logan

I'm trying to write a simple client to prove that this works. I need to be
able to send a web service request (SOAP 1.1/HTTP) with a signed custom soap
header. I'm able to add the custom soap header, I just can't get it signed.
I can find the cert I want to use, it just doesn't sign the custom soap
header.

Here are the important parts of my code.

Custom Message Inspector

Public Class MyCustomMessageInspector
Implements IClientMessageInspector

Public Sub AfterReceiveReply(ByRef reply As
System.ServiceModel.Channels.Message, ByVal correlationState As Object)
Implements
System.ServiceModel.Dispatcher.IClientMessageInspector.AfterReceiveReply
'nothing
End Sub

Public Function BeforeSendRequest(ByRef request As
System.ServiceModel.Channels.Message, ByVal channel As
System.ServiceModel.IClientChannel) As Object Implements
System.ServiceModel.Dispatcher.IClientMessageInspector.BeforeSendRequest
request.Headers.Add(New CustomABCSoapHeader("heliolo"))
Return request
End Function
End Class


Here is my custom message header class.


Public Class CustomABCSoapHeader
Inherits MessageHeader

Dim val As String

Protected Overrides Sub OnWriteHeaderContents(ByVal writer As
Xml.XmlDictionaryWriter, ByVal messageVersion As MessageVersion)
writer.WriteAttributeString("name", CustomABC)
End Sub 'OnWriteHeaderContents

Public Sub New(ByVal value As String)
Me.CustomABC = value
End Sub


<MessageHeader(ProtectionLevel:=System.Net.Security.ProtectionLevel.Sign)> _
Public Property CustomABC() As String
Get
Return val
End Get
Set(ByVal value As String)
val = value
End Set
End Property

Public Overrides ReadOnly Property Name() As String
Get
Return "CustomABC"
End Get
End Property

Public Overrides ReadOnly Property [Namespace]() As String
Get
Return "http://abc.com"
End Get
End Property
End Class 'MyMessageHeader

Here is my Custom Endpoint Behavior.

Public Class MyCustomBehavior
Implements IEndpointBehavior

Public Sub AddBindingParameters(ByVal endpoint As
System.ServiceModel.Description.ServiceEndpoint, ByVal bindingParameters As
System.ServiceModel.Channels.BindingParameterCollection) Implements
System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters

End Sub

Public Sub ApplyClientBehavior(ByVal endpoint As
System.ServiceModel.Description.ServiceEndpoint, ByVal clientRuntime As
System.ServiceModel.Dispatcher.ClientRuntime) Implements
System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior
clientRuntime.MessageInspectors.Add(New MyCustomMessageInspector)
End Sub

Public Sub ApplyDispatchBehavior(ByVal endpoint As
System.ServiceModel.Description.ServiceEndpoint, ByVal endpointDispatcher As
System.ServiceModel.Dispatcher.EndpointDispatcher) Implements
System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior

End Sub

Public Sub Validate(ByVal endpoint As
System.ServiceModel.Description.ServiceEndpoint) Implements
System.ServiceModel.Description.IEndpointBehavior.Validate

End Sub
End Class

And finally here is my client code.


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.Windows.RoutedEventArgs) Handles Button1.Click

Dim myws As New MyWS.MyWSSoapClient

Try



myws.ChannelFactory.Credentials.ClientCertificate.SetCertificate( _
"cn=customcertnamehere", _

System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, _
System.Security.Cryptography.X509Certificates.StoreName.My)

myws.ChannelFactory.Endpoint.Behaviors.Add(New MyCustomBehavior())

TextBox1.Text = myws.WSOperation1("Hello world...sign me please.")

Catch ex As Exception

MsgBox(ex.ToString, MsgBoxStyle.OkOnly, "error")

End Try

End Sub

Thanks for any help you can provide.
 
Hi Mike,

From your description, you're trying to programmatically add some
soapheaders into WCF message and also want to sign them, correct?

Based on my research, here are some findings and suggestion about custom
WCF header and message securing:

** for message signing(entire message or part of message), you need to use
a binding that support Message layer security(WS-security) and also
configure it to use message layer security

** If you want to add a custom soapheader and only sign that header, the
reasonable approach is first define a "MessageContract" for your WCF
service, and then apply "ProtectionLevel" for each part of the
MessageContract(body or headers).

e.g.
==================
[MessageContract]
public class PatientRecord
{
[MessageHeader(ProtectionLevel=None)] public int recordID;
[MessageHeader(ProtectionLevel=Sign)] public string patientName;
[MessageHeader(ProtectionLevel=EncryptAndSign)] public string SSN;

[MessageBodyMember(ProtectionLevel=None)] public string comments;
[MessageBodyMember(ProtectionLevel=Sign)] public string diagnosis;
[MessageBodyMember(ProtectionLevel=EncryptAndSign)] public string
medicalHistory;
}

===================

#Using Message Contracts
http://msdn.microsoft.com/en-us/library/ms730255.aspx


** For adding custom soap header, in addition to add it via
"MessageInspector", you can also use "OperationContextScope" so that you
can add custom header at client application code. e.g.

=====================
CalcSVC.CalcServiceClient client = new CalcSVC.CalcServiceClient();

using (OperationContextScope opScope = new
OperationContextScope((IContextChannel)client.InnerChannel))
{

OperationContext op = OperationContext.Current;

//add a custom header
SimpleCredentialsHeader credheader = new
SimpleCredentialsHeader();
credheader.Username = "steven"; credheader.Password =
"password";
op.OutgoingMessageHeaders.Add(credheader);

string desc = client.GetDescription();
Console.WriteLine(desc);
}
============================

#How do I add a custom header to every WCF message
http://weblogs.asp.net/avnerk/archive/2006/04/25/How-do-I-add-a-custom-heade
r-to-every-WCF-message_3F00_.aspx

However, for such cases(you programmtically add header into WCF message),
you cannot utilize the built-in message securing feature(sign and encrypt)
as the header you add into message is not originally defined in the service
contract and the securing channel doesn't have idea to secure them. If you
need to encrypt or sign them, we also need to use code to sign/encrypt them
ourself.

And for "MessageHeaderAttribute", it can only be used on member of a class
which is decorated with "MessageContractAttribute" as mentioned in the
following document. It cannot be used on a custom header class.

#MessageHeaderAttribute Class
http://msdn.microsoft.com/en-us/library/system.servicemodel.messageheaderatt
ribute.aspx

Is defining a custom MessageContract suitable for your case? If not, would
you provide some further info about your problem scenario so that we can
try look for some other ideas on this.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
 
Hi Mike,

I've performed some further research on this and got some progress. As for
custom header which is added dynamically, one means to secure it is adding
some security protectionRequirement(for message part) dynamically. One
means to do this is defining a custom "ContractBehavior" to customize the
binding parameters. e.g.

==========custom binding behavior==========
public class CustomSecureContractBehavior : IContractBehavior
{
string action;
string header;
string ns;

public CustomSecureContractBehavior(string header, string ns,
string action)
{ this.header = header;
this.ns = ns;
this.action = action;
}


#region IContractBehavior Members

public void AddBindingParameters(ContractDescription
contractDescription, ServiceEndpoint endpoint,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
ChannelProtectionRequirements requirements =
bindingParameters.Find<ChannelProtectionRequirements>();

XmlQualifiedName headerName = new XmlQualifiedName(header,ns);


requirements.IncomingSignatureParts.ChannelParts.HeaderTypes.Add(headerName
);

//uncomment below to enable encryption

//requirements.IncomingEncryptionParts.ChannelParts.HeaderTypes.Add(headerNa
me );
}

public void ApplyClientBehavior(ContractDescription
contractDescription, ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{

}

public void ApplyDispatchBehavior(ContractDescription
contractDescription, ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{

}

public void Validate(ContractDescription contractDescription,
ServiceEndpoint endpoint)
{

}

#endregion
}
=========================

and you can register it at the client-side on the Endpoint. e.g.

=================
static void RunClient()
{
CalcSVC.CalcServiceClient client = new
CalcSVC.CalcServiceClient();

//add my custom contract behavior
client.Endpoint.Contract.Behaviors.Add(
new
CustomSecureContractBehavior("SimpleCredentialsHeader",
"http://www.test.org/customheaders", "*")
);

//I use message security(username client credential type)

client.ClientCredentials.UserName.UserName = "WCFUser";
client.ClientCredentials.UserName.Password = "[Password]";

using (OperationContextScope opScope = new
OperationContextScope((IContextChannel)client.InnerChannel))
{

OperationContext op = OperationContext.Current;

//here I add my custom message header
SimpleCredentialsHeader credheader = new
SimpleCredentialsHeader();
credheader.Username = "steven"; credheader.Password =
"password";

op.OutgoingMessageHeaders.Add(credheader);


string desc = client.GetDescription();
Console.WriteLine(desc);
}
}
==================

BTW, here is my custom message header's definition for your reference

======================
namespace CustomHeaderLib
{
public class SimpleCredentialsHeader : MessageHeader
{

public string Username { get; set; }
public string Password { get; set; }

public SimpleCredentialsHeader()
{
Username = "Anonymous";
Password = string.Empty;
}

public SimpleCredentialsHeader(string username, string password)
{
Username = username;
Password = password;
}

public override string Name
{
get { return "SimpleCredentialsHeader"; }
}

public override string Namespace
{
get { return "http://www.test.org/customheaders"; }
}

public override bool MustUnderstand
{
get
{
return false;
}
}


protected override void
OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion
messageVersion)
{
writer.WriteStartElement("CredentialsContent", Namespace);
writer.WriteAttributeString("username", Username);
writer.WriteAttributeString("password", Password);
writer.WriteEndElement();
}
}
}
===================

If you have anything unclear, please feel free to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.


--------------------
From: (e-mail address removed) ("Steven Cheng")
Organization: Microsoft
Date: Mon, 16 Feb 2009 06:29:51 GMT
Subject: RE: Sign custom SOAP Header on outbound call with WCF
Hi Mike,

From your description, you're trying to programmatically add some
soapheaders into WCF message and also want to sign them, correct?

Based on my research, here are some findings and suggestion about custom
WCF header and message securing:

** for message signing(entire message or part of message), you need to use
a binding that support Message layer security(WS-security) and also
configure it to use message layer security

** If you want to add a custom soapheader and only sign that header, the
reasonable approach is first define a "MessageContract" for your WCF
service, and then apply "ProtectionLevel" for each part of the
MessageContract(body or headers).

e.g.
==================
[MessageContract]
public class PatientRecord
{
[MessageHeader(ProtectionLevel=None)] public int recordID;
[MessageHeader(ProtectionLevel=Sign)] public string patientName;
[MessageHeader(ProtectionLevel=EncryptAndSign)] public string SSN;

[MessageBodyMember(ProtectionLevel=None)] public string comments;
[MessageBodyMember(ProtectionLevel=Sign)] public string diagnosis;
[MessageBodyMember(ProtectionLevel=EncryptAndSign)] public string
medicalHistory;
}
 
Hello Steven. It's always a pleasure to work with you. Thanks for your
responses.

I tried what you suggested and the custom soap header is still not signed.
It's added but not signed. There is one part of this puzzle that may help
you out. I cannot change the service. These services are regular .net 1 and
2 asmx services that have no security on them. It's our service broker that
requires the signed custom soap header.

==================================================

Here is my client code

==================================================

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.Windows.RoutedEventArgs) Handles Button1.Click

Dim vdsi As New DecryptClientProxy.SvcSoapClient

Try

vdsi.ClientCredentials.ClientCertificate.SetCertificate( _
"cn=mlogansc1", _

System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, _
System.Security.Cryptography.X509Certificates.StoreName.My)

Dim mcb As New MyCustomBehavior
vdsi.Endpoint.Contract.Behaviors.Add(mcb)

Using opScope As New
OperationContextScope(DirectCast(vdsi.InnerChannel, IContextChannel))

Dim op As OperationContext = OperationContext.Current

'here I add my custom message header
Dim credheader As New MyCustomSoapHeader("mike")
op.OutgoingMessageHeaders.Add(credheader)

TextBox1.Text = vdsi.Operation1("some text here")

End Using

Catch ex As Exception

MsgBox(ex.ToString, MsgBoxStyle.OkOnly, "error")

End Try

End Sub

==================================================

Here is my custom contract behavior

==================================================

Public Class MyCustomBehavior
Implements IContractBehavior

Public Sub AddBindingParameters(ByVal contractDescription As
ContractDescription, ByVal endpoint As ServiceEndpoint, ByVal
bindingParameters As System.ServiceModel.Channels.BindingParameterCollection)
Implements IContractBehavior.AddBindingParameters
Dim requirements As ChannelProtectionRequirements =
bindingParameters.Find(Of ChannelProtectionRequirements)()

Dim headerName As New Xml.XmlQualifiedName("custom_name",
"http://someplace.com")

requirements.IncomingSignatureParts.ChannelParts.HeaderTypes.Add(headerName)


End Sub

Public Sub ApplyClientBehavior(ByVal contractDescription As
ContractDescription, ByVal endpoint As ServiceEndpoint, ByVal clientRuntime
As System.ServiceModel.Dispatcher.ClientRuntime) Implements
IContractBehavior.ApplyClientBehavior

End Sub

Public Sub ApplyDispatchBehavior(ByVal contractDescription As
ContractDescription, ByVal endpoint As ServiceEndpoint, ByVal dispatchRuntime
As System.ServiceModel.Dispatcher.DispatchRuntime) Implements
IContractBehavior.ApplyDispatchBehavior

End Sub

Public Sub Validate(ByVal contractDescription As
ContractDescription, ByVal endpoint As ServiceEndpoint) Implements
IContractBehavior.Validate

End Sub
End Class

==================================================

And finally here is my custom header

==================================================

Public Class MyCustomSoapHeader
Inherits MessageHeader

Dim val As String

Protected Overrides Sub OnWriteHeaderContents(ByVal writer As
Xml.XmlDictionaryWriter, ByVal messageVersion As MessageVersion)
writer.WriteAttributeString("name", VITAUser)
End Sub 'OnWriteHeaderContents

Public Sub New(ByVal value As String)
Me.CustomValue = value
End Sub

Public Property CustomValue() As String
Get
Return val
End Get
Set(ByVal value As String)
val = value
End Set
End Property

Public Overrides ReadOnly Property Name() As String
Get
Return "custom_name"
End Get
End Property

Public Overrides ReadOnly Property [Namespace]() As String
Get
Return "http://someplace.com"
End Get
End Property

Public Shadows ReadOnly Property MustUnderstand() As Boolean
Get
Return False
End Get
End Property
End Class 'MyMessageHeader
 
Thanks for your reply Mike,

I think the code you used should be ok and for the custome contractBehavior
approach I mentioned, you only need to configure the extension at
client-side(do not need to modify service). However, onething very
important is the current binding your service using. Your sevice should be
using some binding that support message layer security and my test are
using the default "wsHttpBinding" setting.

I've build a new test client that use certificate client credentials to
call a service secured via wshttpbinding. Here is the VB.NET version code:


========VB client code========
Sub CallService()

Dim client As New CalcSVC.CalcServiceClient


client.Endpoint.Contract.Behaviors.Add( _
New VBContractBehavior("custom_name", "http://someplace.com") _
)

client.ClientCredentials.ClientCertificate.SetCertificate( _
StoreLocation.CurrentUser, _
StoreName.My, _
X509FindType.FindByThumbprint, _
"9f1bbe2bf87df0e4c021292ffd8c68ad08648b7c")


Using New OperationContextScope(client.InnerChannel)


OperationContext.Current.OutgoingMessageHeaders.Add( _
New MyCustomSoapHeader("test header") _
)

Dim returnValue As String = client.GetDescription()

Console.WriteLine(returnValue)

End Using
End Sub
======================================

and I include the app.config file below:

=======VB client App.config file============
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalcService">
<security mode="Message">
<message clientCredentialType="Certificate"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:11111/CalcService"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalcService"
contract="CalcSVC.ICalcService"
name="WSHttpBinding_ICalcService">

<identity>
<certificate encodedValue=".....[depend on the
server-side certificate].........." />
</identity>

</endpoint>
</client>
</system.serviceModel>
===================

when calling the service, you can use WCF message trace/log to view the
message sending/receving. Here is the outgoing message I captured, you can
see that the "custom_name" header is signed(with a u:Id ):

=====logged soap message=======
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_2"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd"
xmlns:a="http://www.w3.org/2005/08/addressing">GetDescription</a:Action>
<custom_name u:Id="_3" name="test header" xmlns="http://someplace.com"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd"></custom_name>
....................
==============================

BTW, I've posted the detailed about securing a dynamic message header in
WCF on my blog. You can also have a look there.

http://blogs.msdn.com/stcheng/archive/2009/02/18/wcf-secure-a-dynamically-ad
ded-message-header-via-behavior-extension-part-1.aspx

http://blogs.msdn.com/stcheng/archive/2009/02/19/wcf-secure-a-dynamically-ad
ded-message-header-via-behavior-extension-part-2.aspx

If you still have anything unclear, please feel free to let me know.


Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.


--------------------
From: =?Utf-8?B?TWlrZSBMb2dhbg==?= <[email protected]>
References: <[email protected]>
Subject: RE: Sign custom SOAP Header on outbound call with WCF
Date: Thu, 19 Feb 2009 03:54:01 -0800
 
Hello Steven,

I think I'm getting somewhere. I used your binding to start with. When
negotiateServiceCredential is "true" it sends the xml message below (ex. 1).
My broker has no clue what to do with it. So I set
negotiateServiceCredential to false. Then I get the error "The client
certificate is not provided. Specify a client certificate in Client
Credentials.". So I changed my client code to (ex. 2) and it still couldn't
find the cert. I made sure that COMPUTER/USERS had read access to the cert
using the WSE 3.0 Certificate tool. I also ensured the cert was in the
Trusted Cert. Authorities group. The cert is located in my Local Machine,
not Current User.

So I was playing around with the binding some more and I changed
clientCredentialType to None. I got this weird error about "Identity check
failed for outgoing message. The expected DNS identity of the remote
endpoint was 'mycompany.com' but the remote endpoint provided DNS claim
'mycert'. I looked up that error and added <identity> section in the client
section of the config file, see ex 3.

That sent a request to my web service broker, however it didn't understand
it still, and the custom soap header was gone, see ex 4. So I'm stuck with
the following binding and client endpoint in the app.config ex 5.

Again thanks for the help. As you can see I'm thoroughly confused.

Mike Logan


==========================
example 1
==========================

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action
s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>

<a:MessageID>urn:uuid:1376a079-3df5-4df3-a3f4-047fd9bc6ecf</a:MessageID>
<a:ReplyTo>

<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To
s:mustUnderstand="1">http://mycompany.com/svcaddresslocation</a:To>
</s:Header>
<s:Body>
<t:RequestSecurityToken
Context="blah blah"
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">

<t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>

<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:KeySize>256</t:KeySize>
<t:BinaryExchange

EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType=" http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego">blah
blah</t:BinaryExchange>
</t:RequestSecurityToken>
</s:Body>
</s:Envelope>


==========================
example 2
==========================
changed from this:
clientproxy.ClientCredentials.ClientCertificate.SetCertificate( _
"cn=mycert", _

System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, _
System.Security.Cryptography.X509Certificates.StoreName.My)

to this:

clientproxy.ClientCredentials.ServiceCertificate.SetDefaultCertificate( _

System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, _
System.Security.Cryptography.X509Certificates.StoreName.My, _

System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
_
"mycert")

I also tried cn=mycert there to. Still couldn't find the cert.

==========================
example 3
==========================
<endpoint address="http://mycompany.com/svcaddresslocation"
binding="wsHttpBinding" bindingConfiguration="MyBinding1"
contract="Service1Proxy.Service1Soap"
name="MyBinding1">
<identity>
<dns value="mlogansc1" />
</identity>
</endpoint>

==========================
example 4
==========================

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1"
u:Id="_4">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>
<a:MessageID
u:Id="_5">urn:uuid:cb3e3e0a-a304-4566-be59-1f150c366f32</a:MessageID>
<a:ReplyTo u:Id="_6">

<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1"
u:Id="_7">http://mycompany.com/svcaddresslocation</a:To>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="uuid-cc9549b3-8fb7-4da3-a848-b6292a842ae8-3">
<u:Created>2009-02-20T12:34:33.054Z</u:Created>
<u:Expires>2009-02-20T12:39:33.054Z</u:Expires>
</u:Timestamp>
<e:EncryptedKey
Id="uuid-cc9549b3-8fb7-4da3-a848-b6292a842ae8-2"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
xmlns="http://www.w3.org/2000/09/xmldsig#"/>
</e:EncryptionMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:KeyIdentifier

EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">f9oeOUyFG4RonLQRVm0G0yS68Vk=</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>a long cipher value</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
<c:DerivedKeyToken u:Id="_0"
xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<o:SecurityTokenReference>
<o:Reference
URI="#uuid-cc9549b3-8fb7-4da3-a848-b6292a842ae8-2"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"/>
</o:SecurityTokenReference>
<c:Offset>0</c:Offset>
<c:Length>24</c:Length>
<c:Nonce>some security value</c:Nonce>
</c:DerivedKeyToken>
<c:DerivedKeyToken u:Id="_1"
xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<o:SecurityTokenReference>
<o:Reference
URI="#uuid-cc9549b3-8fb7-4da3-a848-b6292a842ae8-2"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"/>
</o:SecurityTokenReference>
<c:Nonce>some security value</c:Nonce>
</c:DerivedKeyToken>
<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:DataReference URI="#_3"/>
<e:DataReference URI="#_8"/>
</e:ReferenceList>
<e:EncryptedData Id="_8"
Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:Reference URI="#_1"/>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>
some long cipher value
</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</o:Security>
</s:Header>
<s:Body u:Id="_2">
<e:EncryptedData Id="_3"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:Reference URI="#_1"/>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>some long cipher value</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>

my web service broker returned

SECU1037: Security Failure on Access Point 'MyService1'. Reason: SECU3766:
Encrypted elements detected but not specified by security contract.


==========================
example 5
==========================

<binding name="MyBinding1" useDefaultWebProxy="false">
<security mode="Message">
<message clientCredentialType="None" negotiateServiceCredential="false"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>

<client>
<endpoint address="http://mycompany.com/svcaddresslocation"
binding="wsHttpBinding" bindingConfiguration="MyBinding1"
contract="Service1ClientProxy.Service1Soap"
name="MyBinding1">
<identity>
<dns value="mycert" />
</identity>
</endpoint>
 
Just so we are on the same page this is the end result of what I need. I
made this request anonymous by changing the service name, operation name, and
other things.

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"

xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"

xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<wsa:Action>http://www.somecompany.com/Service1/Operation1</wsa:Action>

<wsa:MessageID>urn:uuid:8ff585c9-60df-40fd-8453-edebcc170ee9</wsa:MessageID>
<wsa:ReplyTo>

<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://www.somecompany.com/Service1?WSDL</wsa:To>
<mycomp:CustomHeader wsu:Id="ID-0e743eb1-2ddf-407c-a588-129d072f5b3c"
xmlns:mycomp="http://www.somecompany.com">AppUser</mycomp:CustomHeader>
<wsse:Security
soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
soap:mustUnderstand="1">
<wsu:Timestamp
wsu:Id="Timestamp-137e7a9a-2f9f-4abe-bb0a-d827719cf00a">
<wsu:Created>2009-02-23T11:00:18Z</wsu:Created>
<wsu:Expires>2009-02-23T11:05:18Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken

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

ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="SecurityToken-140c2271-db42-41c8-adb4-4d3a4d548c9f"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">SOME LONG STRING WAS HERE</wsse:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#ID-0e743eb1-2ddf-407c-a588-129d072f5b3c">
<Transforms>
<Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>A DIGEST VALUE WAS HERE</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>SOEM LONG STRING WAS HERE</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference

URI="#SecurityToken-140c2271-db42-41c8-adb4-4d3a4d548c9f"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body>
<Operation1 xmlns="http://www.somecompany.com/Service1">
<object1>hello there</object1>
</Operation1>
</soap:Body>
</soap:Envelope>
 
Thanks for your reply Mike,

So I think the problem is also a bit specific to the ws-* secured
webservice you're calling. At your side, the WCF client generated the
proxy(and bindingsettings) according to the webservice(the service policy
in wsdl). Therefore, the test WCF service I used on my side(which simply
use a wshttpbinding with message security) will not quite conform to your
enviornment.

I'll need to perform more investigation on this. Is it possible for you to
give me a public internet address of the webservice for test? Also, if
convenient, would you start a new thread so that we can continue working on
this problem in the new thread?

Looking forward to your reply.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.


--------------------
 
Back
Top