What is the recommend workflow for doing web authentification (HTTP status codes)? - http

I'm writing a web application which requires a user login. As you might recognise there are many workflows for responding on invalid user credentials. Most browsers are captable of storing (accepted) user credentails in their credential storage.
My original question splits up into two parts:
Which HTTP status code should be send to the user if a site requires a logged in user? I don't mean the situation the user is requesting the login page by herself.
Which HTTP status code should be send to the user if he/she has entered invalid credentials?
HTTP 401 is only for the "old style" authentification via browser prompts I guess. I'm using my own login pages to get rid of those browser prompts.

There are many standards for the authentication. Couple of example you can find here:
http://docs.oracle.com/javaee/1.4/tutorial/doc/Security5.html
The error code 401 you described is used for the Basic Authentication. It is not old :).
When you use your own login form please follow the standard Form authentication flow:
If a user access a protected resource without an authentication redirect to a login page (HTTP code 302)
Show the login page (HTTP code 200). Submit a user name to a dedicated URL (generally it is j_security_check)
After a successful authentication redirect back to the original protected resource (HTTP code 302)
After a failed authentication show once again to the login page with the error code (HTTP code 200)
If a user access a protected resource after the authentication show the resource (HTTP code 200)
To distinguish between an authenticated and not an authenticated session you can use HTTP cookie.
It is recommended to use GUID and not any user information (e.g. user name).

401 Unauthorized / 407 Proxy Authentication Required are the only status codes that are relevant.
401 Unauthorized should only be presented if you are denying access to any resource - NOT if you are redirecting or presenting them with a login page.
407 is just like 401 except you are expecting auth to be handled by an external service and you expect to be provided with a Proxy-Authenticate header field.
More typically, you are presenting the user with a 200 OK and a login page.

Related

Asp.net mvc [Authorize] attribute will return http 302 instead of http 401 if the authorization fail

