How to get information about WCF service client from operation implementation? - wcf

I especially need to get client's certificate used to call service's method. This is to react differently for different clients.

In your operation code, you can examine things like:
OperationContext.Current
or
ServiceSecurityContext.Current
but I'm not sure if you can access the actual client certificate from those.
The ServiceSecurityContext.Current.PrimaryIdentity will contain an IIdentity for the current caller - if it's NULL, then you're dealing with an anonymous call. Otherwise, the PrimaryIdentity will be one of several possible identity types, depending on how the calling user was authenticated - it could be a Windows identity, or something else - depending on your scenario.
See this blog post for a few more tidbits of information on X.509 and WCF.

Related

SecurityContext.Current not working, nullexception

im using a WCF service with the users and roles being kept in the database. In my service im trying to identify whose calling the service. So i type in my WCF service
string user = ServiceSecurityContext.Current.PrimaryIdentity.Name;
but i get i nullexception object not sent to an reference, ive tried googleing it all day but cant seem to find whats wrong. Any suggestions ?
"What's wrong" is that ServiceSecurityContext.Current is returning null rather than an instance of ServiceSecurityContext.
One scenario where this occurs is if the binding is configured to use Message security with MessageCredentialType set to None.
However, I'm not aware of any comprehensive documentation listing every scenario where ServiceSecurityContext.Current can be null: as the security context is established in the channel stack it is something which depends on the specific binding configuration and security providers in use. It could also, I imagine, be affected by custom Behaviors which fiddle with message properties.
Having said that, unless you have custom code inserted into the channel stack, it is probably a safe assumption that this will only occur in cases where the binding does not require any client authentication. You should check first of all that you are using a binding configuration which will auhenticate the client and provide the kind of user name IIdentity you are expecting.

Restrict methods of a WCF service from unauthorized (unwanted) user access

I'm wondering how I can restrict some methods from unauthorized user access. Let's assume I have a WCF service with the following contract:
int Login(string username, string password);
Invoice[] GetCustomersInvoices(int customerId);
A user should act in the following way:
Login to verify against the service and get his custumerId
fetch his invoices by invoking the corresponding method with his customerId
Well, that's maybe a stupid question, but what if customerA's id is 23, but somehow customerA knows customerB's id, which is 42. Now customerA could read customerB's secret invoice data...
What could I best do to avoid this?
You shouldn't use a single id for identifying someone. There are many ways of enabling authn/authz in WCF, I like the article at http://msdn.microsoft.com/en-us/magazine/cc948343.aspx for a good introduction on some ways of doing it.
Your current approach of calling methods will only work if you are able to implement secure(persistent) channel between client and server using SSL or any other such mode (typical scenario would be Baking Payments Getaways)
So IMO you need to implement your user authentication inside the method (no separate calls). i.e. you have to pass userid and password along with invoiceid to GetCustomersInvoices() method and inside it you need to authenticate the user and retrieve the data.
Following would be solution for such scenario,
Implement your own User Name Password Validations (custom usernameathentication), which will first authenticate the user and than it will call the method given. Since this will happen in one request so it will solve your problem.
Typical service method call would be like,
Service.UserName = "abc"
Service.Password = "***"
Service.GetInvoiceDetails(1233)
You can get the use of Message Headers and Body to pass your custom values, Webservices support such scenario where you can pass encrypted data in SOAP headers.
Alternatively you can use Certificates also, but these are not free.
In general you can go through following links to get more info in various kinds of security WCF supports,
http://msdn.microsoft.com/en-us/library/ms731925.aspx

MVVM on top of claims aware web services

