Custom Authentication and Security for Routing Service of WCF 4.0
I came across to WCF 4 routing features while designing some Central services which will provide various service to all of my client-end service. I like to create a single entry point to communicate all those service and keep them separate because of scalability reason. WCF routing feature seems to me very exciting which support for a configurable routing service that you can use in your WCF solutions. Provides features for content-based routing, protocol bridging, and error handling. But I have faced some issues there while defining their security context.
Now a days I am building such architecture where ‘Service L’ in customer domain end will provide some services to Client X, Y , Z and so on.. workstations. ‘Service L’ has lots of things to provide its clients (like data from databases etc… etc…).
And the interesting thing is that in some cases it will consume some services from the Provider End which have been distributed in several independent backend services like ‘Service A’, ‘Service B’. Since those services in Provider domain in not available outside, it has a routing service ‘Router service’ that gives all ‘Service L’ Clients to access the backend services and it act like a bridge to consume them. So all ‘Service L’ going to become as a client to Routing service who send request to it over the internet and it going to route them to appropriate backend service based on filter/policy.
The security between Service L and Client X/Y/ Z has already been established and I am not going to talk on that part so. I am very much concern about rest of part I have, the security in the routing environment.
This routing part has been developed based on WCF 4.0 routing feature. But I didn’t find any good solution for the security context when forwarding the messages to backend services.
What about Transport Security?!!
WCF routing is based on message level rather than transport layer routing. Therefore, authentication at transport layer cannot be forwarded correctly by the router and there
hasn’t a direct means to make those security assertion flows from client to
backend (bypass the Router Service). HTTPS/SSL like transport layer solution which can be used only for point to point rather than end to end case. So you cannot establish HTTPS/SSL connection across multiple nodes (client, router and server)
Here the routing service like Consumer –> Routing Service –> Backend Service, than I need to make sure that there is transport security enabled between
· Consumer -> Routing Service
· Routing Service -> Backend Service
According to that, the message will be encrypted on transport from the consumer to the routing service. When the message enters the routing service it will be decrypted, when sending the message to the backend service it will be encrypted again on transport and decrypted at the backend service. So the message will be encrypted and decrypted twice in such solution. But Since There is intermediary systems between client and the service; each intermediate point must forward the message over a new SSL connection.
So Transport security is not appropriate when
· you are sending a message directly from your application to a WCF service and the message will not be routed through intermediate systems
· Both the service and the client are located other than an intranet.
So I am going to avoid Transport security in my scenario.
What about Message Security?!!
Message security is transport-independent and therefore can be used with any transport protocol. When you use message based security this is done on the SOAP message (so the encryption takes place on service level instead of transport level) which gives an End-to-End security solution. So the consumer sends an encrypted message (header is not encrypted default) and the Routing Service just routes the encrypted message to the backend service and the backend service decrypts the message. . So message security directly encrypts and signs the message, having intermediaries does not break the security. But Message based security gives you a performance penalty in comparison to Transport Security, because the message becomes way larger after encrypting it.
So message security with Windows credentials in Router and backend service will work since support of delegation (Kerberos). And Client needs the access to that identity object. On the other hand, it doesn’t also allow me to forward security context for:
· Username and Password
· Federated credentials
It means that the router can be configured to enforce message security but the service must be configured to disable security and it cannot access the security context such as the user’s Identity.
So, What I am going to Do
- Add extension of endpoint behavior to add headers to send User name and password (Can be send in encrypted way too).
- Create a custom binding to encrypt and compression message in between Client and Routing Service.
- Use Regular security in binding while forwarding message to back-end service from Routing service.
- Create an authentication manager to do authentication by user name and password (against database) to avoid anonymous calls.