Different behavior in GET vs. POST Ajax request - ajax

We have an MVC app that uses controllers for AJAX endpoints, and FormsAuth for authentication.
I've run into an interesting scenario where a GET request will behave differently than a POST request (both for an unauthorized user).
In this particular case, our custom ControllerFactory runs the following code trying to access this controller:
FormsAuthentication.SignOut();
requestContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl);
throw new UnauthorizedAccessException();
(I realize that redirecting inside an AJAX request makes no sense, but bear with me).
When I do a GET request (AJAX) to this controller, the client receives a 401 - Unauthorized exception, which I can trap on the client side and redirect the user to the login page.
When I do a POST request (AJAX) to this controller, I'm getting a 302, and my request got redirected to my login page.
Why do the GET and POST requests act differently?

So I took Darin's advice and did some refactoring, and I no longer run into this problem. :) I discovered the root of my problem, which was that we had a attribute for MVC error handling that did not have the IExceptionFilter attribute, so some stuff was happening in non-determinate orders. Thanks for the helpful kick in the butt. ;)

Related

URL redirect in spring mvc

Hi guys I want that I have a post method in spring controller
But user hits url request directly from a browser then user gets nothing.
So how can I redirect this to login page in spring mvc.
As per your description
But user hits url request directly from a browser then user gets
nothing
When user hitting a URLfrom browser, it should be a GET request but you said you have POST request there. That's why nothing happens(should give
GET not supported
in browser though).
POST method requests server to process submitted form data.
To achieve that, you have to declare a GET method for that URL in your controller side and return your resource(view) to the user and then user will get that after hitting that URL. After that you can perform POST request from user side(i.e. form data submission).
In one line: Your POST request will be GET in controller side if you want to just what you want.
Please let me know if I can assist more.
probably you should look for security instead of look for "redirects", you can cool at this question for reference :
link to similar question
It is NOT possible to make POST request from the browser.
You can find some other approaches fire-http-post-requests-with-firefox-or-chrome

redirection after 'delete' in express

From the client side, I am making an Ajax request of type "delete" using jquery.On the server side, I am doing res.redirect(URL).But instead of redirecting, browser is again making a delete request with URL returned from server side for redirecting.
However, it is not happening for a post request.Everything is OK with post request.
Short version
Ajax is trying to follow the request to it's bitter end to get a successful response (2xx). If you want to delete a resource and send the user to a new web page, you will need to handle that after receiving a success response from your Ajax call.
Full explanation
While redirects are sometimes used after processing a request (such as a successful / failed login) it's not really what they're intended for. Generally you would only redirect the user to get them to the resource their looking for. For example, you might move an endpoint such as POST /blog-post to the new location of POST /blog-article. What you're saying to the requester here is that something used to be where it is, but now they need to make a request elsewhere to find what they're after. This is incredibly important when trying to prevent link rot.
The idea of accepting and processing a request, and then moving the user off to another page is more of a coincidence really. It just happens to work due to how a browser handles URL requests.
I expect your POST request is actually using a form, in this case the browser is following the redirect because it received something like a 301 and is attempting to see a request chain through. However when using Ajax a redirect is being handled by the Ajax call itself, not the entire browser. Ajax in this case is acting as if you'd expect if the endpoint had been moved. So for example, if you moved the endpoint on the server side, your application would still function as it would follow the redirect instruction.
What you really need to do is return a successful response to your Ajax call such as a 204 (No content) and then in your frontend move the user on to a new page.
This isn't as convenient I'll admit, but when you understand why the redirects actually exist it makes more sense. They're not a way of telling a user to move onto something else, they're a way of trying to prevent link rot and enable applications to continue working against an API which may have changed slightly.

How do I handle an MVC Cross site POST?

