What's the correct response to unauthorized HTTP request? - asp.net-mvc

I am writing web application I am not sure what is the correct response to unauthorized request. For user it is convenient when server response with 302 and redirects him to login page. However somewhere deep inside I feel that 401 is more correct. I am also little afraid if the 302 cannot be misinterpreted by search engines.
So how do you response to your unauthorized requests?
Edit
I am using ASP.NET MVC. This is not important from theoretical point of view. However ASP.NET form authentication use 302 approach.
I also like the behavior when user is redirected after successful login to the page he was requested. I am not sure if this can be implemented with 401 approach easily.

I think the correct response is entirely dependent on the context of the request. In a web application intended for human (not machine) consumption, I prefer to either redirect to login if the user is not authenticated and render an error page if the user is authenticated, but not authorized. I won't typically return an unauthorized response as it contains too little information for the typical user to help them use the application.
For a web service, I would probably use the unauthorized response. Since it is typically consumed by a program on the other end, there is no need to provide a descriptive error message or redirection. The developer using the service should be able to discern the correct changes to make to their code to use the service properly -- assuming I've done a good job of documenting interface usage with examples.
As for search engines, a properly constructed robots.txt file is probably more useful in restricting it to public pages.

401 seems grammatically correct, however a 401 is actually a statement presented back to the browser to ask for credentials - the browser would then expect to check the WWW-Authenticate header so that it could challenge the user to enter the correct details.
To quote the spec.
The request requires user
authentication. The response MUST
include a WWW-Authenticate header
field (section 14.47) containing a
challenge applicable to the requested
resource. The client MAY repeat the
request with a suitable Authorization
header field (section 14.8). If the
request already included Authorization
credentials, then the 401 response
indicates that authorization has been
refused for those credentials. If the
401 response contains the same
challenge as the prior response, and
the user agent has already attempted
authentication at least once, then the
user SHOULD be presented the entity
that was given in the response, since
that entity might include relevant
diagnostic information. HTTP access
authentication is explained in "HTTP
Authentication: Basic and Digest
Access Authentication" [43].
If you do a 302 you at least guarantee that the user will be directed to a page where they can log in if non-standard log in is being used. I wouldn't care much what search engines and the like think about 401's.

