Because of compliance reasons we have to switch off the support of some ciphers and SSL2 on our webservers. This is not really a problem, but we would also like to inform them, after their successful login into the website, that we suggest switching on TLS 1.2 in their browser in case they are not already connecting to the server with TLS 1.2. So the question I have is:
How can I detect the protocol and cipher used in an https request to an ASP.net (MVC 4) application running in IIS?
I know that there are ways to log the SCHANNEL request to the event log and then read them out again, but this sounds very ugly to me.
And I have seen that the System.Net.Security.SslStream has the properties that I would need, e.g.: CipherAlgorithm, HashAlgorithm, KeyExchangeAlgorithm & SslProtocol, but I'm not sure where I can get these properties in my Controller Action in a mvc4 application.
The bad news, as determined by ILSpy, is that there is no way to get to a System.Net.SslStream instance from anywhere inside ASP.NET. That class is used for direct programming against the network, for example by the WCF framework. The best you can do from ASP.NET (whether using System.Web or OWIN on top of IIS or HttpListener) is to get a server variable (see list of IIS server variables) for whether the connection is secured by whatever secure transport was negotiated with the client.
As far as deterministically reading data from the event log during a web request... that seems scary. But if you can make it work, please share the code. :)
Alternatively, you could try to implement your own Owin host (aka web server!) that uses SslStream underneath. Maybe. :P See this article for a thorough introduction to SslStream programming.
But since you're already able to turn off certain protocols on your server (as in this article, I assume)... You could set up your site on two different subdomains, e.g. www.example.com and secure.example.com, where the former is a vanilla web server and the latter is configured to only accept TLS 1.2 connections. Then you'd write some bootstrapping logic that gets served from www.example.com and attempts to make an AJAX request to secure.example.com/securityUpgradeCheck (possibly with a nicely styled spinner animation and "Please wait, attempting to secure this connection" text to impress your users :)). If that request succeeds, the user can be redirected to secure.example.com (probably permanently, since that user agent is then known to support TLS 1.2 unless for some reason the user changes their browser settings).
For added impact, order an EV SSL certificate for the secure domain so your users will notice the upgrade in security. :)
UPDATE: I did some more digging, on the theoretical basis of writing a custom (native) ISAPI filter (or extension) to get at this information via the SChannel API. At first I was hopeful because I discovered a function HSE_REQ_GET_SSPI_INFO that would return an SSPI CtxtHandle structure, and which you could call from a custom ISAPI extension via the EXTENSION_CONTROL_BLOCK ServerSupportFunction function. That CtxtHandle structure, it turns out, represents an SChannel context and can get you a reference to a SECPKG_ATTR_CONNECTION_INFO attribute with which you can retrieve SSL connection-level information (the same information that's surfaced in the SslStream class in .NET, as far as I could tell). However, sadly, Microsoft anticipated that possibility and decided that this information is only available if you are using client certificates. The behavior is "by design."
There was one (native) SSPI function, QueryContextAttributes (Schannel), that I discovered during a long hunt through MSDN which may work. I haven't tried it, and it could simply fail for the same "by design" reason as the ISAPI API limitation linked to above. However, it may be worth a try. If you want to explore this route, here is an example of an ISAPI extension. Actually, with this approach you might be able to write an IIS module instead, using the newer IIS 7.0+ SDK.
But, assuming you don't have the luxury of requiring client certificates and that long shot doesn't work, that absolutely leaves only two options.
Use a different web server (Apache, etc.), running on the same physical/virtual machine but on a different port, etc. (as per our discussion in the comments, since you can't spin up another machine). If you only want to give the client an informational message, then this approach, coupled with an AJAX request, might be sufficient. Yes, a different port could well be blocked by a firewall somewhere, but hey - it's only an optional informational message anyways.
Rely on the semi-brittle approach with the System event log. Enable Schannel event logging and then write some event log querying code to try to correlate the request with the last-logged Schannel event. Note that you'll need to find a way to reliably correlate whatever gets put in the event log with the current HTTP request, so you might also need to write an ISAPI filter/extension or IIS module in this case to find the Schannel context handle (which is what I'm assuming the correlation would be based on).
By the way - is your load balancer configured to do any SSL interception? Because then this whole thing is moot anyways... Just a thought to consider.
UPDATE: Enabling Schannel logging netted this gem:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Schannel" Guid="{1F678132-5938-4686-9FDC-C8FF68F15C85}" />
<EventID>36880</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2014-08-13T02:59:35.431187600Z" />
<EventRecordID>25943</EventRecordID>
<Correlation />
<Execution ProcessID="928" ThreadID="12912" />
<Channel>System</Channel>
<Computer>**********</Computer>
<Security UserID="S-1-5-18" />
</System>
<UserData>
<EventXML xmlns:auto-ns3="http://schemas.microsoft.com/win/2004/08/events" xmlns="LSA_NS">
<Type>client</Type>
<Protocol>TLS 1.2</Protocol>
<CipherSuite>0x3c</CipherSuite>
<ExchangeStrength>2048</ExchangeStrength>
</EventXML>
</UserData>
</Event>
This can be read out directly from managed code. I think the UserID only corresponds to the IIS worker process SID, unfortunately, but assuming you can come up with some kind of correlation heuristic, you could set up a background thread to continually poll the event log and give you a list of recently established client handshakes (use a ConcurrentDictionary perhaps).
There. That's it. No more curious investigating for me. I'm done. :P
Reading this with interest as we have exactly the same problem.
It occurred to me that there must be a public web service available to query this type of information and I did a little research and found this:
https://www.howsmyssl.com/s/api.html
The API is here
This API can be called from client side Javascript and it returns standard JSON which can be easily parsed and a suitable alert shown to your users.
You can also send the information to your own web service for logging purposes and try to combine the information with your existing IIS logs.
The only issue you face then is relying on a third party. This can be mitigated by standing up your own server and hosting the code which is freely available on GitHub.
We are going to be working on this solution so once I have some code in place I will update this answer.
Thanks again to Lars for the comprehensive answer above. I would have added this as a comment to that post however I thought it worth creating a separate answer so people can find it easier.
How do you check the Negotiated TLS Handshake from the Server? has the way to get this under IIS 8.5 and higher in ASP.Net MVC / WebAPI. At least it worked for me and a couple of others when I answered it yesterday.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I've spent a few months trying to grasp the concepts behind WCF and recently I've developed my first WCF service application.
I've struggled quite a bit to understand all the settings in the config file.
I am not convinced about the environment but it seems that you can do amazing stuff with it.
The other day I've found out that Microsoft has come out with a new thing called ASP.NET Web API.
For what I can read it's a RESTful framework, very easy to use and implement.
Now, I am trying to figure out what are the main differences between the 2 frameworks and if I should try and convert my old WCF service application with the new API.
Could someone, please, help me to understand the differences and usage of each?
For us, WCF is used for SOAP and Web API for REST. I wish Web API supported SOAP too. We are not using advanced features of WCF. Here is comparison from MSDN:
The new ASP.NET Web API is a continuation of the previous WCF Web API project (although some of the concepts have changed).
WCF was originally created to enable SOAP-based services. For simpler RESTful or RPCish services (think clients like jQuery) ASP.NET Web API should be good choice.
ASP.net Web API is all about HTTP and REST based GET,POST,PUT,DELETE with well know ASP.net MVC style of programming and JSON returnable; web API is for all the light weight process and pure HTTP based components. For one to go ahead with WCF even for simple or simplest single web service it will bring all the extra baggage. For light weight simple service for ajax or dynamic calls always WebApi just solves the need. This neatly complements or helps in parallel to the ASP.net MVC.
Check out the podcast : Hanselminutes Podcast 264 - This is not your father's WCF - All about the WebAPI with Glenn Block by Scott Hanselman for more information.
In the scenarios listed below you should go for WCF:
If you need to send data on protocols like TCP, MSMQ or MIME
If the consuming client just knows how to consume SOAP messages
WEB API is a framework for developing RESTful/HTTP services.
There are so many clients that do not understand SOAP like Browsers, HTML5, in those cases WEB APIs are a good choice.
HTTP services header specifies how to secure service, how to cache the information, type of the message body and HTTP body can specify any type of content like HTML not just XML as SOAP services.
Since using both till now, I have found many differences between WCF and Web API. Both technology stacks are suited well to different scenarios, so it is not possible to say which is better, this depends on configuration and scenario.
Properties ASP.Net Web API WCF
--------------------------------------------------------------------------------------------------
End point (mainly) Http based SOAP based
Service Type Front End Back-end
Support caching, compression, versioning No
Framework ASP.net WCF
Orientation Resource Oriented Service Oriented
Transports http http, tcp, MSMQ, Named pipe
Message pattern Request reply request Reply, one way, duplex
Configuration overhead Less Much
Security lesser than WCF (web standard security) Very high (WS-I standard)
Hosting IIS IIS, Windows Service, Self hosting
Performance Fast A bit slower than Web API
In use from .NET 4.0 .NET 3.5
Note: The data is not only my view, it is also collected from other official websites.
WCF will give you so much of out the box, it's not even comparable to anything. Unless you want to do on your own implementation of (to name a few) authentication, authorization, encryption, queuing, throttling, reliable messaging, logging, sessions and so on. WCF is not [only] web services; WCF is a development platform for SOA.
Why I'm answering:
I took huge amount of time to understand the difference between these two technologies. I'll put all those points here that I think "If I had these points at the time when I was wondering around in search of this answer, then I have decided very earlier in selecting my required technology."
Source of Information:
Microsoft® Visual Studio® 2015 Unleashed
ISBN-13: 978-0-672-33736-9 ISBN-10: 0-672-33736-3
Why ASP.NET Web API and WCF:
Before comparing the technologies of ASP.NET Web API and WCF, it is important to understand there are actually two styles/standards for creating web services: REST (Representational State Transfer) and SOAP/WSDL. The SOAP/WSDL was the original standard on which web services were built. However, it was difficult to use and had bulky message formats (like XML) that degraded performance. REST-based services quickly became the alternative. They are easier to write because they leverage the basic constructs of HTTP (GET, POST, PUT, DELETE) and typically use smaller message formats (like JSON). As a result, REST-based HTTP services are now the standard for writing services that strictly target the Web.
Let's define purpose of ASP.NET Web API
ASP.NET Web API is Microsoft’s technology for developing REST-based HTTP web services. (It long ago replaced Microsoft’s ASMX, which was based on SOAP/WSDL.) The Web API makes it easy to write robust services based on HTTP protocols that all browsers and native devices understand. This enables you to create services to support your application and call them from other web applications, tablets, mobile phones, PCs, and gaming consoles. The majority of applications written today to leverage the ever present Web connection use HTTP services in some way.
Let's now define purpose of WCF:
Communicating across the Internet is not always the most efficient means. For example, if both the client and the service exist on the same technology (or even the same machine), they can often negotiate a more efficient means to communicate (such as TCP/IP). Service developers found themselves making the same choices they were trying to avoid. They now would have to choose between creating efficient internal services and being able to have the broad access found over the Internet. And, if they had to support both, they might have to create multiple versions of their service or at least separate proxies for accessing their service. This is the problem Microsoft solved with WCF.
With WCF, you can create your service without concern for boundaries. You can then let WCF worry about running your service in the most efficient way, depending on the calling client. To manage this task, WCF uses the concept of endpoints. Your service might have multiple endpoints (configured at design time or after deployment). Each endpoint indicates how the service might support a calling client: over the Web, via remoting, through Microsoft Message Queuing (MSMQ), and more. WCF enables you to focus on creating your service functionality. It worries about how to most efficiently speak with calling clients. In this way, a single WCF service can efficiently support many different client types.
Example of WCF:
Consider the example:
The customer data is shared among the applications. Each application might be written on a different platform, and it might exist in a different location. You can extract the customer interface into a WCF service that provides common access to shared customer data. This centralizes the data, reduces duplication, eliminates synchronization, and simplifies management. In addition, by using WCF, you can configure the service endpoints to work in the way that makes sense to the calling client. Figure shows the example from before with centralized access of customer data in a WCF service.
Conclusion:
i) When to choose Web API:
There is no denying that REST-based HTTP services like those created using ASP.NET Web API have become the standard for building web services. These services offer an easy, straightforward approach for web developers building services. Web developers understand HTTP GET and POST and thus adapt well to these types of services. Therefore, if you are writing services strictly targeted to HTTP, ASP.NET Web API is the logical choice.
ii) When to choose WCF:
The WCF technology is useful when you need to support multiple service endpoints based on different protocols and message formats. Products like Microsoft BizTalk leverage WCF for creating robust services that can be used over the Web as well via different machine-to-machine configurations.If, however, you do need to write an application that communicates over TCP/IP when connected to the local network and works over HTTP when outside the network, WCF is your answer.
Be Warned:
Web developers often view WCF as more difficult and complex to develop against. Therefore, if you do not foresee the need for multiprotocol services, you would likely stick with ASP.NET Web API.
There is a comparison on MSDN about this
WCF and ASP.NET Web API
For me, the choice was about Who the clients are, and where are they located?
Within the company Network and .NET based clients : Use WCF with TCP binding (Fast communication than HTTP)
Outside the company Network, and use diverse technologies like PHP, Python etc: Use Web API with REST
Business speaking, WebApi lacks of a WSDL, so the developers should document all manually. And if, for example, the WebApi operation returns a list of objects then, the client should creates the objects manually, i.e. WebAPI is really prone to errors of definitions.
The pro of Webapi is its more lightweight than WCF.
Regarding the statement "WebApi lacks of WSDL" there are several ways to generate Rest client. One popular approach is Swagger UI / (Swashbukkle Nuget). This gives a rich interface to understand the REST end point's input and output schema and online tool to test the end points.
JSON LD (Json Linked Documents) is another emerging standard which will further improve the JSON based REST developer experience by exposing the JSON schema with better semantics.
With wcf we can configure and expose the same service support for multiple endpoints like tcp, http.if you want your service to be only http based then it will be better to go with web API. Web API has very less configuration when compared to wcf and is bit faster than wcf. Wcf also supports restful services. If you have limitation of .Net framework 3.5 then your option is wcf.
I'm wondering if any of you can recommend some steps for how I can debug
502 - Web server received an invalid response while acting as a
gateway or proxy server. There is a problem with the page you are
looking for, and it cannot be displayed. When the Web server (while
acting as a gateway or proxy) contacted the upstream content server,
it received an invalid response from the content server.
errors in my web app that is hosted on Azure. The problem is that I cannot consistently reproduce them and they seem to magically go away given enough time. For example, I was getting them sporadically on Friday, but after leaving my site up all weekend it was working fine today ... until I deployed it again with changes that can't possible effect the server (basic presentation-level changes). Sometimes I get 502 for static assets such as images.
How can I figure out what is going on here?
My answer seems a bit late but perhaps this article may help.
Troubleshoot HTTP errors of "502 bad gateway" and "503 service unavailable" in your Azure web apps
The article suggests three specific tasks:
Observe and monitor application behavior
Collect data
Mitigate the issue
Perhaps these suggestions are helpful when hosting in Azure but from my perspective the content isn't very deep.
Recently a couple of WCF services have been introduced to our company's API.
There are sample implementations for Windows that make use of proxy codes generated by Visual Studio 2010 (either full WCF client or Silverlight code). All looking nice.
Then I figured out that it is also possible to let Studio generate a Webservices 2.0 client code proxy and what can I say:
It works just as fine as the WCF client
It also returns real objects, just like WCF
It is also using SOAP
What the heck is the difference/advantage of a native WCF client?
Please note that I'm especially interested in the CLIENT SIDE. The server side is a different story. The point is: why would I connect to a WCF server using WCF client code if Web Services client code works as good?
I can also ask with regards to MONO: WCF support in Mono is far from being perfect, while WebServices 2.0 are woking pretty well. So after fighting with WCF for a while I switched back to a WS 2.0 client code proxy and have not noticed any issues so far. Are there problems I will have to expect?
Flexibility.
Today, you're hitting that service via HTTP. Tomorrow, you might want to add some persistance and hit it via MSMQ. Using WCF that's a configuration change - using Webservice client code you're looking at a complete rewrite of that area of your code.
Another benefit is the ability to turn on tracing, message logging and diagnostics with nothing more than a configuration change.
See Administration and Diagnostics, which says
Diagnostics Features Provided by WCF
WCF provides the following diagnostics functionalities:
End-To-End tracing provides instrumentation data for troubleshooting an application without using a debugger. WCF outputs
traces for process milestones, as well as error messages. This can
include opening a channel factory or sending and receiving messages by
a service host. Tracing can be enabled for a running application to
monitor its progress. For more information, see the Tracing topic. To
understand how you can use tracing to debug your application, see the
Using Tracing to Troubleshoot Your Application topic.
Message logging allows you to see how messages look both before and after transmission. For more information, see the Message Logging
topic.
Event tracing writes events in the Event Log for any major issues. You can then use the Event Viewer to examine any abnormalities. For
more information, see the Event Logging topic.
Performance counters exposed through Performance Monitor enable you to monitor your application and system's health. For more
information, see the WCF Performance Counters topic.
I am trying to build a service mechanism which should be add-on based and communicating through a publish subscribe system. It must be based on WCF services.
What I have right now is a concept which I can't get to work so I decided to ask you because maybe I am going at this the wrong way (I only just started using WCF).
What I want to achieve is making a single core service with session persistency which can be extended by linking an unknown number of add-on services. I want to set up the publish subscribe system at runtime, not at buildtime, so the core-service should be able to detect what add-on services are available (using the web.config?) and then bind them to the message bus.
From the front end (ASP classic) it must be possible to access any .svc file but, maintaining session, each .svc file must be connected to the message bus.
All is hosted in a single IIS active directory.
Can you give me some hints as to where to look?
I am especially interesed in:
WCF dynamic discovery
WCF to WCF communication on the same host (in the same active directory even)
Thanks in advance, hope you can help!
Update
Thanks for your answers, I'll read up at the links you send me. I'll post my final concept solution here in due time for future reference.
My 2 cents about Publish subscribe mechanism using WCF - WCF is not inherently built for pub/sub mechanism. It is built for Request/Response model of communication. Have a look at the NService Bus for pub/sub here
Talking about Add on services on top of core service, I am not able to get What you want exactly ? Is it the Routing service which you want ? WCF 4 now provides routing service For more information look here The link also talks in detail about the discovery mechanism in WCF 4.
Also have a look the Agatha framework which also have single WCF service and no. of request handlers where in the framework will decide which request handler to call based on each request.
Search for Agatha - Davy brion for more information
I was having a similar problem since I have one common WCF service but the implementation depends on the user's role so it was kind of difficult to do that at runtime.
I found this tutorial on the matter which runs great for my propouses: http://blog.micic.ch/net/dynamic-iis-hosted-wcf-service
I have tested in my env and is very powerful technique. Hope that helps you as well. Cheers.