Why should I use HTTP basic authentication instead of username and password post parameters? - basic-authentication

I have an API endpoint https://www.example.com/api/authentication which takes username and password as input and returns an authentication token.
In terms of passing username and password, I have two options (at least), namely:
HTTP Basic Authentication (which passes credentials as part of HTTP headers)
HTTP POST parameters
I understand that neither method provides encryption (hence the use of HTTPS/SSL). I also understand why using HTTP GET is is a Bad Idea.
Is there any real difference (aside from the fact that basic authentication feels more idiomatic) between the two methods?

The difference is that basic authentication is a well specified challenge/response scheme that all browsers understand and it is the server that starts it by telling a client that it requires (basic) authentication for a realm. This triggers the browser to show a popup to the user to enter a name/password which it then passes in the headers as you described.
In your second example you have to do all that in your own customized way and create your own login form for the user (etc).
If you deduct this process to the single step of passing the username/password from the client to the server I have to agree that there isn't that much difference but basic authentication implies a bit more than just that.

HTTP Basic authentication implementation is the simplest technique for enforcing access controls to web resources because it doesn't require cookies, session identifiers, or login pages; rather, HTTP Basic authentication uses standard fields in the HTTP header, obviating the need for handshakes.

Related

How to add login credentials to URL

I tried https://myserver.com/~username=username&password=mypassword but it doesn't work.
Can you confirm that it's possible to pass the user/pass via HTTPs parameters (GET or POST)?
Basically, I want to access this link https://www.globalnorm.net/gn/doc.php?name=ASTM%20F%202638:2012-00&erx=0 (but I need to authenticate ) How can pass my username and password in URL?
The standard method to pass basic authentication to web servers is to use a url of the form:
http://user:password#domain.com/
Web servers do not expect basic authentication in the query parameters. You can, of course, implement your own authentication using query parameters / HTTP headers or any other method.
Update
The specific URL you had supplied redirects to https://www.globalnorm.net/login.php?ecd=S&info=nosessionorcookie&doc=....
The login path does not return the header WWW-Authenticate which is used to indicate that basic authentication is supported. So no point in trying HTTP basic authentication.
This specific login page seems to expect a POST request to /login.php with USR, PAS parameters. The answer will probably include a cookie which is later used to authenticate with the server.
There seems to be some controversy about whether or not browsers have dropped the feature, and/or whether the feature is deprecated. But unless your browser has in fact dropped the feature, then as noted in #nimrodm's answer above, you can specify a url with basic authentication as
http://user:password#domain.com/
However, you really should not use http protocol, since that will send the credentials in clear text. Instead, just use:
https://user:password#domain.com/
Note that you must urlencode special characters in the user or password fields (I frequently use '#' in my passwords, so those must be written as '%40').
The browser extracts the credentials, and passes them to the server in an Authorization header:
Authorization: Basic credentials
where the credentials are simply the (url-decoded) string "username:password" as written in the url, but base64-encoded. But since the https connection is encrypted, the header is encrypted and the credentials are not exposed outside the browser.
I think the whole issue about removing support or deprecating the feature was based on the security implications of specifying the credentials using http protocol. But with the availability of free ssl certificates, and the push for "ssl everywhere", that no longer seems like much of a problem these days.
Of course there's also the issue of how much good passing credentials this way does you. Many or most applications that require login expect to get the credentials from a form the user fills out and sends with a POST request. The application would have to be written to check each request for an Authorization header, and if present, process the credentials the same way they would if they had been specified by a POST of a filled-out login form.
Applications that expect HTTP basic authentication generally are built with that requirement built into the server configuration, e.g. using Apache directives along theses lines:
<Directory "/htdocs/protected">
AuthName "Registered User"
AuthType Basic
AuthUserFile /lib/protected.users
require valid-user
</Directory>
Where the file /lib/protected.users is a file of encrypted usernames and passwords generated by the Apache utility program htpasswd. With this configuration, any request for resources below /htdocs/protected is automatically checked by Apache for an Authentication header. If the request has no such header, or the credentials specified in the header do not match one of the pairs of usernames and passwords in /lib/protected.users, then the server responds with a 401 Unauthorized status and a header:
WWW-Authenticate Basic realm="Registered User"
Note that the realm value "Registered User" is the AuthName value from the Apache configuration. The browser handles this response by displaying a prompt requesting username and password, with the value of the realm contained in the prompt to give the user a hint as to what particular username and password is required.
Browsers have to treat the credentials specially anyway to convert them to an Authorization header, and so they also cache them and send them each time with requests to the same endpoint, like sending cookies. If they didn't do this, then the user would have to supply them on each subsequent url specifying that endpoint to avoid getting prompted.
Hope this helps.
The web server doesn't care about anything past the "?". This data gets sent to the application.
If you're actually authenticating to the application you would need to check the app's documentation for the correct parameter names.
In the past, you could supply the username:password#domain in the URL, but this has been disabled in many recent browsers because of security risks.
Currently, the only way I'm aware of to do an auto login is to set a basic auth header and do a form post, however you'll be better off to use a library that already knows how to do it, since the fields need to be encoded properly to work.
If I am correct in my assessment, the question is Can you confirm that it's possible to pass the user/pass via HTTPs parameters (GET or POST)?
Here is a snippet of code that I am using to send username and password as parameters to a GET call. Hope it helps.
$('#button').click(function () {
var username = $('#username').val();
var password = $('#password').val();
window.location.href = '#Url.Action("DesiredAction")?username=' + username + '&password=' + password;
});

RESTful best practice for authentication