I'm looking for some input for a challenge that I'm currently facing.
I have built a custom WIF STS which I use to identify users who want to call some WCF services that my system offers. The WCF services use a custom authorization manager that determines whether or not the caller has the required claims to invoke a given service.
Now, I'm building a WPF app. on top of those WCF services. I'm using the MVVM pattern, such that the View Model invokes the protected WCF services (which implement the Model). The challenge that I'm facing is that I do not know whether or not the current user can succesfully invoke the web service methods without actually invoking them. Basically, what I want to achieve is to enable/disable certain parts of the UI based on the ability to succesfully invoke a method.
The best solution that I have come up with thus far is to create a service, which based on the same business logic as the custom authorization policy manager will be able to determine whether or not a user can invoke a given method. Now, the method would have to passed to this service as a string, or actually two strings, ServiceAddress and Method (Action), and based on that input, the service would be able to determine if the current user has the required claims to access the method. Obviously, for this to work, this service would itself have to require a issued token from the same STS, and with the same claims, in order to do its job.
Have any of you done something similar in the past, or do you have any good ideas on how to do this?
Thanks in advance,
Klaus
This depends a bit on what claims you're requiring in your services.
If your services require the same set of claims, I would recommend making a service that does nothing but checks the claims, and call that in advance. This would let you "pre-authorize" the user, in turn enabling/disabling the appropriate portions of the UI. When it comes time to call your actual services, the user can just call them at will, and you've already checked that it's safe.
If the services all require different sets of claims, and there is no easy way to verify that they will work in advance, I would just let the user call them, and handle this via normal exception handling. This is going to make life a bit trickier, though, since you'll have to let the user try (and fail) then disable.
Otherwise, you can do something like what you suggested - put in some form of catalog you can query for a specific user. In addition to just passing a address/method, it might be nicer to allow you to just pass an address, and retrieve the entire set of allowed (or disallowed, whichever is smaller) methods. This way you could reduce the round trips just for authentication.
An approach that I have taken is a class that does the inspection of a ClaimSet to guard the methods behind the service. I use attributes to decorate the methods with type, resource and right property values. Then the inspection class has a Demand method that throws an exception if the caller's ClaimSet does not contain a Claim with those property values. So before any method code executes, the claim inspection demand is called first. If the method is still executing after the demand, then the caller is good. There is also a bool function in the inspection class to answer the same question (does the caller have the appropriate claims) without throwing an exception.
I then package the inspection class so that it is deployed with clients and, as long as the client can also get the caller's ClaimSet (which I provide via a GetClaimSet method on the service) then it has everything it needs to make the same evaluations that the domain model is doing. I then use the bool method of the claim inspection class in the CanExecute method of ICommand properties in my view models to enable/disable controls and basically keep the user from getting authorization exceptions by not letting them do things that they don't have the claims for.
As far as how the client knows what claims are required for what methods, I guess I leave that up to the client developer to just know. In general on my projects this isn't a big problem because the methods have been very classic crud. So if the method is to add an Apple, then the claim required is intuitively going to be Type = Apple, Right = Add.
Not sure if this helps your situation but it has worked pretty well on some projects I have done.

WCF services: passing a token to validate a subscription and get database info

I'm creating a smart client application using .NET 3.5. A Winforms client connecting through WCF services to retrieve data from SQL Server 2008. I need to pass a username/password (encrypted and over HTTPS) and return information such as:
Is this user (e-mail address) under a current subscription
What server should we go to next for all subsequent calls (poor man's load balancing)
What server/database should be used in the connection string (credentials not required), as people could be using different databases depending on their subscription, etc.
So my first call when signing on sends the credentials which a lookup is performed. A serializable class will be used to create a token object (I assume this is the way to handle this) which will return the expiration, server info, database info.
The question is on all subsequent calls do I pass this token as a parameter to every service contract (web method) or can I leave all my current contracts as is and pass the token in a header or some other more universal method?
How do you suggest implementing a token system such as I describe?
Thank you
For one, I would only return a TokenID - some unique ID to clearly identify the user and his subscription in question - from your first "authentication" call. No need to send back and forth the whole set of information all the time - only the service on the server side needs those details, so you can leave that info on the server and only consult it in your server code when needed.
So that first call - the authentication call - would most likely check the credentials being sent against a database table, against a subscription table, and then put that information (who's calling in, based on what subscription) and possibly some kind of an expiration date/time into a "Valid Callers" table and generate an ID from that (a GUID or something). You might want limit the "lifespan" of a TokenID - e.g. it's valid for 30 minutes or so - so that it can't be hijacked and used perpetually after a first successful call. That generated GUID is then returned as the TokenID from the Authentication call and can be used as an identifier in each subsequent call.
Things like what database server to use have really no place in messages going back and forth - they're strictly important to the server-side service code - just leave it there!
It is definitely preferred practice to put such "meta information" that isn't the real value information for your calls into headers and go search for it there. WCF supports this quite nicely and easily - with either message inspectors (sample for that here and here) on client and service side, or by using the OperationContextScope (sample blog post here and here) - both work just fine.

Passing the original caller in WCF

We currently have a setup like this:
lan\john lan\application1 lan\appService1 lan\appService2
client ------> website ----------> WCF Service1 ------> WCF Service2
So each website/service runs as a different identity account that is setup in active directory. Security checks are based on the identity of the immediate caller (i.e. WCF Service2 would verify that its caller lan\appService1 has the rights to perform that task).
For logging purposes though we need to know who the original caller was (in this example lan\john) so that we can record they did an action. I would like a way to do this in a more secure fashion than is currently being done (passing the string of "lan\john" as a message header with each call). Any ideas?
If its just matter of checking the security of WCF service caller you can checkout the mechanism suggested by msdn here.
For the entire application if you want to enable the identity impersonation at this stages, you can explore the design pattern explained on msdn.