Requesting partial view via ajax in forms authenticated application - ajax

I have an ASP.NET MVC application with forms authentication enabled. I'd like to request a partial view using ajax and load the resulting html into a div on my main view, but I want to make sure that the ajax request is an authenticated request.
Is passing the authentication cookie in the ajax request for the partial view common practice to validate such requests and if so how would one go about acquiring the authentication cookie while on the client and then sending it along with the ajax request?

You can just set the authentication-attribute on your action-method and it will be sent correctly:
[Authorize]
public ActionResult GetPartial(){
return PartialView();
}
It is common to just pass the cookie with an Ajax-call. From the server's point of view, an ajax-call is not different from any other call.

Related

Make ajax call to service which using Spring loginUrlAuthenticationEntryPoint

I have a web app with spring boot that uses loginUrlAuthenticationEntryPoint and restful service next to it.The Application serves to a one web page that uses thymeleaf which authenticate using sessions and a mobile app that uses basic authentication.So there is a cart items screen (html table ) in a restaurant page , i want to make those items deleted by clicking on them asynchronously(from database).But that page's security (page url) is handled by login-url-auth-entry-point , not rest auth security config.
So when ı make a ajax call to delete cart item url it returns 302.My ajax call don't authenticate and tries to redirect me to login page. I tried many things.
I tried using xhrFields{withCredentials:true} in ajax call-didn't worked.
I tried using setting Authorization field with document.cookie - document.cookie returns empty.
There is the controller i am trying to send request:
#ResponseBody
#PreAuthorize("hasRole('RESTAURANT') OR hasRole('ADMIN')")
#GetMapping("/flushitem/{id}")
public ResponseEntity<String> freeCartItem(#PathVariable("id") Long id) {
try {
cartService.deleteCart(id);
}catch(Exception e) {
e.printStackTrace();
}
return new ResponseEntity<>(HttpStatus.OK);
}
I also tried to delete #ResponseBody annotation and make a request with thymeleaf's th:href with a html link tags.It tries to redirect to somewhere even if my controller returns void.
So long story short, my question is , how should i make a ajax call in a web page which makes authentication by sessions ? Or can i make the functionality that i want without using ajax and rest controller function ?
Im not triying to make any cors related operation.(I guess)

Redirect user to Login page, from an jquery ajax request

Iam using custom Authorize filter to on my action method to check if user has an access to it.
If user does not have an access then user is redirected to Unauthorize page.
The problem iam facing here is iam using Jquery Ajax request to call that action method. Everything works well if the user has an access. But if the user does not have an access the code is not able to bind the View("Unauthorize") and it display the existing view on the browsers screen;
Any suggestions would be helpful.
Thanks.
The thing is that ajax requests can not send a redirect response. You can instead either return a status code that tells the calling javascript to redirect or simply change the Response.ContentType to application/javascript and use window.location = "newUri" as the response body.

How to handle session timeout in MVC3 in javascript?

In my application this is how we are dealing with the session timeout till now
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="20" />
</authentication>
Now I want to deal session time out on client side, something like this
<authentication mode="Forms">
<forms loginUrl="showPopup();" timeout="20" />
</authentication>
Is that possible, or any other suggested way to achieve this?
Edit
I visited to other questions of the same type but could not get any real help from them.
In my application this is how we are dealing with the session timeout till now
Great, that's the correct way to define forms authentication in web.config
Is that possible
No, sorry, putting javascript in the loginUrl attribute is meaningless.
or any other suggested way to achieve this
From what I understand you are trying to display the LogOn form using some javascript function if the session has expired.
You should distinguish between 2 types of request to your server:
Standard synchronous requests (anchors, forms, redirects, ...)
Asynchronous requests (AJAX - done by using javascript)
In both cases on the server side you should protected actions that require authentication by decorating them with the [Authorize] attribute. For example:
[Authorize]
public ActionResult SomeAction()
{
...
}
Once you have secured your server you could start thinking about how to handle forms authentication cookie expiration or simply the case of an anonymous user attempting to call this action.
For the first case of standard synchronous calls to the server, the forms authentication module will intercept the request and if the user is not authenticated or his session expired ASP.NET will automatically redirect you to the LogOn page you have defined in the loginUrl attribute. It will also pass as a ReturnUrl query string parameter to this action which will be pointing to the originally requested url by the user and for which he was not authorized yet. This parameter could then be used to redirect him back to this page once he has authenticated.
Now the second case is a bit more difficult because since ASP.NET automatically redirects the request to the LogOn page you have no way of knowing inside your AJAX success callback that the user is not authorized and the server redirected the request to the LogOn page. Phil Haack wrote an excellent article on how you could prevent this redirect for AJAX request. I invite you to read this article now.
Alright, now that you have read the article and have installed his NuGet (Install-Package AspNetHaack), assuming you are using jQuery for your AJAX requests, you could subscribe to the .ajaxComplete() global event handler. Inside this handler you could test the server response code and if it is 401 it means that the user was not authorized. So you could act accordingly:
<script type="text/javascript">
$(document).ajaxComplete(function(event, xhr, ajaxOptions) {
if (xhr.status == 401) {
// the AJAX request failed because either the user was not
// authenticated or his session expired. So here you could
// do whatever you want. For example you could redirect him
// to the loginUrl defined in your web.config file:
window.location.href = '#FormsAuthentication.LoginUrl';
// you also have the possibility to show this logon form
// inside a popup or render it inline inside the page,
// by sending an AJAX request to this action and retrieving the
// corresponding partial
}
});
</script>
This configuration area is to configure server side behaviour, that happens when the server tries to handle a request where the session has expired. It is the result of a client -> server request for a page. As the client is a web browser and is by design disconnected from the server, you would have to include the logic you require in each page (probably in the main layout template) and then make AJAX calls at repeating intervals to the server to ascertain the user's session time-out state. The pop-up would also be handled on the client.
This area of configuration probably isn't going to help you reach your goal, I'd just remove the <forms> element altogether and look at solving the problem using AJAX calls to the server.

