3

I want to delay the response of my website authentication request so that the server begins responding at a particular seconds offset from when the request was received.

For example, if the user authenticates at 04:00:00, I want the response to come back at 04:00:05, not sooner nor later. If it is not possible for the code to meet the deadline, I want it to cause an error.

This must be done on the server side and I would like to avoid using Thread.Sleep. Though, I was thinking there may be a way to do this with an async controller and using Thread.Sleep in part of the request's continuation

Has anyone here faced a similar challenge and what was your solution?

Can any of you folks think of a way to do this while avoiding Thread.Sleep and maintaining responsiveness?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Michael J. Gray
  • 9,784
  • 6
  • 38
  • 67
  • 2
    Why do you want to do this? – Dai Dec 11 '12 at 01:03
  • "No sooner nor later"? What about network (un)reliability? – Ian Dec 11 '12 at 01:03
  • 1
    @Dai The response time of an authentication attempt can be used to determine various pieces of information about where the web application's logic stopped. For example, you can test if a username exists in a database by measuring if it came back quicker than a username that is known to not exist. I have a multiple stage authentication scheme that has too many variables to make each of them resistant to such attacks. I just want to specify how long those operations are going to take in terms of a minimum and maximum time. Latency isn't considered because it's an uncontrollable variable. – Michael J. Gray Dec 11 '12 at 01:09
  • @Ian I only care about when the action starts and stops, not how long it takes to be received or how long the response takes to be transmitted back. Since network latency is outside of the scope of the operations, it will not matter. It's strictly about the time it takes for the internal authentication operations to complete. Hopefully that clarifies a bit better! – Michael J. Gray Dec 11 '12 at 01:11

2 Answers2

4

You can use the Async support in MVC 4 (or an AsyncController if you're on MVC 3)

public async Task<ActionResult> GizmosAsync()
{
    var gizmoService = new GizmoService();
    return View("Gizmos", await gizmoService.GetGizmosAsync());
}

The method in await can then use the time it needs, including Thread.Sleep.

That way, you're not blocking ASP.net from handling other requests.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • +1 This is what I've been thinking of doing as mentioned in my question. If nobody else comes forward, I'll give it the tick. Seems to be pretty elegant in MVC 4 because you don't need the whole AsyncController fud. – Michael J. Gray Dec 11 '12 at 02:51
3

You can use a custom ActionFilters.

  • Record the time the request arrived in the OnActionExecuting method.
  • Then on the OnResultExecuted method inspect the result. If it is a valid response let it through, if it is a not authorized response delay it using Thread.Sleep with the desired delay based on the start time recorded.

Just make sure your filter runs before the authorization filter ([Authorize] ?) or is registered before it if you're using global filters and not attributes.

In this way the delay has no impact on authorized users which I assume is the reason you don't want to use Thread.Sleep. Note that Thread.Sleep by default is not very accurate (on the order of 20ms), but network latency to the client should obscure that.

Eli Algranti
  • 8,707
  • 2
  • 42
  • 50
  • +1 because it's something different. However, it seems to throttle all different unauthorized users in a sort of additive manner. If one response is sleeping and others become queued, they return in chunks of 8. If I have 1024 requests going, the last request will come back after 129 seconds. – Michael J. Gray Dec 11 '12 at 02:50
  • hmm, yes, forgot about possible thread allocation issues. Does this happen on IIS/IIS Express or are you using the internal http server? There's probably a threshold of eight concurrent threads running, this can be probably raised in some configuration parameter, but it seems a bit low for a default in a production server. – Eli Algranti Dec 11 '12 at 03:00
  • I was hoping there was some way to make the action filter asynchronous and use Task.Delay instead of sleep to solve this problem, but apparently this is not (for now) supported in MVC4: http://stackoverflow.com/questions/12482338/async-action-filter-in-mvc-4 – Eli Algranti Dec 11 '12 at 03:28
  • Edited. I spoke too soon and without reading everything twice! I used `Task.Delay` instead of `Thread.Sleep` inside of my authentication action and it's exactly what I needed. I didn't notice the "[...] action filter asynchronous" part of your comment and jumped into testing and it worked the way I described. It's exactly what I needed. – Michael J. Gray Dec 11 '12 at 04:55