MessageSecurityException when consuming WCF service

G

Guest

Hi,

Recently I'm confused by this exception.
-----
The message could not be processed. This is most likely because the action
'http://tempuri.org/IBCC2MatrixService/UserMatchingSearch' is incorrect or
because the message contains an invalid or expired security context token or
because there is a mismatch between bindings. The security context token
would be invalid if the service aborted the channel due to inactivity. To
prevent the service from aborting idle sessions prematurely increase the
Receive timeout on the service endpoint's binding.
-----
This happens when I try to call a WCF service method. It doesn't happend all
the time and I haven't found any pattern yet. What can I do to solve this? Is
there any best practice on how to establish WCF connection and release them?

Thanks.

Daniel
 
S

Steven Cheng[MSFT]

Hi Daniel,

From your description, you're encountering the following error when running
a WCF based client server communication application, correct?

=========
The message could not be processed. This is most likely because the action
'http://tempuri.org/IBCC2MatrixService/UserMatchingSearch' is incorrect or
because the message contains an invalid or expired security context token
or
because there is a mismatch between bindings. The security context token
would be invalid if the service aborted the channel due to inactivity. To
prevent the service from aborting idle sessions prematurely increase the
Receive timeout on the service endpoint's binding.
=========

Regarding on the error info, I've performed some research and found some
cases with similar symptom. I'd like to confirm some things about your WCF
client, server applications:

** What's the type of endpoint binding type are you using and are you using
Message layer security to secure the service communiaton?

** For the client-side, are you using the autogenerated proxy class?

According to those former issue with the similar error message, the problem
is likely caused by the securitycontextToken be expired (client send to
server). When you use message layer security, the generated proxy will use
established security context token to communicate with server. However,
when the server close the connection (for some reason), the client is not
going to know the service connection timed out until it actually tries to
contact the service...which raises the exception.

If the problem in your case does be due to the above reason, you can
consider the following resolutions:
The best solution is to catch the exception and then abort the proxy and
recreate it.

Or you can also disable message layer security and use transport layer
security.
<<<<<<<<<<<<<<<

Hope this helps some.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



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

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 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 or complex
project analysis and dump analysis issues. 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/subscriptions/support/default.aspx.

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


This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Steven,

I'm using wsHttpBinding. What is "Message layer security"? Is it the
following config in app.config?
--
<identity>
<userPrincipalName value="daniel" />
</identity>
--
The proxy is auto generated.
I found that if I increase the ReceiveTime on server side, this exception
doesn't appear as often as before.

Thanks.

Daniel
 
S

Steven Cheng[MSFT]

Thanks for your reply Daniel,

As for the "Message Layer security", it is one of the two security modes of
WCF service(Message Layer security and Transport layer security):

#Message Security in WCF
http://msdn2.microsoft.com/en-us/library/ms733137.aspx

#Transport Security
http://msdn2.microsoft.com/en-us/library/ms733043.aspx

When using "message Layer security", that means you secure your WCF message
through encrypt the message itself rather than rely on the transport
protocol(TCP, http) to secure the channel.

Yes, "ReceiveTime" does helps some here. This is because when you enlarge
"REceiveTime", the server-side become more unlikely to timeout and dispose
the channel, thus the "security context token" at client-side will become
unlikely to expire. But this is not a thorough solution since it only make
it infrequent. The most recommended approach is to manually capture the
exception and then recreate the client proxy.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thanks Steven.

Could I ask more about manually capturing this exception? This exception
occurs when I'm calling a service method. Something like this:
--
MethodResponse response = proxy.Method(request);
--
If I need to catch it and recreate the proxy, it would be something like this:
--
MethodResponse response = null;
try
{
response = proxy.Method(request);
}
catch(MessageSecurityException)
{
proxy = new ServiceClient();
response = proxy.Method(request);
}
--
It is quite some work to refactor the code based on the fact that we do have
a good amount of service methods. Is this what you recommend?


Daniel
 
S

Steven Cheng[MSFT]

Thanks for your reply Daniel,

Yes, you need to at least wrap the "proxy.methodcall" code statement in
try...catch... block so as to capture the potential exception from service.

And so far this is most recommended approach(without changing other design
or configuratrion such as security model) according to some former issue
records.

BTW, some community member and I have also provide some suggestion in your
another thread about "getting application physical path in WCF service
hosted in IIS". Please feel free to have a look there.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Daniel,

Any further question on this? If so, please feel free to let me know.

Thank you for your posting!

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Siyad

Hi,

I am really confused! and couldn't find any resource to solve my confusion.
I am not sure whether this is an appropriate place to ask WCF query. Since i
found this WCF releted query here, i assume this may be a proper place. Ok
now let me move to the query.

I have a WCF service which will authenticate the clients accessing it using
a valid username/password from Active Directory or local machine. I am
hosting my service in IIS and i have disabled 'anonymous access' option too
instead i turned on Integrated Windows Authentication option. Now when i try
to access the SVC file of service thru browser it is asking me for windows
user id / password. But same way if i try to invoke a service method from
client application it fails and throws an exception. I am setting the
clientproxy's clientcredential appropriately. Just like the one below


ServiceClient client = new ServiceClient();
client.ClientCredentials.Windows.ClientCredential = new
System.Net.NetworkCredential("Others", "password");
MessageBox.Show(client.GetData(1234));
client.Close();


