When custom SecurityTokenHandler gets triggered? - wcf

I have a simple REST Web Service. I have tried to implement SimpleWebToken security therefor I created a custom SecurityTokenHandler with overridden CanreadToken and ReadToken then I registered it in web.cofig file.
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<clear/>
<add type="TestTokens.SimpleWebTokenHandler, TestTokens"></add>
</securityTokenHandlers>
<audienceUris>
<clear/>
<add value="http://mytestrealm/"/>
</audienceUris>
</identityConfiguration>
I thought that CanReadToken() is always called, in order to make sure that the incoming request can be handled.
Why it is not called?

IFAIK, this collection of security handlers is only called when the WIF plumbing needs it. This can be p.e. when you offer a WS-Trust service. It is not called on all requests.

That is correct, WIF plumbing can be used to authenticate users. It looks like you are looking for more of a WebAPI solution. I would recommend using Jwt tokens as everyone seems to be leaning that way. Have a look here:
http://www.cloudidentity.com/blog/2013/06/06/the-json-web-token-handler-for-net-4-5-reaches-ga/
We put in some features that help when validating jwt's for WebAPI's.

Related

PayPal REST API - Moving from Sandbox to Production

I am using the PayPal .Net SDK (got it from github) in my Asp.Net MVC5 web application. Everything worked well while testing in the sandbox environment. Everything is stored in the web.config file:
<settings>
<add name="mode" value="sandbox"/>
<add name="connectionTimeout" value="360000"/>
<add name="requestRetries" value="1"/>
<add name="clientId" value="my rest app sandbox client id"/>
<add name="clientSecret" value="my rest app sandbox client secret" />
</settings>
What I have done for going live is getting the live credentials of the REST App from the paypal developer portal. I then chnaged the web.config settings to:
<settings>
<add name="mode" value="live"/>
<add name="connectionTimeout" value="360000"/>
<add name="requestRetries" value="1"/>
<add name="clientId" value="my rest app live client id"/>
<add name="clientSecret" value="my rest app live client secret" />
</settings>
When I run my web application in the live mode, it fails when calling the oAuth token generation:
string clientRequestsToken = payPalTAuthToken.GetAccessToken();
I am getting an IdentityException while the line of code above is executed.
Am I missing something ? do I need to configure anything else for going live with the PayPal REST APIs ?
I have read that when using the Classic APIs, a certificate needs to be generated and installed on the consumer server to encrypt the credentials, but I would assume this is only relevant for the Classic APIs, not for the REST APIs.
Thx for your help !
Sam
You could find information about moving from sandbox to live over here:
https://github.com/paypal/PayPal-NET-SDK/wiki/Frequently-Asked-Questions#how-do-i-target-the-live-or-sandbox-paypal-services
We are adding more and more FAQs to help developers resolve issues faster. Let us know, or update yourself, if you have any FAQ, that you want answered, or help us answer.

Configure IIS Express 8 to enable CORS