Send a 401 response, and include a login form on the page you return with it. (i.e. don't just include a link to the login page, include the whole form right there.)

I have to agree with you that the 401 result is actually the correct response.
That said why not have a custom 401 page which is well designed and shows the unauthorised message as well as a link to the login page, which you could have a 15 second javascript countdown to automatically send them there.
This way you give the correct 401 response to a bot which is told that the page is restricted but a real user gets redirected after being told that they are accessing a secured resource.

Don't bother about the search engines if your site is mainly used by humans. The ideal approach when a user reaches a protected page is to redirect them to a login page, so that they can be forwarded to the protected page after successful login.
You cannot accomplish that with a 401-error, unless you are planning to include a login form in the error page. From the usability point of view, the first case (302) is more reasonable.
Besides, you could write code to redirect humans to your login page, and search engines to 401.

How are the search engines going to be indexing the secured pages in the first place? Unauthorized users, such as bots, shouldn't be getting that far in the first place IMHO.

Related

How to handle unauthorized accesses gracefully in backend?

I have a Ruby on Rails application which redirects users to the start or login page if they end up at a resource they are not authorized for.
For that, it redirects through a 302 Found.
This does not feel right to me, as for example a successful creation of a resource via POST also returns a 302, with the only difference being that it redirects to the created resource.
On the other hand, it does not seem possible to redirect a user without returning a 30X status code (401/403 in this case).
Am I missing something here, or am I already doing it correctly and this is just the way to go?
Well I'd say that it depends of the context, for an API I'd go for you way, if the user is trying to reach an endpoint without authentication or without enough permissions, I'd return a 401 or 403 respectively.
But for a web application without a separated frontend app, you've no choice to tell to the browser where it has to go next and the only way of doing this is to use redirections (that are only 3xx HTTP codes => https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages).

Azure Logic Apps 302 Error MVC Authentication

I am trying to create my very first Azure Logic App that simply makes a http post request every hour to a website that has MVC ASP authentication. Whilst setting up the http Logic App action I am using the Basic option to enter the user details.
When it is run, the Logic App keeps failing and returning a 302 (redirect) error; I guess this is because the http post is getting redirected to the account login page.
I have run a test by carrying out a Logic App action to run a http post on a url from the same site that doesn't require user authorisation and it works.
I have also read that I may be able to add configuration to the Logic App action using the Run After rules, but for some reason this option is disabled for my action.
I'd appreciate it if someone with any knowledge in this area, could provide some possible direction.
Thanks.

How to protect against CSRF

How can I protect my website against Cross-Site Request Forgery attack?
I am visiting a "normal" website. (f.e. normal.php)
In the background it loads another website (f.e. victim.php/send_comment) where I'm already logged in.
The website fills the comment boxes of the victim.php with JS and automatically send the request.
In the web I always find the trick to use tokens against CSRF. But in this example, the website normal.php will get the token, when it loads the other website.
Am I misunderstanding how the token works? If not, how can i prevent my site from accepting this request?
The whole idea of CSRF is that you can't get victim.php/send_comment without a token from a previous page you've visited.
You form a "chain" of requests from your initial login until you get there, where each request is authorized by the previous one - unless you intercept the login page, there should be no way to forge requests.
The easiest and safest way of doing this is just using a web framework that handles CSRF for you. Doing it by hand is probably unnecessary and error-prone.

ASP.Net MVC: Lock JSON Requests to within a site by HTTP_REFERER

Suppose I have an ASP.Net MVC site. How do I lock controller methods (perhaps with an Attribute on the Action) so that HTTP_REFERER must point to my site?
To expand:
I have many JSON actions on my Controllers that are marked [Authorize], to prevent an uncookied* user from getting in.
Someone sneaky builds an attacker webpage and emails it to a user logged-in to my site. That page includes a script that fetches from my JSON Controller action. That causes the user's browser to send a logged-in cookie to my authorized controller method, getting that user's data back to the attacker's webpage, which they can then read and pass elsewhere.
If I could just lock these requests so that HTTP_REFERER must point to my site, a cross-site attack to request the JSON would be prevented. What's the simplest way?
Note that I obviously don't want to lock all requests, JSON, Authorized, or no - people still need to be able to link to the site. But no Authorized JSON request should ever be accessible from anything but pages on our site.
*Yes I made this word up.

How to detect if the user of a Silverlight app is logged into server?

I'm looking for a good clean solution to detecting whether a user has been logged out of an ASP.NET MVC application from Silverlight when performing a web request.
The problem is that the website has a Silverlight component that the user could potentially spend a large part of his time in, thus letting him get logged out of the website. Some of the actions in the Silverlight component triggers a web request to the server (using WebClient), generally getting a JSON result. But if the user has been logged out, the result I get is the HTML for the login page of the system (As the request is redirected).
I could check if the response is a valid JSON result, but if I need to introduce other response types later this will fail. I can also begin parsing the response stream to see if it contains elements from the login page but this seems very inelegant and fragile. Perhaps configure MVC somehow to respond to requests from a specific source by returning a know error response.
EDIT
Using Fiddler I found out that I could look for the 302 response code of the HTTP request. However, it turns out that you can't derive from the WebClient class in Silverlight, so I couldn't easily get to the status code. I considered using the WebRequest class instead but it seems a bit too low level for what I want to do. My current solution is to parse the first line of the response stream.
If you are using forms authentication with cookies, you could try to check to see if the cookie is present.
The following link shows how to access cookies in SL:
http://msdn.microsoft.com/en-us/library/dd920298(VS.95).aspx

Resources