I have to handle Cross site POSTS from Ajax calls in an MVC project.
I have a method in my controller that is supposed to accept a POST with the view model as the POST body. My page is making an ajax call to it from Javascript. This works fine if everything is under the same domain.
IE11 sends an OPTIONS request without a POST body the first time my Ajax call is made. MVC tries to route this, fails to find my method (probably because it takes the ViewModel parameter), and returns a 404. However after the first time the call errors out, subsequent calls include the POST body and are routed successfully.
I thought I could fix this easily by including an overload of my method in my controller that takes no parameters and returns a 200 (or 204) and no message body. However this gives me "The current request for action on controller type is ambiguous between the following action methods" and lists both overloads.
What is the best way to get this to route correctly? If I got to my controller method with a null ViewModel, I could return a 200/204 and probably be okay - but I don't get there, routing sends back a 404.
Solved this. CORS requires 2 things, you need all responses to include the Access-Control-Allow-Origin header, and you need to response to OPTIONS requests (either with a 200 or 204).
My OPTIONS requests were not routing correctly, returning a 404 with the Access-Control-Allow-Origin header, which caused the error but allowed the next request to work without an OPTIONS request.
I had to handle the OPTIONS requests in my Global.asax.cs

Backbone Collection.fetch() when after session timeout

I have an ASP.NET MVC4 sub web application added in to an existing ASP.NET WebForm web site. the whole website is using forms authentication.
In my MVC4 client side, I use Backbone.js for building the application, and the client application is most likely a SPA.
Everything works fine, but after session timeout my application does not redirect to log-in page.
I tried the error callback on Collection.fetch method, it was triggered (which is good) when trying to fetch after session time out.
However, the response status code is 200 (OK) with response content is the log-in page content.
So, my question is, in error handler how do I know whether the callback is triggered by session timeout or any other unexpected error?
If determined, how should I do to let Backbone redirect page to log-in page while referring current page?
Here is something what Phil Haack had blogged about
Exceprts from the post :
Possible Solutions
I’m going to cover a few possible solutions I’ve seen around the web and then present the one that I prefer. It’s not that these other solutions are wrong, but they are only correct in some cases.
Remove Forms Authentication
If you don’t need FormsAuth, one simple solution is to remove the forms authentication module as this post suggests. This is a great solution if you’re sole purpose is to use ASP.NET to host a Web API service and you don’t need forms authentication. But it’s not a great solution if your app is both a web application and a web service.
Register an HttpModule to convert Redirects to 401
This blog post suggests registering an HTTP Module that converts any 302 request to a 401. There are two problems with this approach. The first is that it breaks the case where the redirect is legitimate and not the result of FormsAuth. The second is that it requires manual configuration of an HttpModule.
Install-Package MembershipService.Mvc
My colleague, Steve Sanderson, has an even better approach with his MembershipService.Mvc and MembershipService.WebForms NuGet packages. These packages expose ASP.NET Membership as a service that you can call from multiple devices.
Some more info from comment of this blog
We had the same problem. But what we did, was to hook to AuthenticateRequest (just like you did) and we also checked the request to see if it's ajax or not (again, just like what you did). But at this point, we simply returned a JSON like {location: 'http://www.domain.com/path-to-login-page'} and we simply ended response in that method with HTTP code 200. This way, jQuery still gets a JSON result. But if the result has a "location" property, we simply do a client-side redirect to login page. That's our way and it works like a charm.

Considering authentication when using Ajax with Spring MVC

I am trying to use ajax in my spring mvc application. When I try a url (post/get) which is secured and needs authentication, the response is the html of login page as it is redirected behind the scenes.
What is the best approach to overcome this issue?
First, I would avoid displaying Ajax links to URLs needing authentication if the user is not authenticated, if possible.
If not always possible, your login page could be returned with a specific HTTP response code, (or any other way to distinguish it from a normal response) and your JavaScript callback could replace the entire body of the current page with the HTML received if this response code is received. Most AJAX libraries come with a way to define a handler to all the AJAX requests. Such a global handler could be used here.
The login page could also be adapted to only return a status code in case of an AJAX request, and the JavaScript code would then redirect to the login page (without using AJAX) if this status code is received.
I may not have explained the issue well. So I did not get the right response. However the response from JB Nizet contained some other points. So thank you.
I could solve the issue after coming back to this issue after some time, so
I posted about this on my blog.
I hope it is useful.

Resources