The underlying connection was closed: The connection was closed unexpectedly
This is a generic error, and since I am very new to wcf I don't know where to start diagnosing the problem. I've been searching google for hours, and really need an advice from someone with more experience with wcf. So please bear with me, I will try to describe the problem the best I can.
My domain is made of a wcf project and a class library project where i have the data entities. I have 1 svc file. I call the service in my asp.net mvc 3 controller. doing something pretty simple. I will post the relevant code and stack trace.
I am trying to display a list of candidates in the list action of the candidates controller. I added a service reference to the mvc project, and pointed it to my localhost (the service it was discovered and it is running).
Stack Trace:
[WebException: The underlying connection was closed: The connection was closed unexpectedly.]
System.Net.HttpWebRequest.GetResponse() +6117395
System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +48
[CommunicationException: The underlying connection was closed: The connection was closed unexpectedly.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +9440287
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +345
ADMWeb.UI.ADMServices.IADM.GetCandidateList() +0
ADMWeb.UI.ADMServices.ADMClient.GetCandidateList() in C:\Users\ori\Documents\Visual Studio 2010\Projects\ADMWeb\ADMWeb.UI\Service References\ADMServices\Reference.cs:1025
ADMWeb.UI.Controllers.CandidatesController.Index() in C:\Users\ori\Documents\Visual Studio 2010\Projects\ADMWeb\ADMWeb.UI\Controllers\CandidatesController.cs:22
lambda_method(Closure , ControllerBase , Object[] ) +62
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9030045
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
The Error:
Line 1024: public ADMWeb.UI.ADMServices.Candidate[] GetCandidateList() {
Line 1025: return base.Channel.GetCandidateList(); Line 1026: }
ADM.svc:
namespace ADMServices
{
public class ADM : IADM
{
public List<Candidate> GetCandidateList()
{
List<Candidate> candidateList = new List<Candidate>();
candidateList = CandidateManager.GetCandidateList();
return candidateList;
}
}
}
Candidates Controller (List Action):
ADMClient client = new ADMClient();
List<Candidate> candidates = client.GetCandidateList().ToList();
return View(candidates);
WCF Project web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<connectionStrings>
<add name="ADMConnectionString" connectionString="Data Source=;Initial Catalog=ADM_ATID;Persist Security Info=True;User ID;Password"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="myUserTraceSource"
switchValue="Information, ActivityTracing">
<listeners>
<add name="xml"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="Error.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
MVC web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IADM" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:49341/ADM.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IADM" contract="ADMServices.IADM"
name="BasicHttpBinding_IADM" />
</client>
The first thing i will do is, instead of returning the full list of candidates i will return an empty list. If that works fine, then it is very clear that the size of the data is a problem. To modify the size play with your binding parameters.
Related
i'm writing a wcf service to handle large files, i've followed the rules explained on msdn and found around on web. The service download method returns a stream and calls a business logic object which searches for documents into an ecm . the ecm api raises an exception when there aren't matching documents and the bl object returns a null stream.
The server side code executes without exceptions, but when the response reaches the client i got a System.ServiceModel.CommunicationException : The underlying connection was closed: The connection was closed unexpectedly .
I've searched the web and all problems related to that exception refer to excessive size of returned values , while i'm having the opposite problem. My question is there's a specific way to handle null return streams ? Is something related to the service or client configuration ? at the moment i'm returning an empty stream , but it doesn't look a smart solution .
Below i've addded sever-client configuration and the trace of the wcf service.
Server configuration:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpBindingConf" transferMode="StreamedResponse" messageEncoding="Text"
maxBufferSize="5000000" maxReceivedMessageSize="1073741824"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<!--<security mode="Transport">
<transport clientCredentialType="None"/>
</security>-->
<readerQuotas maxBytesPerRead="4096" maxStringContentLength="65536" maxArrayLength="5000000" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="FileNetLoaderService.FileNetLoaderServiceBehavior" name="FileNetLoaderService.FileNetLoaderService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="httpBindingConf"
contract="FileNetLoaderService.FileNetLoaderService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<!--<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="FileNetLoaderService.FileNetLoaderServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<!--<serviceMetadata httpsGetEnabled="true" />-->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
client configuration :
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_FileNetLoaderService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="1073741824"
messageEncoding="Text" textEncoding="utf-8" transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2436/FileNetLoaderService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_FileNetLoaderService"
contract="localFilenetLoaderService.FileNetLoaderService"
name="BasicHttpBinding_FileNetLoaderService" />
</client>
</system.serviceModel>
trace log
<TraceData><DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/it-IT/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>TestForm.vshost.exe</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The underlying connection was closed: The connection was closed unexpectedly.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at TestForm.localFilenetLoaderService.FileNetLoaderService.downLoad(String guid, String CodiceAzienda, String TipoLavorazione)
at TestForm.localFilenetLoaderService.FileNetLoaderServiceClient.downLoad(String guid, String CodiceAzienda, String TipoLavorazione)
at TestForm.Form1.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TestForm.Program.Main()
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
</StackTrace>
<ExceptionString>System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---</ExceptionString>
<InnerException>
<ExceptionType>System.Net.WebException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The underlying connection was closed: The connection was closed unexpectedly.</Message>
<StackTrace>
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
</StackTrace>
<ExceptionString>System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)</ExceptionString>
</InnerException>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
a piece of code
server
System.IO.Stream s = myDBRead.GetDocumentStream(guid, out filename);
if (s == null)
return new MemoryStream();
return s;
client
try
{
object ss = client.downLoad("297584cf-29c2-4ad5-be37-5219ad04cb74", "5728", "Effetti");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
the answer to my question is here
just my lack of knwoledge of stream class
I'm using ACS/Service Identities as a temporary STS while I get things into place. Unfortunately, while I appear to be able to get a SAML 1.1 token fine from ACS, the second I try to pass it into my WCF service things go crazy. As far as I can tell, the token isn't expired (it's being used promptly), I'm not sure how it could be invalid, and nothing I've done with logging has displayed to me any detail on what exactly could be wrong. I'm tempted to assign blame to the binding, because I've never done a formal WCF/WIF binding before. Can anyone see anything wrong with the client/server bindings I'm using (the client was generated via service reference), or suggest an alterative avenue of investigation?
BTW, both the server and client are running on the same development machine.
Web.config:
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
<add key="ida:FederationMetadataLocation" value="--omitted--" />
<add key="ida:ProviderSelection" value="productionSTS" />
</appSettings>
<location path="FederationMetadata">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.5">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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" />
<serviceCredentials useIdentityConfiguration="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="https" binding="ws2007FederationHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"/>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true" />
</system.webServer>
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="https://localhost:44300/Service1.svc" />
</audienceUris>
<issuerNameRegistry>
<trustedIssuers>
<add name="--omitted--" thumbprint="--omitted--"/>
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None"/>
</identityConfiguration>
</system.identityModel>
</configuration>
App.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IService1">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" issuedTokenType="">
<tokenRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</trust:TokenType>
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:51853/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
<endpoint address="https://localhost:44300/Service1.svc" binding="ws2007FederationHttpBinding"
bindingConfiguration="WS2007FederationHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WS2007FederationHttpBinding_IService1" />
</client>
</system.serviceModel>
Client code:
static void Main(string[] args)
{
var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress("--Azure ACS URL omitted--"));
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.UserName.UserName = "--omitted--";
factory.Credentials.UserName.Password = "--omitted--";
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new EndpointReference("https://localhost:44300/Service1.svc")
};
SecurityToken token = factory.CreateChannel().Issue(rst);
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false;
var factory2 = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost:44300/Service1.svc"));
factory2.Credentials.SupportInteractive = false;
factory2.Credentials.UseIdentityConfiguration = true;
var proxy = factory2.CreateChannelWithIssuedToken(token);
var info = proxy.GetData("testing"); // Exception thrown here
}
Exception:
System.ServiceModel.Security.MessageSecurityException was unhandled
HResult=-2146233087
Message=An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at TestWCFClient.ServiceReference1.IService1.GetData(String value)
at TestWCFClient.Program.Main(String[] args) in c:\Users\nicole\Documents\Visual Studio 2012\Projects\TestWCFClient\Program.cs:line 43
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.ServiceModel.FaultException
HResult=-2146233087
Message=The message could not be processed. This is most likely because the action 'http://tempuri.org/IService1/GetData' 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.
InnerException:
ETA:
In addition, I've tried: switching to SAML 2.0, switching to JWT with the preview JWT token handler, changing the receive timeout, switching the host machine time to UTC, syncing the host with the Windows Time Service explicitly, and waiting for five minutes after the token is issued before using it.
The MessageSecurityException was right: it's a binding error.
I was mixing a couple of code samples together and got bitten by the mismatch. EstablishSecurityContext is not just window dressing, it is a real part of the binding, and the values must match between service and client.
My application code reads:
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false; // this line is the problem
The service binding is:
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"/> <!-- this line does not match -->
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
The service binding should be:
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" establishSecurityContext="false"/>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
And presto, it works.
I have a general purpose hosting service for WCF (.net v4). It allows for multiple agents to be dropped in plug-in style with each agent having its own config file. It was written as a service since all sites will not have IIS or WAS intalled but we can specify .net v4 and our custome service.
We have had no issues with HTTP, HTTPS or TCP (without credentials). When we add, a certificate to the server it appears to start without an issue. As soon as we attempt to call the servie we get a channel fault. We wrote a small self-hosting program that uses the config file rather than programmatically creating the endpoing and it works without any issue. We can only speculate we missed a setting but cannot identify which.
The error we get is shown below. It appears that for some reason the client it trying to set up a dual-channel tcp connection which we did not configure in the host.
Protocol Type application/negotiate was sent to a service that does not support that type of upgrade.
System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.ServerFramingDuplexSessionChannel.ProcessUpgradeRequest(TimeoutHelper& timeoutHelper)
System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.ServerFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
System.ServiceModel.Channels.CommunicationObject.Open()
System.ServiceModel.Channels.ReliableChannelListener`3.HandleAcceptComplete(TInnerChannel channel)
System.ServiceModel.Channels.ReliableChannelListener`3.OnAcceptCompleted(IAsyncResult result)
System.ServiceModel.Channels.ReliableChannelListener`3.OnAcceptCompletedStatic(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.ServiceModel.Diagnostics.TraceUtility.<>c__DisplayClass4.<CallbackGenerator>b__2(AsyncCallback callback, IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.TcpDuplexChannelListener.System.ServiceModel.Channels.ISessionPreambleHandler.HandleServerSessionPreamble(ServerSessionPreambleConnectionReader preambleReader, ConnectionDemuxer connectionDemuxer)
System.ServiceModel.Channels.ConnectionOrientedTransportManager`1.OnHandleServerSessionPreamble(ServerSessionPreambleConnectionReader serverSessionPreambleReader, ConnectionDemuxer connectionDemuxer)
System.ServiceModel.Channels.ConnectionDemuxer.OnSessionPreambleKnown(ServerSessionPreambleConnectionReader serverSessionPreambleReader)
System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.ContinueReading()
System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.StartReading(Action`1 viaDelegate, TimeSpan receiveTimeout)
System.ServiceModel.Channels.ConnectionDemuxer.OnDuplexConnection(IConnection connection, Action connectionDequeuedCallback, Int64 streamPosition, Int32 offset, Int32 size, TimeSpan timeout)
System.ServiceModel.Channels.ConnectionDemuxer.OnConnectionModeKnownCore(ConnectionModeReader modeReader, Boolean isCached)
System.ServiceModel.Channels.ConnectionDemuxer.OnConnectionModeKnown(ConnectionModeReader modeReader)
System.ServiceModel.Channels.ConnectionModeReader.Complete()
System.ServiceModel.Channels.ConnectionModeReader.ReadCallback(Object state)
System.ServiceModel.Channels.TracingConnection.TracingConnectionState.ExecuteCallback()
System.ServiceModel.Channels.TracingConnection.WaitCallback(Object state)
System.ServiceModel.Channels.SocketConnection.FinishRead()
System.ServiceModel.Channels.SocketConnection.AsyncReadCallback(Boolean haveResult, Int32 error, Int32 bytesRead)
System.ServiceModel.Channels.OverlappedContext.CompleteCallback(UInt32 error, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
CLIENT:
<netTcpBinding>
<binding name="NetTcpEndPoint_ISolutionsDataAccessorV01" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:1177/TcpService" binding="netTcpBinding"
bindingConfiguration="NetTcpEndPoint_ISolutionsDataAccessorV01"
contract="sDAL.ISolutionsDataAccessorV01" name="NetTcpEndPoint_ISolutionsDataAccessorV01">
<identity>
<userPrincipalName value="abc#xyz.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
SERVICE:
-->
<behaviors>
<serviceBehaviors>
<behavior name="SolutionsDALServiceBehavior">
<serviceCredentials>
<serviceCertificate findValue="STSTestCert"
x509FindType="FindByIssuerName" />
</serviceCredentials>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
I have a WCF service that uses message security over HTTPS using wsHttpBinding behind load balancer. When connects to the service on web browser via https, it works. However, Windowns forms client failed, using certificate over https,
Update
The request url is https, but after the exception saying http, below is exception tracing on server side:
For example: the request url is
https://www.server.com/wcf.svc'.
But it becomes
http://www.server.com:81/wcf.svc' on the server side. Is it the load balancer causing it.
System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
There was no channel actively listening at 'http://www.server.com:81/wcf.svc'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening.
Below is the WCF service config:
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" />
</diagnostics>
<services>
<service behaviorConfiguration="verServiceBehaviour" name="ver.Service">
<endpoint address="ver" binding="wsHttpBinding" bindingConfiguration="wshttpbindingcfg"
contract="ver.Iver" behaviorConfiguration ="verEndpointBehaviour">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mexhttpbinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://www.server.com/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<mexHttpBinding>
<binding name="mexhttpbinding" />
</mexHttpBinding>
<wsHttpBinding>
<binding name="wshttpbindingcfg" maxReceivedMessageSize="2000000000" sendTimeout="00:10:00">
<readerQuotas maxStringContentLength="2000000000"/>
<reliableSession ordered="true" enabled="false" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="verEndpointBehaviour">
<instanceContextBehavior/>
<verInspectorBehavior/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="verServiceBehaviour">
<dataContractSerializer maxItemsInObjectGraph="100000000"/>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" trustedStoreLocation="LocalMachine" mapClientCertificateToWindowsAccount="false"/>
</clientCertificate>
<serviceCertificate
x509FindType="FindByThumbprint"
findValue="xxxx"
storeLocation="LocalMachine"
storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Below is client config:
<configuration>
<appSettings>
<add key="CertificateSubjectName" value="subjectName"/>
</appSettings>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ver.IverHTTPS" 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="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://www.server.com/wcf.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ver.IverHTTPS"
contract="ServiceReference.verIver" name="verEndPoint" />
</client>
</system.serviceModel>
</configuration>
below is code in client using certificate:
var proxyClient = new ServiceReference.VerIVerClient("verEndPoint");
proxyClient.ClientCredentials.ClientCertificate.SetCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
subjectName");
proxyClient.CallService()
Below is exception received at client side:
System.ServiceModel.EndpointNotFoundException was unhandled
Message=There was no endpoint listening at https://ver20.server.com/wcf.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at verClient.ServiceReference.verIver.GetClaimver(GetClaimverClaimApplication ClaimApplication)
at verClient.ServiceReference.verIverClient.GetClaimver(GetClaimverClaimApplication ClaimApplication) in D:\Projects\ver\verClient\Service References\ServiceReference\Reference.cs:line 11330
at verClient.verForm.PostXmlTover(GetClaimverClaimApplication ClaimApplication) in D:\Projects\ver\verClient\verForm.cs:line 1408
at verClient.verForm.PostButton_Click(Object sender, EventArgs e) in D:\Projects\ver\verClient\verForm.cs:line 34
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at verClient.Program.Main() in D:\Projects\ver\verClient\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Net.WebException
Message=The remote server returned an error: (404) Not Found.
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
InnerException:
Review the configuration of your load balancer, and make sure that the requests are being for warded to the correct host AND PORT number. If the port number you chose is not standard, make sure to adjust the IIS Site Binding and the base address of your service.
One important thing to understand about transport security is that it has to be configured on a "hop" by "hop" basis. In your example, you have two hops (client) -> (load balancer) and (load balancer) -> (server).
Securing your connection from the client to the load balancer doesn't automatically configure security from the load balancer to the server. You need to install and configure an ssl certificate on both the load balancer and the server.
Your initial https request ended up being an http request on the server, that is a good indication that you did not configure a secure channel between the load balancer and the server.
If you do not wish to secure the connection between the load balancer and the server, then expose your service without transport security. With this, you can still have the communication from the client to the load balancer (the first hop) on ssl.
I’m having an issue using ADFS2 to secure a back-end WCF service that is being called from Passively Federated Website. I have the passive federation working on the website, but the back-end service is giving me problems.
The pieces of the puzzle.
Silverlight Client that is being served from Passively Federated Website.
The Silverlight calls a WCF service (App Service), hosted on the passively Federated Website.
I have SaveBootstrapToken set to true in the config.
From the App Service, I want to call a back-end WCF service using BootstrapToken with the ActAs scenarion.
Federated Website and Back-end WCF service are setup as separate RPs in the ADFS2, token encryption is turned on. Both are allowed to delegate.
Back-end Service configuration:
I have WIF incorporated into the pipeline using behavior extension.
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IQuoteService">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
</issuer>
<issuerMetadata address="https://myADFSserver/adfs/services/trust/mex">
</issuerMetadata>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<behaviors>
<serviceBehaviors>
<behavior name="">
<federatedServiceHostConfiguration name="Service.QuoteService" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="000000000000000000000000000000" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service.QuoteService">
<endpoint address="" binding="ws2007FederationHttpBinding" contract="Service.IQuoteService" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Client Configuration
When add the service using Add Service Reference tooling, the following config on the client gets created:
<customBinding>
<binding name="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
<security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport"
requireDerivedKeys="false" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
<issuedTokenParameters keySize="256" keyType="SymmetricKey" tokenType="">
<additionalRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
<trust:KeySize>256</trust:KeySize>
<trust:KeyWrapAlgorithm>http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
<trust:EncryptWith>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
<trust:SignatureAlgorithm>http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignatureAlgorithm>
<trust:CanonicalizationAlgorithm>http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</additionalRequestParameters>
</issuedTokenParameters>
<localClientSettings cacheCookies="true" detectReplays="false"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Default" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="false" />
</binding>
</customBinding>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IQuoteService" 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">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message algorithmSuite="Default" issuedKeyType="SymmetricKey"
negotiateServiceCredential="true">
<issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"
binding="customBinding" bindingConfiguration="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256" />
<issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" />
<tokenRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
<trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
<trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
<wsid:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
</trust:Claims>
<trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
<trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
<trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<client>
<endpoint address="http://myServiceHost/Service/QuoteService.svc"
binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService"
contract="QuoteService.IQuoteService" name="WS2007FederationHttpBinding_IQuoteService">
<identity>
<certificate encodedValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</identity>
</endpoint>
</client>
Here's the Service Client Code:
List<Quote> quoteList = new List<Quote>();
ClaimsPrincipal myClaimsPrincipal = System.Web.HttpContext.Current.User as ClaimsPrincipal;
SecurityToken bootstrapToken = myClaimsPrincipal.Identities[0].BootstrapToken;
if (bootstrapToken == null)
{
throw new Exception("bootstrap tokein is null. Logout and try again.");
}
ChannelFactory<IQuoteServiceChannel> factory = new ChannelFactory<IQuoteServiceChannel>("WS2007FederationHttpBinding_IQuoteService");
factory.Credentials.SupportInteractive = false;
factory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "0000000000000000000000000000");
factory.ConfigureChannelFactory();
IQuoteServiceChannel channel;
//Create the channel with the bootstrap token
channel = factory.CreateChannelActingAs(bootstrapToken);
try
{
quoteList = channel.GetQuotes(quoteUser);
channel.Close();
}
catch (SecurityAccessDeniedException sadex)
{
channel.Abort();
throw;
}
catch (CommunicationException exception)
{
channel.Abort();
throw;
}
catch (TimeoutException timeoutEx)
{
channel.Abort();
throw;
}
catch (Exception ex)
{
channel.Abort();
throw;
}
return quoteList;
This is the exception I get:
System.ServiceModel.Security.SecurityNegotiationException was unhandled by user code
Message=SOAP security negotiation with 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' failed. See inner exception for more details.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at Microsoft.IdentityModel.Protocols.WSTrust.FederatedSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.TryGetSupportingTokens(SecurityProtocolFactory factory, EndpointAddress target, Uri via, Message message, TimeSpan timeout, Boolean isBlockingCall, IList`1& supportingTokens)
at System.ServiceModel.Security.SymmetricSecurityProtocol.TryGetTokenSynchronouslyForOutgoingSecurity(Message message, SecurityProtocolCorrelationState correlationState, Boolean isBlockingCall, TimeSpan timeout, SecurityToken& token, SecurityTokenParameters& tokenParameters, SecurityToken& prerequisiteWrappingToken, IList`1& supportingTokens, SecurityProtocolCorrelationState& newCorrelationState)
at System.ServiceModel.Security.SymmetricSecurityProtocol.SecureOutgoingMessageCore(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
at System.ServiceModel.Security.MessageSecurityProtocol.SecureOutgoingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at OMG.Admin.DemoApp.Business.QuoteService.IQuoteService.GetQuotes(User quoteUser)
at OMG.Admin.DemoApp.Business.QuoteServiceClient.GetQuotes(User quoteUser) in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteServiceClient.cs:line 131
at OMG.Admin.DemoApp.Business.QuoteBO.GetQuoteList() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteBO.cs:line 26
at OMG.Admin.DemoApp.Web.Services.DemoAppService.GetQuotes() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Web\Services\DemoAppService.svc.cs:line 27
at SyncInvokeGetQuotes(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
InnerException: System.InvalidOperationException
Message=The address of the security token issuer is not specified. An explicit issuer address must be specified in the binding for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' or the local issuer address must be configured in the credentials.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateIssuedSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, Boolean disableInfoCard)
at Microsoft.IdentityModel.Protocols.WSTrust.FederatedClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
at System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, Boolean isOptional, IList`1 providerSpecList)
at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
InnerException:
I'm sure I'm missing something in the configuration and/or code can someone help me out?
I got this scenario working, here’s the solution for anyone interested.
Followed Dominick Baier’s post for ideas / code: http://leastprivilege.com/2010/10/14/wif-adfs-2-and-wcfpart-5-service-client-more-flexibility-with-wstrustchannelfactory/
I changed the back-end WCF service config to this:
<microsoft.identityModel>
<service>
<audienceUris>
<add value="https://localhost/Service/QuoteService.svc" />
<add value="https://localhost/Service/" />
</audienceUris>
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</serviceCertificate>
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add thumbprint="000000000000000000000000000000000000" name="http://myADFSserver/adfs/services/trust" />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None" />
</service>
</microsoft.identityModel>
<system.serviceModel>
<services>
<service name="Service.QuoteService">
<endpoint address=""
binding="ws2007FederationHttpBinding"
contract="Service.IQuoteService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<ws2007FederationHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true" />
<federatedServiceHostConfiguration />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="federatedServiceHostConfiguration"
type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
I’m no longer using WCF config on the client, it’s all done in code.
Here’s the client code:
public QuoteServiceClient()
{
SecurityToken actAsToken = this.GetDelegatedTokenUsername();
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
ChannelFactory<IQuoteServiceChannel> factory =
new ChannelFactory<IQuoteServiceChannel>(binding, new EndpointAddress(svcEndpoint));
factory.ConfigureChannelFactory<IQuoteServiceChannel>();
factory.Credentials.SupportInteractive = false;
this.channel = factory.CreateChannelWithIssuedToken<IQuoteServiceChannel>(actAsToken);
}
private SecurityToken GetDelegatedTokenUsername()
{
var binding = new UserNameWSTrustBinding();
binding.SecurityMode = SecurityMode.TransportWithMessageCredential;
//UserNameMixed is this endpoint "/adfs/services/trust/13/usernamemixed"
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(UserNameMixed));
trustChannelFactory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;
trustChannelFactory.Credentials.SupportInteractive = false;
//Some User Account
//It's used to access the ADFS Server
//Act as is the actual Identity that Will be used.
//If you use one of windows bindings (ex. windowstransport), you wont need this.
//The AppPool identity will be used then.
trustChannelFactory.Credentials.UserName.UserName = #"domain\username";
trustChannelFactory.Credentials.UserName.Password = "password";
try
{
RequestSecurityToken rst = new RequestSecurityToken();
rst.RequestType = WSTrust13Constants.RequestTypes.Issue;
rst.AppliesTo = new EndpointAddress(ServiceAppliesTo);
//This part will give you identity of logged in user
rst.ActAs = new SecurityTokenElement(this.GetBootStrapToken());
var channel = trustChannelFactory.CreateChannel();
RequestSecurityTokenResponse rstr = null;
SecurityToken delegatedToken = channel.Issue(rst, out rstr);
return delegatedToken;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
try
{
if (trustChannelFactory.State == CommunicationState.Faulted)
{
trustChannelFactory.Abort();
}
else
{
trustChannelFactory.Close();
}
}
catch (Exception)
{ }
}
}
private SecurityToken GetBootStrapToken()
{
ClaimsPrincipal myClaimsPrincipal = System.Web.HttpContext.Current.User as ClaimsPrincipal;
SecurityToken bootstrapToken = myClaimsPrincipal.Identities[0].BootstrapToken;
if (bootstrapToken == null)
{
throw new Exception("bootstrap tokein is null. Logout and try again.");
}
return bootstrapToken;
}
That is all good and dandy, except you will not have proper claims on the back-end WCF service. Using this great article I was able to sort out the claim stuff in ADFS: http://technet.microsoft.com/en-us/library/adfs2-identity-delegation-step-by-step-guide.aspx . Scroll down to Enabling Identity Delegation and Fixing Claims Issuance Rules at CONTOSODC. I also removed claim encryption from Passively Federated Website.
After doing this I have same claims in the app service and the back-end WCF service.
I hope this helps someone in the same boat as I was.