I'm writing WCF services that will be used by clients out in the wild so they need to handle cross-origin requests. I have a problem with enabling my development server to accept such requests. Here is the scenario:
I'm running the WCF project in an instance of Visual Studio 2012, using IIS Express 8 as the server on a specific port.
I'm running the client project in another instance of Visual Studio 2012, also using IIS Express 8 as the server. This project uses AJAX to consume services in the other project.
When I run the client project in IE there is no problem because IE does not send the preflight OPTIONS request. When I run it in Chrome however the preflight OPTIONS request returns a 405 Method Not Allowed and Chrome gives up on the service. Previous versions of Chrome would just ignore the error and continue with the actual POST request (or Get, whatever...) but later versions appear to be pickier.
I've also run into this with a deployed WCF project and solved it by moving the OPTIONSVerbHandler to the top of the Handler Mappings list in IIS.
I should point out that I'm using the most generous web.config settings I can think of to try to allow CORS. For instance I have this in the WCF project's configuration:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
<add name="X-Powered-By" value="*" />
</customHeaders>
</httpProtocol>
Regardless, any client cross-origin requests to the WCF project running from code fail with the 405 error.
Any help setting up either the WCF project itself or IIS Express 8 to enable CORS?
Thanks!
You can enable cors for wcf, and it could be quite simple, once you know how.
Elaborating from DavidG response on the more general question "cors on IIS", response which is really near of what is required for a basic solution:
First, configure the OPTIONSVerbHandler to execute before .Net handlers.
In IIS console, select "Handler Mappings". (Do this either on server level or site level. On site level it will redefine all the handlers for your site and ignore any change done on server level after that. And of course on server level, this could break other sites if they need their own handling of options verb.)
In Action pane, select "View ordered list...". Seek OPTIONSVerbHandler, and move it up (lots of clicks...).
You can also do this in web.config by redefining all handlers under <system.webServer><handlers>. (<clear> then <add ...> them back, this is what does the IIS console for you. By the way, there is no need to ask for "read" permission on this handler.)
Second, configure custom http headers for your cors needs, such as:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
This example set them for all responses to all requests on the site/app/directory in which is the web.config. If you want to restrict them to some url, put that in a <location> tag.
You can also add those custom headers in IIS console.
This is a basic solution since it will send CORS headers even on request which does not require it, maybe opening your application to unexpected usages. But with WCF, it looks like being the simplest one.
With MVC or webapi, we could instead handle OPTIONS verb and cors headers by code (either "manually" or with built-in support available in latest version of webapi).
as a value is only valid for Access-Control-Allow-Origin. For the others you need to be explicit. For example:
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
or alternatively:
Access-Control-Allow-Methods: PUT, DELETE
because the spec says GET and POST are implied.
The answer is that the configuration needed to enable WCF to accept CORS preflight messages has nothing to do with the IIS server; rather the WCF project itself needs to be configured to handle the HTTP request with OPTIONS verb.
Long story short: doing this is REALLY HARD. WCF is a jack of all trades when it comes to endpoints so setting it up to do something very specific with one (HTTP) is not advisable, although it can be done. The real solution is to use Web API, which is a master of HTTP and can be set up to do CORS very simply.
I just wanted to mention, that as of this writing, I don't believe that web browsers support the * wildcard value for Access-Control-Allow-Methods or Access-Control-Allow-Headers even though it's in the spec.
Spec:
https://www.w3.org/TR/cors/
https://www.rfc-editor.org/rfc/rfc2616#section-4.2
See Compatibility Notes (easier reading):
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
In lieu of the above, better solutions, this means that you have to explicitly provide each and every header or method you want to allow.
I'm not sure this is really hard as djo.dadof2 says. One of the answers above talks about using the IIS console, but the question is about IIS Express. To be fair it talks about moving the OPTIONSVerbHandler higher which may in fact work in IIS Express, but you have to clear all the handlers and add them back, which without a console such as IIS has, is difficult as you don't know which ones to add back. From this answer, Call WCF service from JQuery : cross-origin OPTIONS request gives error 400, you can see that all you really need to do is handle the OPTIONS request in Global.asax.cs, Application_BeginRequest. I added
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
HttpContext.Current.Response.End();
}
And together with
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="null" />
</customHeaders>
</httpProtocol>
in the webconfig system.webServer section that worked for me. Note that I used content-type in the Access-Control-Allow-Headers header to match what Firefox was sending, and null in the Access-Control-Allow-Origin as I was opening an html page from the local drive.

WCF - Inspect the messages being sent/received?

