I'm trying to add the CORS headers to a WCF service which is part of a precompiled web site project in VS 2012.
The error
The type 'EnableCrossOriginResourceSharingBehavior, MyWebSite, Version=0.0.0.0, Culture=neutral' registered for extension 'crossOriginResourceSharingBehavior' could not be loaded.
from the config file
<behaviors>
<serviceBehaviors>...</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp />
<crossOriginResourceSharingBehavior /> <!-- Error Here -->
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="crossOriginResourceSharingBehavior" type="EnableCrossOriginResourceSharingBehavior, MyWebSite, Version=0.0.0.0, Culture=neutral" />
</behaviorExtensions>
</extensions>
Now, there is no MyWebSite.dll in a precompiled site, apparently. So, how do I get past this and make the BehaviorExtension work?
You have that error because the definition has a wrong type: you lost namescpace of the type.
<add name="crossOriginResourceSharingBehavior" type="MyWebSite.EnableCrossOriginResourceSharingBehavior, MyWebSite, Version=0.0.0.0, Culture=neutral" />
Probably the version is wrong, because it equals to 0.0.0.0 in the definition. See AssemblyInfo.cs for the assembly version.
I see the assembly hasn't a strong name. So you can remove Version and Culture from the definition.
<add name="crossOriginResourceSharingBehavior" type="MyWebSite.EnableCrossOriginResourceSharingBehavior, MyWebSite" />
Related
i have a couple of web site in IIS now i have added a WCF service under sites>default website > MyWCFService.
When i tried to browse the Service1.svc file through content view in IIS i was presented below error
HTTP Error 404.17 - Not Found
The requested content appears to be script and will not be served by the static file handler.
Detailed Error Information
Module: StaticFileModule
Notification : ExecuteRequestHandler
Handler : StaticFile
Error Code 0x80070032
Requested URL : https://localhost:443/MyWCFService/Service1.svc
Physical Path : D:\Inetpub\wwwroot\MyWCFService\Service1.svc
Logon Method : Negotiate
Logon User : XXXXXXXXXXXXXX
Most likely causes:
•The request matched a wildcard mime map. The request is mapped to the static file handler. If there were different pre-conditions, the request will map to a different handler.
Things you can try:
•If you want to serve this content as a static file, add an explicit MIME map.
Here is my webconfig file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="MyService.Service1" behaviorConfiguration="MyService.Service1Behavior">
<endpoint address="Service1" binding="basicHttpBinding" contract="MyService.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyService.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The service runs fine in my local machine, but it fails in IIS, may be something to do with IIS Settings?
I'm running on IIS version 7.5.7600.
Thanks in advance
Edit 1: : Installed WCF Activation (HTTP Activation and Non-HTTP Activation) under .net Framework 3.5.1 features in via Server mnager. Now the error when i tried browing the service1.svc file through browser is
Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
i have added this entry in web.config file as well
<compilation debug="true" strict="false" explicit="true">
<assemblies>
<add assembly="System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</assemblies>
</compilation>
No great change in output.
The requested content appears to be script and will not be served by the static file handler.
Don't use Content View, use a browser.
See also Script not served by static file handler on IIS7.5.
I'm struggling on a setup mentioned in the subject line and am wondering if someone can help me.
Essentially, what I have is a WCF service and I want to achieve that the user can authenticate against the ACS using a custom login page (using the javascript with required information from ACS).
After doing that the user should get redirected to the WCF service using the provided SWT token. I am using the SimpleWebTokenHandler as a basis for the SWT token handling, but I'm not sure it's playing any role in this.
Here's the Web.config I'm running
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral" />
</configSections>
...
<system.serviceModel>
<diagnostics>
</diagnostics>
<services>
<service name="WcfWifSwtAcs.Service1">
<endpoint address="xmlService" binding="webHttpBinding" bindingConfiguration="" behaviorConfiguration="restPoxBehaviour" name="xmlServiceEndpoint" contract="WcfWifSwtAcs.IService1" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="restPoxBehaviour">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials useIdentityConfiguration="true">
...
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="ws2007FederationHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="Message">
<message
issuedTokenType="http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0">
<issuerMetadata address="https://xxxx.accesscontrol.windows.net/v2/wstrust/13/certificate/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
...
</system.webServer>
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="http://localhost:56782/Service1.svc" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add thumbprint="XXX" name="xxx.accesscontrol.windows.net" />
</trustedIssuers>
</issuerNameRegistry>
<issuerTokenResolver type="SimpleWebToken.CustomIssuerTokenResolver, WcfWifSwtAcs" />
<securityTokenHandlers>
<clear/>
<add type="SimpleWebToken.SimpleWebTokenHandler, WcfWifSwtAcs"/>
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
</configuration>
Now I can see, that the authentication happens and that the browser is redirected with the body to the service. I can also see that the SimpleWebToken handler get's instantiated and the token type URI is being requested. But that's almost all that happens. No actual token handling verification and whatsoever is happnening.
This is the token that get's sent to the service (after parsing).
wa=wsignin1.0&
wresult=
<t:RequestSecurityTokenResponse
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:Lifetime>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-02-13T23:14:30.159Z</wsu:Created>
<wsu:Expires
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-02-13T23:24:30.159Z</wsu:Expires>
</t:Lifetime>
<wsp:AppliesTo
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<EndpointReference
xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://localhost:56782/Service1.svc</Address>
</EndpointReference>
</wsp:AppliesTo>
<t:RequestedSecurityToken>
<wsse:BinarySecurityToken
wsu:Id="uuid:58e2fb15-dd1a-40bd-8ff0-ae24e22e6efe"
ValueType="http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
BASE64 DATA==
</wsse:BinarySecurityToken>
</t:RequestedSecurityToken>
<t:TokenType>http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0</t:TokenType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
</t:RequestSecurityTokenResponse>
Service itself is braindead simple, with following signature.
[OperationContract]
[WebInvoke(UriTemplate = "/GetData/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string GetData(string id);
Any ideas? I've been verifying that the uri's, hostnames, thumbprints etc. are all valid. Also the service tracing doesn't really show up anything that is related either to token handling or exceptions in the token verification.
Somehow it almost seems that the token doesn't get even passed to the handler. At least all the claims and other authentication information is missing (null).
I would appreciate if someone points me to a direction of either where can I debug or if I'm missing something really obvious (which might also always be the case).
P.S. I know I could achieve it with custom authentication modules and whatsoever, I'd rather get it running with WIF (it's becoming fundamental as I've spend more time on this as I really wanted and I'm very stubborn :p).
Soo, dedication will bring one to a solution. Although I initially thought that this can't be done, it's apparent that it actually can. I'll put the solution here, as maybe there are other people who find it useful.
First of all, WCF REST services are using webHttpBinding, which according to MS documentation does not support the Windows Identity Foundation and claims handling in the pipeline. Actually it does. Not in the WCF pipeline, but as the IIS module in web authentication flow.
First, you need to add the following modules to Web.config file.
<system.webServer>
<modules runManagedModulesForAllRequests="true">
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" preCondition="managedHandler" />
</modules>
</system.webServer>
There's a caveat tho. You need still the <configSections> from my original posting. The problem is that you need, in VisualStudio, to mark the System.IdentyModel* assemblies as CopyLocal items (in the properties window). Otherwise you'll get some cryptic exception that assembly cannot be loaded for the configuration section. NB! It only happens if you are loading these two modules and doesn't happen when those modules are not getting loaded. Didn't have any will to investigate that thing further, perhaps someone knows better what's the cause there.
Next if for any reason you plan to use the SWT token handling sample from MS WIF code, there are a couple of bugs that need to be fixed, otherwise the token parsing just won't happen or you will get invalid signatures out of the token verification.
SimpleWebToken.cs you need to fix the SwtBaseTime as it is initialized incorrectly and the security token creation fails afterwards:
From
public static DateTime SwtBaseTime = new DateTime( 1970, 1, 1, 0, 0, 0, 0 ); // per SWT psec
To
public static DateTime SwtBaseTime = new DateTime( 1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc ); // per SWT psec
SimpleWebTokenHandler.cs you need to fix the casing of the following values:
From
const string BinarySecurityToken = "binarySecurityToken";
const string ValueType = "valueType";
To
const string BinarySecurityToken = "BinarySecurityToken";
const string ValueType = "ValueType";
CustomIssuerTokenResolver.cs you need to fix the key that is created as it's initalized with a UTF8 bytes, but it should actually get initialized with decoded Base64 bytes:
From
key = new InMemorySymmetricSecurityKey(UTF8Encoding.UTF8.FromBase64String(base64Key));
To
key = new InMemorySymmetricSecurityKey(System.Convert.FromBase64String(base64Key));
After you've fixed all this, everything sits in place. The authenticators and authorizators are getting called and voilà, suddenly you have a WCF Service exposed as REST endpoint and all the claims etc. are also working.
I think your issue may be with the SWTTokenHandler in this sample: http://code.msdn.microsoft.com/vstudio/Custom-Token-ddce2f55
In CanReadToken(), it checks to see if the token is a BinarySecurityToken of type SWT:
if ( reader.IsStartElement( BinarySecurityToken )
&& ( reader.GetAttribute( ValueType ) == SimpleWebTokenConstants.ValueTypeUri ) )
But the constant BinarySecurityToken is defined as:
const string BinarySecurityToken = "binarySecurityToken";
Note the lower-case "b". XML elements are case sensitive, and the actual element is "BinarySecurityToken" with a capital B. This will cause the handler to return false in CanReadToken(), causing WIF to believe it doesn't have a handler registered for this token type.
I'm trying to add a web application in IIS under an existing (root level) website. The root level website's web.config file defines certain behaviorExtensions under system.serviceModel:
<extensions>
<behaviorExtensions>
<add name="errorHandler" type="API.ErrorHandler.WCFErrorHandlerElement, API.ErrorHandler, Version=1.5.1.832, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
The extension is used like this:
<serviceBehaviors>
<behavior name="DefaultRESTBasedHTTPSServiceBehavior">
<errorHandler />
</behavior>
</serviceBehaviors>
For certain reasons I'm not allowed to add a reference to the required assembly in the added website, so I want to disable the extension's inheritance by this way (in the added website's web.config of course):
<behaviors>
<serviceBehaviors>
<clear/>
</serviceBehaviors>
<endpointBehaviors>
<clear/>
</endpointBehaviors>
</behaviors>
I was also trying to prevent the inheritance of the extensions section like this: <extensions><clear/></extensions>. It seems though, that <clear/> is not supported for the extensions node.
Yet I get the following exception when a WCF error happens on the added website (the problem is at Line 191):
Parser Error Message: The type 'API.ErrorHandler.WCFErrorHandlerElement, API.ErrorHandler, Version=1.5.1.832, Culture=neutral, PublicKeyToken=null' registered for extension 'errorHandler' could not be loaded.
Line 189: <serviceBehaviors>
Line 190: <behavior name="DefaultRESTBasedHTTPSServiceBehavior">
Line 191: <errorHandler />
Line 192: </behavior>
Line 193: <behavior name="DefaultSOAPBasedHTTPSServiceBehavior">
Please consider, that it is not possible to prohibit inheritance in the root level website's web.config, because other added websites are using the settings in question.
If you are able to use the <location> element in the root web.config then you can chose which sections not to inherit using the inheritInChildApplications attribute:
For example:
<location path="MyWebApp" inheritInChildApplications="false">
<system.serviceModel>
</system.serviceModel>
</location>
I have a WCF RESTful web service (using the webHttpBinding) running under IIS, exposed via an SVC file (accessed at http://projectserver/BlarghService/BlarghService.svc).
I can access service endpoints through the URI templates defined on each service by using the BlarghService.svc file, like so:
http://projectserver/BlarghService/BlarghService.svc/accounts/
http://projectserver/BlarghService/BlarghService.svc/accounts/342432
Both of these work fine.
However it's important I remove implementation details from the URIs, so I used IIS URI rewriting module and set up a wildcard rewriting rule which tacks everything after /BlarghService/ to the end of BlarghService.svc, so the following are transformed into the earlier representations:
http://projectserver/BlarghService/accounts/
http://projectserver/BlarghService/accounts/342432
However, when I request these resources I get 404 errors. These are not IIS-generated 404 errors, but those generated by ASP.NET itself (so IIS is correctly rewriting the URL). However ASP.NET decides to check if the specified file ("BlarghService.svc/accounts/342432") exists in the filesystem which it should be passing it on to my web service.
But the strange thing is when I copy the reported "Requested URL" (from the ASP.NET 404 error) back into the address bar, it works fine.
So what's going on?
EDIT: Here is my web.config (located in the "BlarghService" directory)
<system.web>
<compilation debug="true" />
<authentication mode="None" />
<customErrors mode="Off" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<!-- Currently ASP.NET steps in says it's a 404 error when it should be handled by BlarghService.svc, I've no idea why. -->
<rewrite>
<rules>
<rule name="BlarghServiceRewriteRule" patternSyntax="Wildcard">
<match url="*" />
<action type="Rewrite" url="BlarghService.svc/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://projectserver/BlarghService" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<services>
<service name="Foo.Blargh.Api.BlarghService" behaviorConfiguration="BlarghServiceBehavior">
<endpoint name="BlarghEndpoint" address="BlarghService.svc" behaviorConfiguration="BlarghEndpointBehavior" binding="webHttpBinding" contract="RH.Blargh.Api.BlarghService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BlarghServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="BlarghEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
UPDATE: It turns out that WCF can only respond on one particular HTTP host header at a time, and that my URL rewriting was involved in responding to some host headers but not others. By standardising on a single set of host-headers and reformulating my rewrite rules accordingly it started working.
Is there a way to serve up a custom "Sorry not found" page from a direct access request to a WCF Service (.svc file) on a server running IIS 6.0, and .NET 3.5 SP1.
I have a requirement that my service in a Production environment is not discoverable. The requirement states that WSDL publishing should be off, and the request also states that when directly accessing the MyService.svc file via a HTTP Get Request that a "Sorry Not found" page is displayed instead.
I have no problem disabling the metadata in the config file.
<serviceMetadata httpGetEnabled="false" />
But I can't figure out a way to not show the default .svc page.
SERVICE
This is a Windows© Communication Foundation service.
Metadata publishing for this service is currently disabled.
If you have access to the service, you can enable metadata publishing by completing the following steps to modify your web or application configuration file:
...
** Also posted at ServerFault.
in web.config:
<httpHandlers>
<remove verb="*" path="*.svc" />
<add path="*.svc" verb="POST" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>
</httpHandlers>
Try setting http[s]HelpPageEnabled to false in Web.config. Example:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" />
<serviceDebug httpHelpPageEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>