I have a thick client application that has users that are in a different windows domain than my data portal server. Whenever they try to connect to the server from a different domain, I get this error:
System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
--- End of inner exception stack trace ---
How do I allow users in other domains to access the dataportal?
Do you have WCF configured to use Windows authentication and/or do you have ASP.NET set up to use Windows authentication/impersonation and/or do you have the IIS virtual root set up to deny anonymous users?
One of those configuration items is set to require that the client provide valid Windows (AD) credentials to access the service - and of course the clients outside your domain can't provide those credentials.
I'm exteremly new to WCF and do not have much knowledge in AD authentication and impersonation.
I was orignally using wsHttpBinding for WCF. This worked fine when I was in the same domain, but my company has an office in India that is in a different domain. I had to switch to basicHttpBinding for them to be able to connect, but (correct me if I'm wrong) the messages are no longer encoded and anyone on the network could capture a message and edit it along the way.
When starting the app they are prompted with a customer Id, user Id, and Password that is used to authenticate against an LDAP server. (Because the user needs to be able to login to different customers, I was having issues configuring the service to use username creditionals because the UserNamePasswordValidator Validate function only allows a username and password) So I'm using custom Authentication once I get to the Data Portal, but I'm unable to get there using wsHttpBinding.
From Reading the CSLA 3.0 PDF, I was thinking that I was going to have to create an X.509 certificate and place it on the server and use that in my behavior configuration but I had a few concerns.
1. This is a 100% internal app. Do I need to get this through VeriSign?
2. If I can create one, can I create it on any computer and transfer it up to the server and set it up to be trusted on the server?
3. Is there anything that is required on the thick client side of things besides updating the configuration file's behavior service credentials?
4. Will using a certificate resolve my issue with being in different domains?
Any help you can give will be much appreciated.
After the Data Portal, the user credentials are authenticated against an Oracle LDAP server. The credentials used to access the LDAP server are stored on the Data Portal Server.
I don't know what the network configuration that allows them to access the server, but I do know they can ping the server just fine.
OK, it sounds to me like you are using custom authentication
within CSLA itself. And you are merely using WCF as a network transport between
client and server – not for integrated authentication within WCF itself.
So you have two issues.
1.
You need to authenticate the user – which you already do
via LDAP and your custom Identity object, and it sounds like that works fine –
so I think this is a non-issue.
2.
You need WCF to establish a connection between client and
server, and it sounds like you want that connection secure/encrypted –
this is a separate issue from authentication.
To address the second issue, you need to dig into WCF security configuration
options. You DON’T need WCF to authenticate for you, but you do need it
to be secure in a cross-domain scenario.
I am not enough of an expert on WCF security to directly help you…
I know the Patterns and Practices group at Microsoft is working on something in
this area, and I thought they were releasing a beta on CodePlex earlier this
week if you can find it.
Ultimately you’ll need to decide on transport or message
security. Either way you need an x509 certificate on the server, trusted by the
client (typically through a chain of trust to a trusted root cert). In the
transport case the cert is usually part of an overall SSL/https channel. In the
message case it is a cert you supply in your config settings (look at Using
CSLA .NET 3.0 for an example of this one).
I do NOT think your data was encrypted just because you used the
wsHttpChannel. It is true that it defaults to message security, but without an
x509 key it can’t encrypt the data. Though I could be wrong, and perhaps
it somehow gets the key from some mystical place in the AD configuration? This
is the point at which my knowledge runs out…
Rocky
Yes Rocky, you've perfectly described my situation.
So it sounds like I have 2 options, tranport security (which is transporting on a secure channgel) or message security (which is encrypting the message and sending it on an unsecure channel). I was planning on using your example in CSLA .net 3.0 to create a x509 cert and try to use message security, I just wanted to make sure that there was no manual steps that would be required for users in a different domain to connect to the data portal.
It sounds like as long as I setup a chain of trust to a trusted root cert, this shouldn't be a problem. Does anyone else have any more information? If I go through the steps required, I'd like to make sure it will work across domains.
The trusted root cert thing will be your challenge – you need
to buy a cert from Verisign or RapidSSL or someone – or set up a certificate
authority server, issue yourself a root cert and get everyone to install it as
a trusted root cert.
For TESTING you can use the makecert.exe utility I use in the
ebook, but for production you need a real cert.
Rocky
Thanks for all your help and suggestions Paul and Rocky.
I appreciate it.
I know this thread is little outdated, but it seems I am having similar problem with a WCF service called by .NET application from another domain. As long as the client is in the same domain the WCF service is there are no exceptions during login, otherwise I receive this error:
“The caller was not autheticated by the service”.
The tracelog from the WCF service returns this values :
"The Security Support Provider Interface (SSPI) negotiation failed."
Here is the app.config (client side):
<appSettings>
<add key="CslaDataPortalUrl" value="http://SERVER_IP/WCFService/WcfPortal.svc"/>
<add key="CslaDataPortalProxy" value="Csla.DataPortalClient.WcfProxy, Csla"/>
<!--<add key="CslaAuthentication" value="Windows"/>-->
<add key="ClientSettingsProvider.ServiceUri" value=""/>
<add key="Culture" value="sl-SI"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_IWcfPortal"
maxReceivedMessageSize="2147483647">
<readerQuotas
maxBytesPerRead="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647"
maxDepth="2147483647"/>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://SERVER_IP/WCFService/WcfPortal.svc"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding_IWcfPortal"
contract="Csla.Server.Hosts.IWcfPortal" />
</client>
</system.serviceModel>
Here is the web.config (server side):
<configuration>
<appSettings>
<!--<add key="CslaAuthentication" value="Windows" />-->
<add key="CslaWriter" value="Csla.Serialization.Mobile.CslaBinaryWriter, Csla" />
<add key="CslaReader" value="Csla.Serialization.Mobile.CslaBinaryReader, Csla" />
<add key="Culture" value="sl-SI" />
</appSettings>
<system.serviceModel>
<services>
<service name="Csla.Server.Hosts.WcfPortal" behaviorConfiguration="WcfPortalBehavior">
<endpoint contract="Csla.Server.Hosts.IWcfPortal" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_IWcfPortal"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_IWcfPortal" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" receiveTimeout="00:25:00" sendTimeout="00:25:00">
<readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647"/>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfPortalBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<httpRuntime maxRequestLength="2147483647" />
<compilation targetFramework="4.0" />
<pages controlRenderingCompatibilityVersion="4.0" />
<trust level="Full" />
</system.web>
My IIS is configured the way you have suggested.
Is there any chance I can use this service without having to apply certification authentication on the server and client side?
Copyright (c) Marimer LLC