Correct Event to check user authentication in BaseController class

I'm in the process of converting a web application of mine to an MVC application. I think it will benefit from it but I'm a newb and a half at MVC. I want all of my controllers to inherent from a base controller and the first thing I want to do is redirect the User to the Login view if they are not authenticated. The method already written basically looks for a Cookie and if it doesn't find it does a Response.Redirect() to the login screen. I want to move this method to the BaseController but I'm not positive what's the best way to go about it. So in essence what BaseController Event should I invoke to check for authentication before loading the page?
Thanks
The MVC way to handle this is to decorate controller actions with the AuthorizationAttribute.
When you mark an action method with AuthorizeAttribute, access to that action method is restricted to users who are both authenticated and authorized. If you mark a controller with the attribute, all action methods in the controller are restricted.
The Authorize attribute lets you indicate that authorization is restricted to predefined roles or to individual users. This gives you a high degree of control over who is authorized to view any page on the site.
If an unauthorized user tries to access a method that is marked with the Authorize attribute, the MVC framework returns a 401 HTTP status code. If the site is configured to use ASP.NET forms authentication, the 401 status code causes the browser to redirect the user to the login page.

ASP.NET MVC - Failed to load resource in Response.Redirect

I noticed if my session expired whilst on my site and then I clicked on an Ajax.ActionLink, the login page would be displayed in a PartialView. I've created an override of the OnActionExecuting method like so:
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
if (!ctx.HttpContext.User.Identity.IsAuthenticated)
{
if (ctx.RequestContext.HttpContext.Request.IsAjaxRequest())
{
//ctx.RequestContext.HttpContext.Response.RedirectToRoute(new { controller = "Account", action = "LogOn" });
ctx.RequestContext.HttpContext.Response.Redirect(Url.RouteUrl(new { controller = "Account", action = "LogOn" }));
}
}
}
This checks if the User is Authenticated and then if the request is an AjaxRequest. It will then redirect the user to the LogOn method in my Account controller if they're no longer authenticated for an Ajax actionlink. The problem is I get "Failed to load resource" in the console.
This checks if the User is Authenticated and then if the request is an
AjaxRequest. It will then redirect the user to the LogOn method in my
Account controller if they're no longer authenticated for an Ajax
actionlink
Yes, but if you configured your Ajax.ActionLink or Ajax.BeginForm to update some DOM element with the results of the AJAX request using the AjaxOptions, it doesn't really matter if you are redirecting on the server. The AJAX request will simply follow the redirect and insert the resulting HTML you redirected to (/Account/LogOn) inside the DOM element.
So redirecting from an AJAX request won't solve your problem. As you know the whole point of an AJAX request is to stay on the same page (the address bar never changes).
If you wanted to handle the authentication cookie expired condition in a proper way within your AJAX requests you will have to perform the redirect on the client (using window.location.href). In order to achieve that you may take a look at the following blog post in which Phil Haack exposes a great technique allowing your server to send a 401 HTTP status code in this case instead of redirecting. Then on the client you could intercept this code (by subscribing to a global AJAX handler for example) and redirect to the logon page from the client.

Resources