We are using basicHttpRelayBinding for WCF service which is exposed via Azure Service bus Relay.
We need to apply the security for this service so that end points are secured. Could someone please confirm whether all we need to do is below?
<security mode="Transport" relayClientAuthenticationType="RelayAccessToken" />
....
<tokenProvider>
<sharedAccessSignature keyName="WebServiceCaller" key="XXX" />
</tokenProvider>
I've seen few example of on net using below and with token expiry etc. on client side code:
TokenFactory tf = new TokenFactory(
string.Format("{0}-sb", serviceNamespace),
issuerName,
issuerKey);
Just want to confirm the we are not missing anything that has security impact.
That is correct configuration.
Most common use is TokenProvider.CreateSharedAccessSignatureTokenProvider if you need to add it to your endpoint.
Related
We need to create a WCF service (.NET 4.0) that will be consumed by a client outside of our organization.
The case is that we have two servers that are behind a load balancer which terminates the SSL. This is where it gets confusing for me.
How we could and should handle the authentication?
The previous experience about WCF is only about services for internal use. If I understood correctly we should use basicHttpBinding to guarantee interoperability with Java based client. I don't know if this is an issue with JAX-WS based client.
There will only be this one client that is going to use the service.
We need to somehow ensure that caller is authenticated to use the
system
Make sure the message is encrypted when moving in public network
So far the best article that I found was
http://devproconnections.com/net-framework/wcf-and-ssl-processing-load-balancers
There were few suggestions how to do this.
WCF services can be configured for basic authentication and receive credentials in the clear over HTTP. This can work; however, it precludes passing credentials in the message, and the use of more interesting credentials (such as issued tokens).
We use forms authentication on our website under which the service will be hosted. I think it is not easy or even possible to make the service then use basic authentication.
WCF services can be configured to fake the presence of transport security so that the runtime will allow receiving message credentials without transport or message protection
Will this be the way to go and will this work with basicHttpBinding?
The client and server binding will be different. The client binding will use username auth in eitehr message or transport level with transport security (ssl):
<bindings>
<basicHttpBinding>
<binding name="NewBinding0">
<security mode="Message" />
</binding>
</basicHttpBinding>
</bindings>
then the server config will use the same config but without the transport security. If you chose to use message security then check out WCF ClearUsernameBinding. If you use trasnport security (basic http) then set mode="TransportCredentialOnly".
I'm currently designing and developing a WCF 4 RESTful service that will be used by mobile devices. I specifically picked REST because it's supposedly lightweight and the JSON output makes parsing simple for the mobile clients.
The service takes care of the mobile devices part of the entire application. But, it requires that users log in before using the service. Basic HTTP authentication is not an option: It's insecure and a man-in-the-middle attack could easily intercept the user accounts. SSL is an option here, but I have no idea how easily SSL works on a WCF RESTful service and how simple it is to implement on mobile devices.
I've looked into Digest Authentication, but I can't really find any good information on how to implement it. And that also brings up: How am I going to allow users to add a device to their account with this? Hash the username/password combination into the Digest header along with other information?
Could someone shed some light on this? Because I'm confused as hell. There is plenty of information on the net on how to implement WCF (RESTful) services, but the moment you need to secure it, the amount of information drops significantly... Articles are welcome.
Leveraging SSL is brain dead simple in WCF and should be supported by every mobile platform at this point. You should defintiely go basic auth with SSL to keep your life as simple as possible IMHO.
All you need to do to enable HTTPS on your WCF service is:
<webHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</webHttpBinding>
That will say "only allow access to this service over a secure transport and expect a basic auth credential to be passed".
Now, the only question is, where are you hosting your WCF service? If hosting in IIS you need simply need to configure the service certificate with it and you're all set.
Another option is to do SSL up front with an F5 device or something like that. Then you have to do a little more work because, by default, WCF will not let you pass crendentials over a non-secured transport. Then you need to get into customizing your own binding and setting the AllowInsecureTransport = true on the TransportSecurityBindingElement. This will basically say "trust me, I'm doing the right thing" to WCF and allow the service to initialize propertly even though the credential will flow over a non-secure binding.
I have deployed wcf services in machineA and tried to accessed it through wcftestclient which is another system machineB. But i am getting error "The caller is not authenticated by wcf service". This wcf services is working fine when i testing it in machineA itself.
I have used wsHttpBinding.
How to solve this? Please help me.
on Machine A remove security if that service is only exposed in intranet.
Add binding configuration as follows
<binding name="none">
<security mode="None" />
</binding>
and In service add
bindingConfiguration="none"
If you don't want any security then only.
On machine B you'll have to supply some credentials that have access to the service on A.
See this article: Debugging Windows Authentication Errors for details, especially the section Client Credentials Are Not Set Correctly at the bottom of that document.
I have wcf service using net.msmq protocol but service fails to activate with following error. What could be wrong?
Looks like it is trying to find machineid or something in AD but why?
Sevice name is like net.msmq://localhost/private/myservice.svc
A connection with Active Directory cannot be established. Verify that there are sufficient permissions to perform this operation.
System.Messaging.MessageQueue.GetMachineId(String machineName)
System.Messaging.MessageQueueCriteria.set_MachineName(String value)
System.Messaging.MessageQueue.GetPublicQueuesByMachine(String machineName)
System.ServiceModel.Channels.MsmqBindingMonitor.OnTimer(Object state)
What security settings to you have? By default, the MSMQ binding will expect users to present a certificate to authenticate them and needs access to AD to verify that certificate.
If you want to totally turn off all security, add this snippet to your config:
<bindings>
<netMsmqBinding>
<binding name="NoSecurity">
<security mode="off" />
</binding>
</netMsmqBinding>
</bindings>
<endpoint name="...." address="..." contract="....."
binding="netMsmqBinding" bindingConfiguration="NoSecurity" />
That way, you should be able to call MSMQ without access to AD.
Marc
Maybe it needs to check with AD to be able to write to the message queue.
If you are running under a local account that does not have access to AD you may get this error.
I've had this error when my WCF service is hosted by a Windows Service that is running as the LocalSystem or NetworkService account. Changing the Windows Service to run under an interactive login account, like my own account or one I create just to host MSMQ-WCF Windows Services, eliminates this problem.
I believe the error is not related to WCF, but rather the service not having an interactive login that can auto-retrieve an AD certificate that will allow the WCF code to communicate with MSMQ.
I've got a WCF service that will need to receive client credentials, and maintain some kind of role-based data, based on my auth method.
The clients will reside on many different systems, and as such, each client will have a unique userID and pw.
I'm using basicHttpBinding and have read a few articles, such as this one,
http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/, that describe the process.
So what I'm looking for is if someone has a full client/server configured like this to take a look at so I can derive my own solution from this.
What I'd like to do is have the username and password passed in the headers for each request, passing back some kind of SecurityTokenValidationException on fail, or continuing if passing.
Thanks.
UPDATE
I'm using the wsHttpbinding with the following config on both the client and server:
<wsHttpBinding>
<binding name="wsHttpEndpointBinding" >
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
And the call out to the server from the client as follows:
ServiceReference1.ServiceClient myClient = new ServiceReference1.ServiceClient();
myClient.ClientCredentials.UserName.UserName = "billuser";
myClient.ClientCredentials.UserName.Password = "mypassword";
Response.Write("Data from WCF Service: " + myClient.GetData(1));
I think I need a bit of a hand with linking up the CustomUsernamePasswordValidator on the server as I'm still getting the '...could not be activated.' error.
Are you required to use the basicHttpBinding? That binding is really only there to provide support for legacy WS-BasicProfile implementations (i.e. ASMX). If your clients are also .NET/WCF, I would highly recommend using wsHttpBinding, which provides a plethora of security options out of the box. You could use certificates, username/password, etc. with transport and/or message security and not need to write any of the security stuff yourself. Just configure-and-go (CAG).
Security credential information is available to the service itself via the OperationContext, in case you need to access it directly from your code. If your code does need to access it, however, I would recommend writing a behavior to extract the pertinent information from the OperationContext and place it in something more application specific so that you don't have to reference System.ServiceModel everywhere you need to access information on OperationContext.