WCF / WIF - Should I find claims in the backend? - wcf

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).

Related

WCF Service not accepting multiple body parameters

I have OpenRIA WCF Service hosted within an asp.net website. I have a WPF client that connects to the Authentiction and DomainService. I am having trouble calling the Login method. It basically does not like that the message parameters are not "Wrapped". See the error message below
An unhandled exception of type 'System.InvalidOperationException' occurred in OpenRiaServices.DomainServices.Client.dll Additional information: Operation 'Login' of contract 'IPatientAuthenticationDomainServiceContract' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped. On the client side, The WebHttpBehavior in domainClient.ChannelFactory.Endpoint.EndpointBehaviors has DefaultBodyStyle = Wrapped
The asp.net project that's hosting the OpenRIA services has web behavior set to Wrapped.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp defaultBodyStyle="Wrapped"/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
What could I be missing? Has anyone encountered this issue?
A possible workaround is to change the method parameters to accept a complex type but I do not have control over the Login method of the AuthenticationService. It is part of a base class that RIA framework provides.
Thanks,
Ankur
Issue resolved. Just wanted to share the fix. I am using SharedCookieContainer that Kyle McClellan wrote for sharing cookie between Auth service and Domain service when not using an in-browser client. See http://blogs.msdn.com/b/kylemc/archive/2010/05/14/ria-services-authentication-out-of-browser.aspx
The SharedCookieBehavior in this code is an extension of WebHttpBehavior. This class needs to have the DefaultBodyStyle set to Wrapped when its newed up. Simple fix but took me a while to figure out.
Thanks,
Ankur

Client config of WCF REST service is not being updated

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.

Windows Serice Hosted WCF - Username Authentication

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>

WCF (SOAP):Protecting single operations with custom UserName validator - similar to what WcfRestContrib offers but for soap?

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.

How can I authenticate using client credentials in WCF just once?

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.