Architecture advice needed for WCF services - wcf

I'm currently working on a backend infrastructure and I could need some advice.
First, here is the current global architecture:
I have WCF services hosted in IIS
I have multiples databases hosted on SQL Server. One ClientData database per client and one global MasterDatabase.
MasterDatabase contains a mapping of credentials associated to a connection string. That database allows me to use the appropriate ClientData database (via Entity Framework) depending on the credentials provided.
I'm using Basic Auth over SSL.
Credentials verification are done in overridden method checkAccessCore() in my ServiceAuthorizationManager subclass. Inside that method, I fetch MasterDatabase, ensure credentials are correct (password are saved in DB using Bcrypt) and retrieve the connection string.
Once the connection string is retrieved, I create an instance of my class CustomIdentity that inherits from GenericIdentity. Using that instance I can then set the Thread.CurrentPrincipal property.
Each WCF service implementation retrieves the connection string from the CustomPrincipal in order to fetch data from the appropriate ClientData database.
My questions/thoughts are the following:
If I decide to use concurrency in my WCF services, how will I handle that due to the fact that CheckAccessCore is a method of a WCF extension that force concurrent operations to run sequentially?
http://support.microsoft.com/kb/KbView/2907010
This means that all my call will be enqueued and blocked at the checkAccessCore level.
Overriding checkAccessCore is the best way I found to intercept calls early in the call stack in order to verify user credentials.
Should I use a different way to transport the client connection string other than over the custom identity? Is it secure?
If I use concurrency, I guess the identity set into the CustomPrincipal will be overridden. If yes, how to handle that?

Related

How WCF client access nested object methods

My WCF Service has API to create 'Employee' object which needs to be send to client app. This object has set of methods and properties. Now, client need to access Methods in order to set it's fields (API has few validation logics to set it's fields). How WCF service will send an custom object where client must be able to access methods.
Here the design is, my wcf service will provide a 'template' (from api) to client where in client uses this object methods to set/update fields and will send back to service.
If the objects you send and receive have logic associated to them (not a very good idea), you will need the assembly where those objects are impemented on both sides, since the metadata exposed by wcf only shows fields, and not methods.
I'd split that in two, keep the datacontracts clean and if you need validation logic, you can either do it in the wcf service and return errors to the client, or in the client, but that will extra logic to the client that you'll need to provide.
I'd go with validation logic in the server, and clean datacotracts. It's the best way to ensure your services are interoperable.
Its not a good idea to return any objects from wcf service which contains any functions. Keep the data contract simple by having only fields (properties) , if any additional operation is needed make this available as part of operation contract.

WCF Authenticate Client with database

I have a WCF service that supposed to provide service to several clients.
The WCF will have a Data-Access-Layer that will communicate with the database.
This is part of my design idea : My Design
As you can see - each client will connect to the 1st WCF service for pulling information (get product, update product), and also to the 2nd WCF service in a pub\sub manner, so it would be able to receive notifications about different things it wants.
I have a table in the database for 'Users' with all the users in the system.
(there is an administrator, a normal user and a technician).
My question is - how do I do the 'logging' in from the client to the database ?
My current idea - have a function in the services called 'Connect ( username, password )' and when a client connects - it will pass the username and password to be authenticated in the database, and only if authenticated - the client will start sending commands.
Problem with this is - anyone can write his own client that connects to my service and runs other functions without authenticating. I can solve this by saving in the service whether or not the client has authenticated.
But is there a better solution that just having a 'Connect' function in the service ?
Hope there is something simple yet effective.
You should create a custom user name and password validator that derives from the UserNamePasswordValidator abstract class and implements the Validate() method. Then you can validate the provided user name and password however you want. To learn more about setting this up, read this article.

How can I get Entity Framework and WCF to work with transactions? Okay...what's the secret?