Here is my Web.config file portion

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConfig" >
<security>
<message negotiateServiceCredential="false"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="IService"
bindingConfiguration="wsHttpBindingConfig">
<!--
Upon deployment, the following identity element should be
removed or replaced to reflect the
identity under which the deployed service runs. If removed,
WCF will infer an appropriate identity
automatically.
-->
<identity>
<servicePrincipalName value="localhost/ASTRIX"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set
the value below to true. Set to false before deployment to avoid disclosing
exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Here is client side app.config

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32"
maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"
/>
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://astrix/WinAuthDemoWCFService/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<userPrincipalName value="localhost/ASTRIX" />
</identity>
</endpoint>
</client>
</system.serviceModel>

When i try to access the service method from client, getting following
exception

SecurityMessageException-{"The HTTP request is unauthorized with client
authentication scheme 'Anonymous'. The authentication header received from
the server was 'Negotiate,NTLM'."}
InnerException - (WebException) - {"The remote server returned an error:
(401) Unauthorized."}.


is there anything extra i have to setup?.... What is the role of SPN and UPN
in this scenario?

Thanks in Adv,
Siyad
 
S

Siyad

Hi,

I am really confused! and couldn't find any resource to solve my confusion.
I am not sure whether this is an appropriate place to ask WCF query. Since i
found this WCF releted query here, i assume this may be a proper place. Ok
now let me move to the query.

I have a WCF service which will authenticate the clients accessing it using
a valid username/password from Active Directory or local machine. I am
hosting my service in IIS and i have disabled 'anonymous access' option too
instead i turned on Integrated Windows Authentication option. Now when i try
to access the SVC file of service thru browser it is asking me for windows
user id / password. But same way if i try to invoke a service method from
client application it fails and throws an exception. I am setting the
clientproxy's clientcredential appropriately. Just like the one below


ServiceClient client = new ServiceClient();
client.ClientCredentials.Windows.ClientCredential = new
System.Net.NetworkCredential("Others", "password");
MessageBox.Show(client.GetData(1234));
client.Close();


Here is my Web.config file portion

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConfig" >
<security>
<message negotiateServiceCredential="false"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="IService"
bindingConfiguration="wsHttpBindingConfig">
<!--
Upon deployment, the following identity element should be
removed or replaced to reflect the
identity under which the deployed service runs. If removed,
WCF will infer an appropriate identity
automatically.
-->
<identity>
<servicePrincipalName value="localhost/ASTRIX"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set
the value below to true. Set to false before deployment to avoid disclosing
exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Here is client side app.config

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32"
maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"
/>
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://astrix/WinAuthDemoWCFService/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<userPrincipalName value="localhost/ASTRIX" />
</identity>
</endpoint>
</client>
</system.serviceModel>

When i try to access the service method from client, getting following
exception

SecurityMessageException-{"The HTTP request is unauthorized with client
authentication scheme 'Anonymous'. The authentication header received from
the server was 'Negotiate,NTLM'."}
InnerException - (WebException) - {"The remote server returned an error:
(401) Unauthorized."}.


is there anything extra i have to setup?.... What is the role of SPN and UPN
in this scenario?

Thanks in Adv,
Siyad
 
S

Siyad

Hi,

I am really confused! and couldn't find any resource to solve my confusion.
I am not sure whether this is an appropriate place to ask WCF query. Since i
found this WCF releted query here, i assume this may be a proper place. Ok
now let me move to the query.

I have a WCF service which will authenticate the clients accessing it using
a valid username/password from Active Directory or local machine. I am
hosting my service in IIS and i have disabled 'anonymous access' option too
instead i turned on Integrated Windows Authentication option. Now when i try
to access the SVC file of service thru browser it is asking me for windows
user id / password. But same way if i try to invoke a service method from
client application it fails and throws an exception. I am setting the
clientproxy's clientcredential appropriately. Just like the one below


ServiceClient client = new ServiceClient();
client.ClientCredentials.Windows.ClientCredential = new
System.Net.NetworkCredential("Others", "password");
MessageBox.Show(client.GetData(1234));
client.Close();


Here is my Web.config file portion

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConfig" >
<security>
<message negotiateServiceCredential="false"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="IService"
bindingConfiguration="wsHttpBindingConfig">
<!--
Upon deployment, the following identity element should be
removed or replaced to reflect the
identity under which the deployed service runs. If removed,
WCF will infer an appropriate identity
automatically.
-->
<identity>
<servicePrincipalName value="localhost/ASTRIX"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set
the value below to true. Set to false before deployment to avoid disclosing
exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Here is client side app.config

<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32"
maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"
/>
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://astrix/WinAuthDemoWCFService/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<userPrincipalName value="localhost/ASTRIX" />
</identity>
</endpoint>
</client>
</system.serviceModel>

When i try to access the service method from client, getting following
exception

SecurityMessageException-{"The HTTP request is unauthorized with client
authentication scheme 'Anonymous'. The authentication header received from
the server was 'Negotiate,NTLM'."}
InnerException - (WebException) - {"The remote server returned an error:
(401) Unauthorized."}.


is there anything extra i have to setup?.... What is the role of SPN and UPN
in this scenario?

Thanks in Adv,
Siyad
 

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