and thank all of you for viewing this question.
I am not sure to on how do this so i am asking for the community help on this matter.
I read int his post Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant" that sessions are not "completely" advised on the REST convention, and that all authentication should be made using HTTP Basic authentication or Digest.
Ok, so far i get it.
But has far has i know, basic authentication is made on the actual server against a regular non-encrypted text file.
Would it be going against the convention, putting the username/password in the http request parameters, instead of passing them down trough the headers and letting the web server do the authentication?
This way, for every request made, the user/pass parameters would be checked and managed using my own logic. I mean using a database table, that has all the info necessary for the application.
The method I currently use is the first request is for a auth token via a POST method, which contains Headers of Username and Password, these are then verified against my authentication methods. If the credentials are valid, I return a time limited token. All subsequent requests must have the auth token as a header, which is checked and if valid access is allowed. I maintain the list of valid token in code and expire them as required. This is faster than having to validate the username & password on each call and is slightly safer than the username & password being passed in with each call as a token could be stolen, but it is only valid for a small period of time.
All of this this must be run under SSL otherwise the data is not secure and users credentials can be read.
Basic auth is handled by the server however the server chooses to handle it. There certainly doesn't have to be a plaintext file containing usernames and passwords! My current client stores passwords in a 1-way salted hash in their database. On an incoming request, the plaintext password is pulled from the header, salted, hashed, and them compared to the database value.
Putting a password in a request parameter is a really bad idea. What happens when a user copies and pastes a URL to email to their coworker?

Asp.NET WebAPI custom authorization

I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.

Backbone HTTP basic rest api authentication

I am using Backbone.js and it communicates with a stateless rest API. Some calls require authentication, through HTTP basic.
What I don't understand is, somehow I have to authenticate each request, how could I do this securely? My first thought was to have a cookie, store the username and password but this would be vulnerable?
Can this be done securely?
There are two themes to this question. One is about security and one seems to be about REST rules.
The way to do authentication securely, is to pass that data through an SSL connection. It's the only way to securely transfer data over the wire.
With regards to sending authentication using basic auth over each request (REST), not many people I know do this in reality.
There's always a big long discussion on how much security is enough security and it really depends on your application and what the purpose is. I know this isn't the definitive answer you might be looking for but I'll just give you my take and how I'm going about dealing with the issues you mention.
With RESTful apps, the story is one should authenticate each request but in real practice I find this is more a "guide" than a hard rule. Rare is the fully RESTful application that follows all the rules. I use an encrypted cookie to store the user session data with a standard authentication flow that happens once and expires in a week. Data transfers happen through SSL to prevent MITM attacks and a modified Backbone sync sends a CSRF token along with each POST, PUT, DELETE to prevent cross site request forgeries. Probably "good enough" for the social app that I am working on. Maybe not if you're doing bank wire transfers and stuff. Hope this sort of gives you a point of reference in judging what you might want to do.
Is https://github.com/fiznool/backbone.basicauth something you'd find useful?
This plugin enables access to remote resources which are protected by HTTP Basic Authentication through your Backbone Models and Collections.
How does it work?
A resource protected with HTTP Basic Authentication requires the following HTTP header to be set on every request:
Authorization: Basic
The access token is formed by taking the username and password, concatenating together with a : separator and encoding into Base64.
This plugin handles the Base64 encoding and automatically sets the Authorization header on every request which uses Backbone.sync.

Why does PayPal use HTTP Request Headers for its API authentication?

I'm just reading Paypal's API documentation, e.g. Adaptive Accounts API
My question: What's the reason/advantage of using (custom?) HTTP Request Headers for authentication instead of "normal" POST/GET (or even COOKIE) variables?
In the mentioned example PayPal uses the following HTTP Request Headers:
X-PAYPAL-SECURITY-USERID
X-PAYPAL-SECURITY-PASSWORD
X-PAYPAL-SECURITY-SIGNATURE
X-PAYPAL-APPLICATION-ID
X-PAYPAL-DEVICE-IPADDRESS
X-PAYPAL-REQUEST-DATA-FORMAT
Why use HTTP headers rather than something in the body of the request?
By keeping your authentication info separate from the payload (the data you are transmitting) you make it easier to handle authentication at an earlier stage in the request pipeline. For example, a gatekeeper server can receive requests and authenticate them by looking only at the headers, and then pass them along to the module/server/class that does parses the request body and does the real work.
If the request fails authentication, it can be rejected before it even gets near the code that deals with the money.
Of course, you can architect your system this way no matter what, but keeping it in the headers means you don't need to parse the request body or even look at it. You also don't need to worry about adjusting Content-Length: if you wanted to modify the headers before passing it along to another server.
Why use custom HTTP headers rather than WWW-Authenticate or Cookie?
I think this is simply because PayPal wants a more robust scheme than either of these can accommodate. WWW-Authenticate only allows for basic (cleartext) and digest (MD5) authentication, and many better schemes have been developed since the spec for these was written. They also don't allow for more than a username and password.
Cookies are technically opaque bits of data that you receive from a server and pass back to it unchanged. Again, they could tell you how to generate the info that you pass along in a Cookie header, but that wouldn't really be following the spec, so at that point, why not just use some custom headers?
The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication", look here.
User agents are advised to take special care in parsing the WWW-Authenticate field value as it might contain more than one challenge, or if more than one WWW-Authenticate header field is provided, the contents of a challenge itself can contain a comma-separated list of authentication parameters.
If the connection is trusted between two parties and SSL is implemented, HTTP Authentication is a simple to implement way to authenticate between two fixed parties. The connection is simply rejected at the traffic level if the authentication fails.
I don't think Paypal uses HTTP Authentication for payments? It's just for you to access API features to build your own admin interface for Paypal accounts?

Resources