I have below scenarios.
My controller check that user has proper rights and then redirect him on proper action.
All action have ChildActionOnly attribute, because these action can't be invoke directly by URL. (only user with proper rights can call invoke action)
Each action return View with special button. This button can call critical action.
In the picture I illustrate it (link is below)
http://s23.postimg.org/fmndgt5p7/mvc.jpg
My question is how can I call DeleteData Action after click a special button? and I don't want have ability to call DeleteData Action directly via URL and I don't want check user rights second time.
I don't want have ability to call DeleteData Action directly via URL
So, you want to send brain waves to the server? How will the server ever get the message to do the delete operation?
I don't want check user rights second time.
The fact of the matter is you are making another round trip to the server, so you must check user rights again, at least if you want to have any measure of security.
MVC doesn't provide any magic. It still depends on the stateless HTTP protocol to function. So everything that it does must communicate over that protocol. You can get fancy and make calls via AJAX so there aren't so many page loads, but every interaction with the server must make a complete round trip (request and response) to the server. There is no way to avoid that.
Sounds like you are already hiding the button if they do not have permissions to delete but you would need to check the permission again when making the delete request since it would be a new request.
Delete actions should be restricted to POST only.
Why shouldn't data be modified on an HTTP GET request?
You would need to expose the delete action via a URL that only responds to POST and it would need to verify permissions again since it's a new request to the server.
It could be done with an ajax request or (Post/Redirect/Get)
http://en.wikipedia.org/wiki/Post/Redirect/Get
A (Post/Redirect/Get) is shown below and prevents the user from clicking refresh and submitting the request again and it will not be in the browsers back history.
[HttpPost]
public ActionResult DeleteSomething(int entityId){
//Delete object then redirect back to original page
return RedirectToAction("Index")
}
Related
I am using a complex template for my new ASP.NET Core application. Now I wanted to create a new controller which receives a POST request from another external server. That didn't work. I tried a lot until I found out that there is a mechanism set up which only allows POST request to access my controller which have a certain header (X-XSRF-TOKEN). This is done to prevent a Cross-Site-Request-Forgery attack.
However one specific controller should allow such requests, because this controller is not used from the webpage visitors browser. Is there a way to annotate the controller or any other way to allow this exception?
I finally found the answer and it is indeed possible by using an annotation. Just annotate your controller or action with [IgnoreAntiforgeryTokenAttribute] and the whole XSRF mechanism won't bother your controller any more.
Note that even if you don't intend to use that controller action from a browser, if it can be accessed via http, it may easily be susceptible to CSRF. An attacker may still for example create a rogue webpage, which if visited by one of your users, makes the user send a request to that action. If session management is cookie-based or equivalent and the action changes server state, it would still be an exploitable vulnerability.
So while you can turn of CSRF protection, you need to consider consequences carefully.
I have this Confirm method in my Account controller to which I redirect the users to when they click the link I've sent them to their email to activate their account. The returned view displays a message whether the activation has succeeded or not.
The problem is that if the user types in the url .../account/confirm/... they would also be able to see this view (this view should be available only for people who have received an email with the link).
Is there any way to specify that this method must be called only from a link?
There is no such thing as "called from a link". Someone typing in the URL, copy-pasting the URL from the mail or directly clicking the link in the mail all end up exactly the same in your controller.
The only difference would be a link clicked from an HTTP (not HTTPS) page, where sometimes the referrer is set. You shouldn't rely on that though, as it is user-supplied and can thus be modified by the user. Certain browser settings or plugins disable the referrer altogether.
Add a token to the URL and check that. If it's not present or invalid, display a 404 or whatever you want.
I've got an Asp.net MVC action that creates user account(after input validation). And a View containing registration form that invokes this action. While action validates input, user is left with webbrowser waiting for server response and click submit button a few more times. This creates several accounts. Is there a way to prvent user from form resubmition without javascript. I cannot use javascript in this project it is intended for non javascript browsers. Or can you suggest(server) other solution?
EDIT:
This form request use POST method
JavaScript is not allowed because this Web Application is aimed for special web browsers for people with disabilities that do not support javascript
You have to handle the situation on the server-side then, there's no way around that.
There are 3 options that come to my mind atm:
create a cookie and for each submit check if it exists
similar, but using a session object
before creating a new account, always check if the user exists in the database. THIS should be a no-brainer anyway!
You can add a unique hidden token as part of the form. This token can also be saved as part of the session on the server.
When the user posts the form on the first action, the token is validated and a flag set to indicate the request is being processed. The action processed and results presented. If, while awaiting results, the user attempts to repost the request, the token validation fails as the request is still being processed.
On a side node, the main reason people continuously click is that there is no feed back on whether the request was received by the server or not. To this affect, it might be better to redirect the user to an interim page that shows the request is being processed. Which in conjunction with the above can be used to show the request progress and redirect to the appropriate page when completed.
Of-course, you should also consider making the process a bit lighter. So, that the system can respond quickly to input rather than making the user wait.
Is it a requirement to use MVC? I think you can accomplish something similar using WebForms. When the user submit the request, in the code behind you can disabled the submit button like this:
btnSubmit.Enabled = false;
But if MVC is a must be, #walther answer would be correct
I have a put and post method in controller that when they work, they would normally redirect to the get method. But I noticed that using the redirect process in MVC is slower than just returning the call of the get method.
Sample from MS code:
return RedirectToRoute("someRoute", routeVarWithId);
What I found that takes less time:
return Get(Id);
Since my put, post, and get, all return IHttpActonResult, I don't see why I should use the redirect if the call is within my one controller, and the security rights are the same.
Am I missing anything obvious here?
But I noticed that using the redirect process in MVC is slower than just returning the call of the get method.
Of course it is; there are now two requests.
Am I missing anything obvious here?
Imagine I submit a form as a POST request to order a new computer from your website. Instead of returning a redirect to my order page, it just renders it out. Then my cat jumps on the keyboard and hits CTRL+R (refresh). What happens? My browser resubmits the last request, which was the POST. Now I've ordered two computers!
Instead, after successfully processing the POST request, you should return a redirect to the order page, which my browser will fetch with a GET. Now I can refresh to my heart's content and nothing bad will ever happen.
This also gives the user the ability to bookmark the page or email it to my wife. You can't email links that are POST requests.
For some light reading on the topic, refer to the HTTP/1.1 standard, specifically section 9.5 and following:
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
So when a POST creates a new resource, like an Order, it should return a 201 Created redirect to the URL where the new resource (i.e. the order) can be retrieved.
Nearly every page of our application has several filters on it. My current goal is to implement a mechanism to store the filters and preselect them when a user re-opens a page, so at least during one session user don't have select them over and over again when he's opening a page, or moving from page to page.
The application is written with ASP.NEt MVC and we use a lot of javascript to handle filtering. At the moment a lot of filtering is done only on the client side(for example, the complete data for the grid is retrieved and all further filtering is made only on the client).
I was thinking of these steps:
Base class for the controllers: Method1 takes data send by the method from the common.js and saves it in the Session.
common JS: to common.js add a method, which accepts a selection made by a user, and together with the name of the control and name of the page sends it to the server Method1 in order to store new selection in the Session object.
Base class for the controllers: Method2 accepts name of the controller, name of the page and retrieves Session object.
JS of individual pages: in the onload event specifying all existing filters and getting data from the Method2.
However, I'm not sure that this solution is universal and optimal.
And I don't want to reinvent the wheel. Is there any already existing solutions or patterns for this task? Or any ideas how this can be done better?
One of the way that comes to my mind is using of Cookies rather than the session as it just the section and you can read the cookies from the JavaScript itself. it will save the server resource as you will not save anything in the Session. If your selection criteria is not very sensitive , there should not be any security issue