Silverlight authentication and ICredential - asp.net

I've setup up a WCF web service to handle requests from a Silverlight application. That service has Windows authentication set up which works well with the following endpoint configuration
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Test.Service.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="customBinding0">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="Test.Service.ServiceBehavior" name="Test.Service.Service">
<endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="Test.Service.Service"/>
<endpoint address="mex" binding="customBinding" bindingConfiguration="customBinding0" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
The service also has the following code in the constructor which authenticates to a TFS server
teamFoundationServer = TeamFoundationServerFactory.GetServer(tfsServer);
teamFoundationServer.EnsureAuthenticated();
workItemStore = (WorkItemStore)teamFoundationServer.GetService(typeof(WorkItemStore));
Then I have a Silverlight application that uses this web service and contains the following code to access it
proxy = new ServiceClient("Service");
Lastly there is a host web site that only contains the .xap silverlight file. That site has also Windows authentication configured.
Both the service and the host are running in IIS.
The problem I'm having is that when the service authenticates with TFS I always get an exception
Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException: TF30063: You are not authorized to access
Since the service and the host are windows authenticated then the Silverlight application is most likely causing me problems. After googling Silverlight and authentication it seems like there is some issue realated for Silverlight to forwarding the credential from the host to the service. Has someone been able to accomplish this task ?
To provide further info then I've been able to get the current users username by doing
OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.AuthenticationType
But that returns a WindowsIdentity which is not compatible with ICredential which the TFS API requires :(

Related

Using WCF Service on web host server

The possibility of this being a duplicate question is high.
The reason I'm querying it again, is that I have searched through tons of articles to no avail. I need some guidance, perhaps it may be specific to my application.
I've written a WCF Service, which works fine on the localhost.
Once the website is published to the live hosting server,
* I cannot access the WSDL - I obtain a 404 - File or directory not found.
* Should I try an add a service reference to the application, I get:
There was an error downloading 'http://freewaytoyota.co.za/FreewayToyotaService.svc/$metadata'.
The request failed with HTTP status 403: ModSecurity Action.
Metadata contains a reference that cannot be resolved: 'http://freewaytoyota.co.za/FreewayToyotaService.svc'.
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
The remote server returned an error: (403) Forbidden.
If the service is defined in the current solution, try building the solution and adding the service reference again.
My web.config is as follows:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFreewayToyotaService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8777/FreewayToyotaService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFreewayToyotaService"
contract="FreewayServiceReference.IFreewayToyotaService" name="BasicHttpBinding_IFreewayToyotaService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="1"/>
</system.serviceModel>
I have not made any changes. This is the original file.
How do I modify it to get the .svc working on the live web host server.
Please help :(. Thanks in advance.

WCF configuration and authentication nightmare

I am working with windows server 2008 r2 running iis 7.5. My WCF service is running on framework 4.0. 32-bit app running integrated pipeline.
Service is in a virtual directory with Annonymous and Windows Authentication enabled. My configuration looks like:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyWebservice.MyService" behaviorConfiguration="MyWebservice.MyServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="MyWebservice.IMyService" />
<endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyWebservice.MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I connect with the WCF Test Client from an account that is on the domain, I get the following exception:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate'.
This error is profoundly un-helpful. Can anyone point me to the error of my ways?
Reboot fixed the error. When will I ever learn, with Windows... when things stop making sense, reboot.

WCF: How to combine several services into single WSDL

In my ASP.NET WebForms project I have a reference to the WCF services library project, which contains different WCF services for each business object. The services are hosted in IIS and it's possible to get WSDL via routes I defined in the Global.asax: one WSDL via one route for each service.
What I really need - some ability to choose services what I want to provide for different customers and generate a SINGLE WSDL for the chosen services set.
Yes its possible to configure WCF routing service and get WSDL files form individual service behind it.
Step 1 - Set HttpGetEnabled set to true and configure MEX Endpoint in all WCF Service those are behind your router service
<service behaviorConfiguration="routingBehv" name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfRoutingService/RoutingService.svc"/>
</baseAddresses>
</host>
<endpoint address="http://localhost/WcfRoutingService/RoutingService.svc" binding="mexHttpBinding" name="mexEndpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
</service>
Step 2- Configure Routing Service
Add Endpoint
<endpoint address="" binding="mexHttpBinding" name="mexEndpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
Add service behaviour
<behaviors>
<serviceBehaviors>
<behavior>
<routing routeOnHeadersOnly="false" filterTableName="routingTable" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Client Endpoint address should specify the "MEX" endpoint address
<client>
<endpoint address="http://localhost/PremiumWcfService/PremiumWCFService.svc/mex" binding="mexHttpBinding" contract="*" name="PremiumServiceMex"/>
<endpoint address="http://localhost/StandardWCFService/StandardWCFService.svc/mex" binding="mexHttpBinding" contract="*" name="StandardServiceMex"/>
</client>
Specify the routing table
<routing>
<filters>
<filter name="StandardServiceMexFilter" filterType="EndpointAddress" filterData="http://tempuri.org/WcfRoutingService/RoutingService.svc/StandardService" />
<filter name="PremiumServiceMexFilter" filterType="EndpointAddress" filterData="http://tempuri.org/WcfRoutingService/RoutingService.svc/sPreminuService" />
</filters>
<filterTables>
<filterTable name="routingTable">
<add filterName="StandardServiceMexFilter" endpointName="StandardServiceMex"/>
<add filterName="PremiumServiceMexFilter" endpointName="PremiumServiceMex"/>
</filterTable>
</filterTables>
</routing>
You are all done.
You can directly access the WSDL file of your services by below URLS individually :
http://localhost/WcfRoutingService/RoutingService.svc/StandardService
http://localhost/WcfRoutingService/RoutingService.svc/PremiumService
the problem in your solution is : you give to your clients a WSDL with the address of your web service PremiumWCFService and StandardService , and the clients (WCF) can use that directly without check and can call your web sevices without call routing service.

Is there a way to pass domain credentials from the originating browser in webHttpBinding wcf service?

Is there a way to pass domain credentials from the originating browser in webHttpBinding WCF service?
I'm thinking this should be possible as when I log into any aspx page with Windows Authentication enabled in IIS, I can get the calling user's domain credentials. How would I setup my WCF service in such a manner? Currently the user identity I get in the WCF service are those of the app pool the svc is running under?
EDIT
I don't have .NET 4 -- My configuration file is below, but I still get an error:
Security settings for this service require 'Anonymous' Authentication
but it is not enabled for the IIS application that hosts this service.
Should I explicitly enable Anonymous for that path in IIS? I think this would undo my efforts to get the domain name.
<behaviors>
<endpointBehaviors>
<behavior name="Awesome.Project.OperationsBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</serviceBehaviors>
<behavior name="Awesome.Project.OperationsServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Awesome.Project.OperationsServiceBehavior"
name="Awesome.Project.Operations">
<endpoint address="" binding="webHttpBinding"
contract="Awesome.Project.Operations"
behaviorConfiguration="Awesome.Project.OperationsBehavior"
bindingName="windowsSecurityWebHttpBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!--<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />-->
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="windowsSecurityWebHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
You need to turn on authentication in the service - assuming .NET 4 add the following to your config
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
for .NET 3.5 or 3.0 you need
<bindings>
<webHttpBinding>
<binding name="webBindingConfig">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service ...>
<endpoint bindingConfiguration = "webBindingConfig" binding="webHttpBinding" .../>
</service>
</services>
Edit for additional questions:
WCF will generally not pass credentials over non secured transports - that's why mode="Transport" is important. If you got rid of it its the same as Mode="None" for WebHttpBinding
If the site is considered to be in the intranet zone then IE will pass the user's credentials automatically. However, non-IE browsers will not and so will hit the site anonymously before getting a 401 and then sending the credentials. The intial request requires anonymous access to be supported in IIS as WCF handles the authentication mechanism
If you need to get hold of HttpContext you can use Asp.NET Compatibility. However in WCF you can use ServiceSecurityContext.Current.PrimaryIdentity.Name to get the authenticated user
How to: Impersonate the Original Caller in WCF Calling from a Web Application gives a walkthrough on how to do this.

IIS Hosted WCF Service won't accept https endpoint, receive 404 resource error

Despite all of my efforts, I have not been able to get my simple WCF service hosted on IIS with SSL.
We are using windows server 2k3 with IIS 6.0 and we have up to .NET 4.0 installed on the server (web site is configured for 4.0)
If i go to http//.../rptService.svc url, I get the .svc page with the code blocks and ?wsdl url
on the other hand, if i go to https//.../rptService.svc I get a "Resource not found" 404 error. (colons on urls are removed b/c of spam prevention)
The web site has a working SSL certificate enabled for it.
My relevant web.config file is as follows:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="rptBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="wcfApp.rptServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpsGetEnabled="false" httpGetEnabled="true" />
<serviceTimeouts/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="wcfApp.rptServiceBehavior"
name="wcfApp.rptService">
<endpoint binding="wsHttpBinding" bindingConfiguration="rptBinding" contract="wcfApp.rptService"
address="">
</endpoint>
<endpoint name="MetadataBinding" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
I have tried just about 100 different ways to write the web.config file from 150 different blog/web posts with similar situations, and have not gotten anything to work thus far.
My end goal is to get this wcf service hosted accepting a username/password token with a custom user name validator, but right now I can't even get it working with SSL!
Application is being built in VS 2010.
Please let me know if there is any more information that I can provide.
Any help is appreciated!

Resources