I've looked at the security guide at wcfsecurity.codeplex.com. The guide is fairly straightforward. However, I cannot find anything relating to a WCF service hosted in a Windows Service.
Without the support of IIS, ASP.net runtime and all its role, profile, etc providers, is it possible to still apply security to the WCF service??
Its absolutely possible to host in a windows service and secure the WCF service. For username authentication you can still use the RoleProvider model if that's what you want to do or you can write a custom userName validator
The WCF model is that all WCF features should be available independently of the hosting environment. The only time this changes if you opt into ASP.NET compatibility mode
Edit: added wiring in customer role provider config
To configure user names with a role provider use the following config
<serviceBehaviors>
<behavior>
<serviceCredentials>
<userNameAuthentication membershipProviderName="myCustomRoleProvider"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
Related
I have an ASP.NET application calling a WCF service.
In ASP.NET application, I make a call to ADFS to perform authentication and I can see all the claims of the user in CurrentPrincipal. Then I perform the call of the WCF service (wsHttpBinding), but the list of claims is empty.
What could be the reason?
If I'am not mistake there different ways to get Claims in WCF.
Thread.CurrentPrincipal - Simple and easy to used but need some setting in your configuration, which is most neglected.
<behaviors>
<serviceBehaviors>
<behavior name="Test.Services.WifBehavior">
<serviceCredentials useIdentityConfiguration="true" />
<!---Set principalPermissionMode to always to pass the ClaimsIdentity info to the Thread.CurrentPrincipal-->
<serviceAuthorization principalPermissionMode="Always"/>
</behavior>
<serviceBehaviors>
</behaviors>
OperationContext.Current.ClaimsPrincipal - I can't remember if this needs some configuration but I guess you can get it directly from method invoked.
OperationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets - Create a Custom Authorization Manager for a Service and need to add in config.
Note that I used Windows Identity Foundation (WIF).
I am using VS2012. My client configuration not updated when I have added service reference of WCF REST service. It is updating if I change binding to 'basicHttpBinding' in a WCF Service. Following is my WCF Service configuration.
<endpoint address="" binding="webHttpBinding" contract="MyService.IService1" behaviorConfiguration="RestBehavior">
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
My WCF service is split into following projects.
WCFHost(has only .svc file with web.config mentioned above and uses following two projs)
WCFInterfaces (Class library, has no config file)
WCFImplementaions (Class library, has no config files)
I wonder if I am doing anything wrong with decoupling of WCF layers above and hence my client app unable to get config details when Service reference added.
Visual Studio service reference does the magic because SOAP services provide WSDL. If you create a REST service, there is no WSDL and it will not work. The moment you switch to basic HTTP, it works because it is SOAP. You have to use HTTP libraries like HttpClient to talk to a REST endpoint.
The scenario is:
There is a WCF Web Service on a Windows 7 computer, with IIS7. For IIS7 with Windows 7 only 10 connection can be made (as I found out from the Internet).
This WCF Web Service has a cached service client connection to another WCF Web Service.
Is that one cached service client one of the 10 connections (limited by IIS7)? Or each method call throught that cached connection will be one of the 10 connections?
Note: Thought I have accepted my answer, I am interested on better answers and if they really address the general context of the question (because it's more of a theoretical one) I am going to mark them as a answer (instead of mine).
If your application is built on .Net Framework 3.5 (not .Net Framework 4.0), then I guess that the limit you're hitting is <serviceThrottling> limit which has following default value,
maxConcurrentSessions - 10
MaxConcurrentCalls - 16
maxConcurrentInstances - 16
So, if your binding configuration has Security or Reliable sessions ON and there are 10 concurrent users (users = Service proxy instance in open state) than maxConcurrentSessions limit is reached and requests to create new session (new Service proxy Open) will be queued, until old proxy connections are closed. You can try adding following configuration in both Front-end WCF service and Backend WCF service, and check if it helps.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceMetadata httpGetEnabled="True"/>
<!-- Specify throttling behavior -->
<serviceThrottling maxConcurrentCalls="30"
maxConcurrentSessions="30" />
maxConcurrentInstances="30" />
</behavior>
</serviceBehaviors>
</behaviors>
After some documentation and tests, as no good answer was provided, I managed to found out this:
The 10 connection limit is for HTTP requests.
Each method call from another WCF service needs 2 HTTP requests (this is the way WCF services communicate). May be different thought if the settings of the binding and authentication differs.
I didn't find any information that caching the web service client may help.
The other HTTP requests (more than 10) aren't refused, they are actually cached in IIS.
So the short answer would be a method call is one of the 2 out of 10 HTTP requests.
Some links:
http://www.jpelectron.com/sample/WWW%20and%20HTML/IIS-%20OS%20Version%20Limits.htm
https://www.owasp.org/index.php/Authentication_In_IIS
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/fe1772c8-9ae3-4f6b-b05f-d9eeb683b623/
Note: Thought I have accepted my answer, I am interested in more information and a better answer to this question.
I was hoping to be able to protect my WCF services on an operation level not service level.
Hence some methods are protected and others not. I know there is an attribute called PrincipalPermission but this works with Windows
I was hoping something existed for WCF Soap like it does for WCF Rest in this contrib project. WcfRestContrib
This extra project allows the use of a custom username and password validator and allow it only to protect certain methods by decorating the methods with an attribute
Is this possible with WCF (soap)?
Thanks in advance
Yes, it is possible to do operation level authorization checks with SOAP in WCF, but you'll need to do claims based authorization (as far as I know). That's what my team does for our product.
The hook point in WCF is to implement a custom ServiceAuthorizationManger
ServiceAuthorizationManager.CheckAccessCore Method
How to: Create a Custom Authorization Manager for a Service
and plug that into your service behaviour:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceAuthorization serviceAuthorizationManagerType="MyServiceAuthorizationManager" />
</behavior>
</serviceBehaviors>
When you implement your authorization manager, override CheckAccessCore, and then simply return true/false is they are authorized or not.
What is the best approach to make sure you only need to authenticate once when using an API built on WCF?
My current bindings and behaviors are listed below
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<security mode="TransportWithMessageCredential">
<transport/>
<message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="NorthwindBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Next is what I am using in my client app to authenticate (currently I must do this everytime I want to make a call into WCF)
Dim client As ProductServiceClient = New ProductServiceClient("wsHttpProductService")
client.ClientCredentials.UserName.UserName = "foo"
client.ClientCredentials.UserName.Password = "bar"
Dim ProductList As List(Of Product) = client.GetProducts()
What I would like to do is auth w/ the API once using these credentials, then get some type of token for the period of time my client application is using the web service project. I thought establishsecuritycontext=true did this for me?
If you're on an intranet, Windows authentication can be handled for "free" by configuration alone.
If this isn't appropriate, token services work just fine, but for some situations they may be just too much.
The application I'm working on needed bare-bones authentication. Our server and client run inside a (very secure) intranet, so we didn't care too much for the requirement to use an X.509 certificate to encrypt the communication, which is required if you're using username authentication.
So we added a custom behavior to the client that adds the username and (encrypted) password to the message headers, and another custom behavior on the server that verifies them.
All very simple, required no changes to the client side service access layer or the service contract implementation. And as it's all done by configuration, if and when we need to move to something a little stronger it'll be easy to migrate.
While I hate to give an answer I'm not 100% certain of, the lack of responses so far makes me think a potentially correct answer might be okay in this case.
As far as I'm aware there isn't the kind of session token mechanism you're looking for out-of-the-box with WCF which means you're going to have to do some heavy lifting to get things working in the way you want. I should make it clear there is a session mechanism in WCF but it's focused on guaranteeing message orders and is not the ideal tool for creating an authentication session.
I just finished working on a project where we implemented our own session mechanism to handle all manner of legacy SOAP stacks, but I believe the recommended way to implement authenticated sessions is to use a Secure Token Service (STS) like Pablo Cibraro's.
If you want more details please shout, but I suspect Pablo's blog will have more than enough info for you to steam ahead.