I've been trying several different ways in order to get a simple set of transactions to work for a simple WCF client/server situation. My WCF server has a class level declaration of the Entity Framework class for my database access and several methods to modify data and a method to SaveChanges. I'm using the Oracle Data Access (ODP.NET).
For instance I want to call a modification from the client and then a separate call to save the changes in the WCF service. It doesn't work. Basically, everything executes fine, but when the second call to save the changes is made, the WCF service no longer has the original context and therefore no changes are saved (and, consequently, the previous call that made the changes was automatically rolled back).
I'm utilizing Transaction scope around both operations in my client and executing Complete() after done. My WCF services have OperationContract's that use [TransactionFlow(TransactionFlowOption.Mandatory)] and those method implementations use [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]. Finally, my web config is configured with a wsHttpBinding that has the transactionFlow property set to True.
I'm having no luck. No matter what I try, when I try hitting the service for the follow-up save, the EF context is already renewed.
This has nothing to do with transaction. Transaction works on transactional resource but without calling SaveChanges in the first request there was no transactional resource active because EF context is not part of the transaction - the database is and the database is affected only when you call SaveChanges. To make this work you don't need distributed transactions. You need session-full service and store the EF context in the service instance. It a client uses the same client proxy instance to communicate with the service for all requests the communication will be handled by the same service instance = same EF context instance which will remember changes from previous calls.
IMHO this is very bad architecture. Simply don't use it. Expose specialized methods on WCF service which will do changes and save them. If you need to execute these methods in transaction with other transactional resources use the real distributed transaction.
this might be a reason. Since your are making an update in the different context. context doesn't know that the object is update to have say the context that the object is modified and then you call savechnages(). See if it helps

Custom Authentication with WCF and NHibernate

I'm attaching an NHibernate session to the operation context in my WCF webservice which allows me to access the session object during the processing of each operation (the service instance context is per call).
The service implements custom authentication using UserNamePasswordValidator but unfortunately prior to the request being authenticated the OperationContext.Current is always null (presumably by design).
My question is how should I set up the NHibernate session on the Validate(string userName, string password) method if I can't get the session via the OperationContext.Current? How are other peeps doing this?
Thanks in advance.
Use separate session in validator = create new one through session factory. There is no shared storage between security processing and operation processing by design. They should even run in different threads. You should follow this design and don't share session and loaded objects between security processing and operation processing.

Detect when client connected to wcf service

From a little bit of reading around, it is my understanding that the only way to detect that a client has connected to my service is through writing my own code. I am using a Singleton service. I would like to display a message every time a client connects to my service that client x with ip xxx has connected. There is no built-in event that is generated? Am I correct?
No, I don't think there's any support in WCF for your requirement.
Not sure what you want to achieve with this, either. Your service class (in your case, just a single instance) really doesn't have any business putting up messages (on screen, I presume) - that really not it's job. The service class is used to handle a request and deliver a response - nothing more.
The ServiceHost class might be more of a candidate for this feature - but again, it's job really is to host the service, spin up the WCF runtime etc. - and it's really not a UI component, either.
What you could possibly do is this
have an Admin UI (a Winforms, console, or WPF app) running on your server alongside your service, providing an admin service to call
define a fast connection between the two services (using e.g. netNamedPipe binding which is perfect for intra-application messaging)
when your "real" service gets a call, the first thing it does is send out a message to the admin UI which can then pick up that message and handle it
That way, you could cleanly separate your real service and it's job (to provide that service) and the Admin UI stuff you want to do and build a cleanly separated system.
I have actually implemented my own connect, disconnect and ping service methods which I manually call from my client once the channel has been created. By using them as a kind of header section in all of my ServiceContract interface definitions (and their implementations, of course), they form an makeshift "base service definition" that only requires a bit of cut-n-paste.
The string-based parameters of connect and disconnect will be used to send client info to the server and return server info and (perhaps a unique connection id) to the client. In addition a set of timing reference points may make its way in also.
Note how SessionMode is required and the individual OperationContract properties IsInitiating and IsTerminating are explicitly specified for each method, the end result being what I would call a "single-session" service in that it defines connect and disconnect as the sole session bookends.
Note also that the ping command will be used as the target of a timer-based "heartbeat" call that tests the service connection state and defeats ALL connection timeouts without a single config file :-)
Note also that I haven't determined my fault-handling structure yet which may very well add a method or more and/or require other kinds of changes.
[ServiceContract( SessionMode = SessionMode.Required )]
public interface IRePropDalSvr {
[OperationContract( IsInitiating=true, IsTerminating=false )]
string connect (string pClientInfo);
[OperationContract( IsInitiating=false, IsTerminating=true, IsOneWay=true )]
void disconnect (string pClientInfo);
// ------------------------------------------------------------------------------------------
[OperationContract( IsInitiating=false, IsTerminating=false )]
string ping (string pInp);
// ------------------------------------------------------------------------------------------
// REST OF ServiceContract DEFINITION GOES HERE
One caveat: while I am currently using this code and its implemention in my service classes, I have not verified the code yet.