I have created a new asp.net mvc 5 web application and I use individual accounts (form authentication) authentication. this will build a full Account controller.
Then I created a new controller named People , and I add [Authorize] attribute before it as follow:-
[Authorize]
public class PeopleController : Controller
{
Then I try to directly access the controller without login, so I was redirected to the login page. But what I have noticed is that using IE F12 developer tool, the http status will be 302 and not 401 , although according to http standards if the request fail authentication then the application should return http 401, this what I get:-
Can anyone advice on this? I mean should any application be fully compliance with the http standards? Or there is no problem of redirecting users to login page if the user is not authenticated without raising an http 401 error (as the default asp.net mvc is doing)?
Thanks
Returning 302 or 401 http status code in this case depends on if you want to control what happens when the user is unauthorized from the server side or the client side. It also depends on whether the request you made was a full page submit or an AJAX request. AJAX style requests typically prefer 401 while full page submits prefer 302 redirection.
If you want handle the unauthorized case on the server side and redirect the user back to login page, then the common practice is to return a 302 redirection to that page.
If you want to handle this case on the client side, then you can have the request return 401. Then, you will have a 401 handler in the client which will detect it and do a client side redirect to the login page. 401 is also the way to do it if instead of redirection, you want to show a message on the same page that the user is no longer authorized.
You will see Web API Authorize attribute return 401 and MVC Authorize attribute do a 302 redirect.
302 is a pretty common way to do url redirection. It would be the url redirect that is causing the 302 rather than a 401 error. It indicates that it has moved you from /people/ back to /Account/Login in your case.

using http 401 Versus http 403 for unauthorized requests , which is more appropriate

I read a lot about using http 403 or http 401 for managing unauthorized requests.
I think that if my application uses one phase authentication then using http 403 is more appropriate. since the http 401 response definition indicates that authentication is required, so if a user is not loggin and he tries to access a page then the application should require a username/password. but if the user is authenticated and the application have only one phase authentication then returning 403 is the right code if the user is not authorized, since even if the user re-type his username and password ,, then nothing will chnage. but if my application requires two phase authentication ,for example to enter a second password then returning http 401 will be more appropriate. so can any one aivce ?

Handle OAuth2 authentication failure using Apigee proxy

I've written my own login app to protect my api following the oauth-login-app example.
I've implemented the web server flow and everything works great.
My question is: how should I handle an authentication failure at step 3? How do I tell he client app that the authentication failed? The user could either press the cancel button, or refuse permission or just enter the wrong details.
When you initiate OAuth 2.0 (dance) with
/authorize
the user-agent land on /login page (created/hosted by you),
post redirect.
enduser(user-agent) submits the username/password
to the page hosted by you. Here you collect the credentials and
submit to Apigee, and if authentication fails, send a HTTP 401
response. Now your application should be in position to re-render
the login page and with a flash "invalid credential".
Now coming to if user is authenticated but rejects the authorization request in
consent page, you should redirect to the "redirect_uri" provided
by client, with error code.
How do I tell he client app that the authentication failed?
The login app will redirect the control back to the application redirect URI - with added error code/description in the URL as hash parameters. In case of success the URL is appended with code or token.
You can do this redirect from your login app directly but I would suggest to make the redirect call first to an Apigee Proxy and let Apigee Proxy send the redirect back to app. Both in case of success and failure. In this way you will have the benefit of using Apigee analytics that helps your understand how many OAuths failed for what reason etc.
EDIT:
You can use the same GenerateAuthorizationCode proxy you have built for the success flow. When login fails or succeeds, in either case you need to pass that information to this proxy. Generally the login app and this proxy should share this information using a common session store. You can not pass this information just using a redirect parameter because that can be changed by the client user agent. When you redirect to the GenerateAuthorizationCode redirect proxy, do so by appending a random session ID in the URL. That id can be used by the GenerateAuthorizationCode proxy to look up the login status from the session store. Then you can either send back a redirect with error or a proper oauth code based on if the login was successful. An easy implementation of the session store can be done using a distributed caching resource in the apigee gateway. Login app can put/get the session using an internal API. While the proxy can use policies to retrieve the session information.

Nancy basic auth password change causes authentication to fail

I have created a self-hosting site using Nancy and Owin. I used Nancy.BasicAuthentication for authentication. Everything works fine until I change the current logged in user's password.
Once the password is changed, if the user creates a request then they are redirected to the 404 error page and the window pops up asking for a username and password.
How can I update the user's credentials after a password change to stop them from losing authentication?
Thanks!
a) Basic auth is very easy to listen in on - consider digest auth instead.
b) Both basic auth and digest auth work on a page by page basis - every request is authenticated individually (the browser just automates the authentication if it already has the credentials)
c) Hopefully a 401 Authentication Required, not a 404 Not Found is returned?
d) I suspect doing anything to allow a previously authenticated user to continue using a site after the password is changed (e.g. cookies) would require code changes to the authentication handler. You could for example set a cookie (crypto required) when a page is successfully authenticated, then not require authentication for further pages if the cookie is available (with a timeout on the cookie).

How do I send a 401 response from an HttpHandler?

We have a Login enforcement app which only allows a user to be logged into a single session in our app. This is done in the postauthenticate request event handler.
If the user needs to be logged out (they have another session) we do:
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
This has worked fine for a long time. Now we are adding a web api to our app. When you hit a web api Url the PostAuthentication event does fire, it sees the user has logged in elsewhere... however, it does a redirect to login.. well that's expected due to the code.
I attempted to change the code above to set the Response.StatusCode = 401 and then end the request. Well, that works fine, but asp.net is being "nice" and auto redirecting to the login page.
Is there a way I can respond with a 401 and not have it redirect to the login page if this request came from web api URL?
The problem is that the FormsAuthenticationModule catches all outbound requests at EndRequest and if the status is 401 AND the URL isn't the configured login location, you get redirected to the login location.
There's not any great way to fix that. Basically I've seen two ways, neither of which are awesome:
Implement your own FormsAuthenticationModule. Rather than use the out-of-the-box one, roll your own that knows about the exceptions and lets the 401 through.
Add some logic to the login page that issues the 401 for you. Look at the inbound URL. If the URL is one of the redirects from the FormsAuthenticationModule but the user is already logged in, issue a 401 rather than displaying the login form. The FormsAuthModule won't do a circular redirect to the login form, so you're OK.
You can set SuppressFormsAuthenticationRedirect of the HttpResponse to true and the FormsAuthentication module will not catch the 401.

Resources