I have 2 solutions:
- Server Solution
- Client Solution
The server registers itself to my localhost IIS: http://localhost/MyApp/
The client adds WCF Services (Service References) from the localhost application: http://localhost/MyApp/MyService.svc
When I'm running the client I want to be able to see the messages being passed back and forth. I downloaded Fiddler, but it doesn't seem to want to show me any traffic being sent unless I actually use a web browser. Am I using Fiddler wrong or is there another tool I should be using for this?
To clarify, what I'm looking to do is to see the actual messages being passed in. I don't want to do anything with them except see them visually with my own eyes.
I like the WCF Service Log Utility, but I don't think I have the correct setting on there. I can't see the actual soap message, just that a message was received.
And also to clarify further, I don't care what tool I use as long as I can easily see the messages themselves.
To view the message contents you must add a source for System.ServiceModel.MessageLogging in your configuration file. The message tab in the Trace Viewer will show the full message for a particular service call.
Here is a sample configuration file:
<configuration>
...
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="All"
propagateActivity="true">
<listeners>
<add name="traceListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging"
switchValue="All">
<listeners>
<add name="traceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\Traces.svclog" />
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="500"/>
</diagnostics>
...
</system.serviceModel>
...
</configuration>
See the Configuring Tracing topic on MSDN for more information. http://msdn.microsoft.com/en-us/library/ms733025.aspx
Maybe I'm missing something, but...
Why don't you use the WCF tracing features? It's a fantastic troubleshooting tool. I've used it for services hosted in IIS/WAS also.
Enabling WCF Tracing
BTW, some people don't know it, but you can open traces from server side and client side at the same time, and the Viewer will show you the correlation between the server and client actions in a nice graph.
EDIT: whenever I had to capture TCP/IP traffic, I use WireShark. If you need to do it programatically you can use SharpPCAP, so I can take actions upon what I capture from the network. But for troubleshooting, much much better to rely on WCF Tracing.
If you want to inspect messages programattically, you can implement an IClientMessageInspector interface and register it with your client.
This allows you access to all of the messages, no matter what binding you are using, whereas using tools like Fiddler will only allow you to inspect messages using the HTTP transport channel.
Note, that using this technique, you can do much actually modify the messages or do much more (fire off notifications, for example). If all you wish to do is put your eyes on the message, then using tracing might be an easier approach for you.
Is your service SOAP or RESTful? You can use the WCF Service Trace Viewer Tool to view the SOAP message headers and bodies. Instructions for configuring your web service for tracing are here.
Look at this StackOverflow thread: How to use Fiddler to monitor WCF service
It answers some of your questions. you can also use something like WireShark if you want to examine everything on the wire rather than set up a Proxy, as Fiddler does.
In WCF we can use another way to see actual SOAP messages - custom MessageEncoder - a low-level pipeline extensibility point. Unlike message inspectors (IDispatchMessageInspector / IClientMessageInspector) it sees original byte content including any malformed XML data. You need to wrap a standard textMessageEncoding as custom binding element and adjust config file to use that custom binding.
Also you can see as example how I did it in my project - wrapping textMessageEncoding, logging encoder, custom binding element and config.

Anonymous access with WIF

After having searched for an answer thoroughly on SO, I have to ask my first question for good this time !
Here goes :
I have a Windows Forms app, which uses a dozen WCF services to handle all the business logic.
WIF is implemented on every single WCF service, and users are authenticated through a basic UserName authentication.
Everything works well except the Ping() method that we have.
Before WIF was implemented, we used to call every WCF service with a dummy Ping() method during the splash screen to ensure the service was up, but now the user can't access this method since he's not logged yet.
Is there a way to distinguish Authenticated and Anonymous Methods in a service on which WIF is implemented ? I suppose there isn't, so I'd like to know if maybe an anonymous token could be issued by the STS ?
I'm pretty out of ideas right now, so any help or just some hints would be greatly appreciated :)
Depending on your configuration, you could create a set of services within a specific folder in your site, then add custom configuration to that location that would not include the Authentication and Session modules.
As an example:
<location path="AnonymousServices">
<system.webServer>
<modules>
<remove name="WSFederationAuthenticationModule" />
<remove name="SessionAuthenticationModule" />
</modules>
</system.webServer>
</location>
I have not tried this in practice, but it should work.

WCF Authorization using IIS and ACLs

i'm trying to secure some WCF services. I'd like to use IIS or the Web.config todo all of the heavy lifting/configuration if possible. I don't want to embed anything in my code - thought I know that may not be feasible. If possible, I'd like to achieve this without having to resort to AspCompatibilityMode :(
I'm using a custom BasicHttp binding with TransportCredential enabled.
This works fine. Any valid domain or machine account seems to validate against the service.
My problem is I only want users from specific windows groups to be able to access my service. I wanted to use ACLs on the actual folders to achieve this, but I don't think it is possible.
Would appreciate your help!
Thanks
TM
In your web.config try the following:
<authentication mode="Windows" />
<identity impersonate="false" />
<authorization>
<allow users="MYDOMAIN\YourGroup" />
<deny users="*" />
</authorization>
This will block it at the web config level. You can also put an ACL on your folder. Note the Windows authentication and the impersonate = false means that it is the users credentials that are being used to access the directory.