Authentication for Both Webapplication and WebService - web-services

I'm currently working on an application consisting both of a webapplication and client software. The client communicates via webservices, supporting both a SOAP and Protobuffer implementation.
The initial registration is done via the webapplication, which relies on username + password authentication later on.
After finishing the registration process, all features are also available via the client, which will only communicate via HTTPS. For authenticating webservice calls, I'm currently thinking about three possible approaches:
Including the username and password in every message. But is it really a good practice to include the credentials in every request, even though secured by HTTPS?
Providing the username and password in the first webservice request. The client then gets a token which is used for all future requests. (Note: It's not deemed acceptable to force the user to copy a server-generated token to the client application.) Only if the user revokes the token, he needs to send his username and password again for getting a new token. Such token based approaches seem to be quite common, for example Google, AWS and Rackspace are using them a lot. But does it really pay off in this scenario?
Hashing the password on the client sounds like a good solution. However I'd like to salt the encrypted passwords on the server-side. Adding requests only for fetching salts doesn't sound like an optimal solution or is it?
Are there any best practices or tips? I couldn't find too much information exactly for these requirements.
Currently I'd go with 2), but I'm not really convinced yet.
The project is based on Java, Apache CXF, Protobuffers and Shiro, but shouldn't have too much of an impact for the general question...

If you're only concerned by authentification and neither by confidentiality nor integrity, you can handle it by securing:
HTTP transport level, using HTTP BasicAuth (user+password on each message) + eventually HTTPS for confidentiality, however as you noticed (solution 1) it it is kind of old school and keeping user/password in local cache is not a big deal but cannot be advised.
Message level (the soap message) using Security Token for instance but I do not know Protobuffer
Application level (solution 2 and 3), that is the way Google, Amazon, Ebay and others are working. You will not ask the user to copy/paste his token, you will generate one from user/password
I would securing the application level using a token, since getting a salt from the server is almost like getting a token and does not add more security (a secured salt should be known from only you, and if channel is protected it mean getting the token from given password and username is secured as well).
A better but more complex solution would be usage of SSL certificates, available both in browser and client software.

Related

Advice how to implement a simple user login and authenication

We are in the process of building a simple Android application together with a simple back-end web server to allow the user to get some information form the server.
We need to login the user, to make sure he is authorized to view the data, but apart form that I do not think we have particular security concerns.
I need some advice on how we can implement the server to keep things as simple as possible.
For example, we could use something like this to make sure the user is authorized to see the data:
http://ourwebservice/user/password/viewsuchandsuchdata
Is that a good way of doing things?
Do you have any suggestions or comments?
There are many ways to secure web-services.
The simplest is possible "Basic Auth" (http://en.wikipedia.org/wiki/Basic_access_authentication). On every request, you send the user credentials in the "Authorization" HTTP header concatenated with ":" and base 64 encoded. To keep it safe, you need to make sure the connection to your web-server is using SSL (HTTPS), otherwise the user password could be intercepted.
Another "newer" solution is OAuth2, and in your case the "Resource Owner Credentials" flow. Instead of passing the user credentials on every request, you use them once to "exchange" them for a short-lived access token issued by your server. Then on any request to the web-service you pass that access token in lieu of authentication. The server must then verify that the token is valid and find out for which user it was issued. For more info see this article: http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified.
There are potentially many more "custom" ways of doing authentication...
Going the OAuth2 flow is probably more difficult but there are lots of open-source libraries out there to help you build a OAuth2 provider (http://oauth.net/2/). The advantage is that you don't have to store the user password on the device, which is safer (the less you touch passwords, the better).

How can I implement user authentication for ColdFusion Web Services called from a mobile application?

I am developing several Web Services that will be accessed by a mobile application. I have several requirements:
Each user will need to sign in with their own User ID and Password (the same User ID and Password they use to sign into the website).
Every Web Service request will need to be authenticated to ensure that the request is coming from the mobile app(s).
Every Web Service request will need to authenticate the user, since there is user-specific fucntionality built in, and access will need to be blocked if the user's account is disabled.
Let's assume that OAuth is not an option.
In order to ensure that Web Service requests are coming only from the mobile app(s), I am planning to use HTTP Basic Authentication in IIS (the mobile app(s) will need to have a User Account setup in Windows Server and the mobile app will need to store the User Name & Password and pass these in the header).
Next is the User Authentication for each Web Service request. Would it be suitable to encrypt the User ID, Password, and some shared secret key (a "pepper", of sort) with AES-256, pass that encrypted string as a parameter with each request (over HTTPS, of course), and then decrypt and parse it on the server to authenticate? This is the existing plan, but something just doesnt seem right about it - like it's not "secure enough".
What else can I do to properly authenticate users for Web Service requests?
I recently went through this problem and asked opinions from a group of senior people about how they solve the problem. Opinions were varied, but one consistent feeling is that your level of security depends on the use case of your application. Are you doing online banking or storing medical records? Then your security needs may be quite high. Social networking? Maybe not so much.
Basic Authentication is generally fine when encrypted over SSL, ColdFusion works well with it. If you use Basic Auth, make sure to encrypt your traffic with 1024-bit keys or better. Don't authenticate every request with username/password - that's unnecessary. Authenticate the first request, set a session token, and rely on the session token for your identification of users.
Set a polling mechanism from the client to the server to keep the session alive - set the session timeout to 30 minutes and the polling frequency at 25 minutes, for example. Otherwise you may need to re-authenticate expired sessions. Again, how you approach this part of the solution depends on your paranoia level, which depends on what kind of data/app you are dealing with.
Cookies, and therefore sessions, should work fine in iOS apps. If you use sessions to verify identity after authentication, make sure your session cookies are memory-only (set at the server level).
Check the SSL implementation of your server against the Qualysis SSL Test:
https://www.ssllabs.com/ssltest/
The report will give you a surprising amount of detail about the strength of your SSL implementation.
Lastly, consider implementing two-factor authentication to combat password theft.
If you ignore the SSL advice and plan on encrypting your password and communicating over an insecure channel, look at the Kerberos protocol for a well-known example of how to authenticate securely:
http://en.wikipedia.org/wiki/Kerberos_%28protocol%29
Yes, you can use Basic Authentication but that means the client will need to store the username/password in plain text, and also send them over in plain text. Sending part is sort of fine if it's under HTTPS, but storing username/password in plain text may not be a good idea, unless you're using some secure key store.
Let's assume you have decided that Basic Authentication is the way to go, and you want to make use of the official CF way of supporting that, then you can use CFLOGIN.name & CFLOGIN.password. You may also check out Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion. In the remote cfc side, always validate the username/password, or return some sort of token and asks the client to use that token going forward. The token can be cfid+cftoken if you like, or even roll your own that never expires. If you use cfid+cftoken, and send them over as cookie or in body along with your web service call, I believe you can resume the session if you so choose.

Repeat username/password authentication with each call to web service

I am creating a web service to expose to my mobile apps. I currently am implementing a token based authentication solution (because that what I have done in the past); however, I am struggling in this context to understand why I do not simply pass the username and password each time? I can maintain the password in RAM while running the Mobile app (encrypted between usages if we want to get overly complicated) and then pass it each time I connect to the server and repeat the hash verification each time. Of course everything is SSL so there is no more risk in terms of network transfer in doing it each time versus do it once is there? The only CON I see is that the hash validation process might me more expensive than a token validation - maybe. Are there other cons I am missing here?
There are a few reasons not to do this:
Every time you transmit the information, you open the risk of interception. (Even if that risk is mostly mitigated by using an encryption system such as SSL).
Passing a username / password combination on every request implies that you will be checking the combination of them on the server-side with every request. This usually requires an extra database hit and some logic which is unnecessary.
If you are passing credentialization such as this on every request, you will need to use SSL for every request - which is expensive overhead. It is much cheaper to send an encrypted authentication token back and forth in plain-text - which only the server-side can read.
This seems like a bit of a hot topic here on SO the last few days, as I've answered several questions about RESTful auth and such. I am providing below some links to those answers - which go much more in-depth. Perhaps if you take a look at the auth schemes I'm proposing - you'll see how it protects you more than simply sending username/password on each request.
Authentication in RESTful web services
Public facing Authentication mechanisms for REST

How do I implement login in a RESTful web service?

I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.

RESTful user authentication service

Hey folks, this seems to have been discussion fairly often but I want to make a simple, watered down question around doing authentication with RESTful services. The scenario is as follows:
There is a system that houses registered users for an application. The system exposes a RESTful API for accessing these users.
There is a front-end application that has a login form. The application can either be internal, or external.
The front-end application needs to use the data in the User system to authenticate a user.
The question now is how to authenticate a user whose credentials (username/password) are entered in the client application against the data in the User system such that it is secure and performant? For the sake of this question, suppose the client application is internal to some sort of Intranet but the applications will not reside on the same machine and may only communicate through the service.
I understand the idea of having the application being "hypermedia driven" but we should be able to provide filtering/searching services. For example, consider the resources and API as below:
http://example.com/users
GET - retrieves all users (paged, hypermedia driven)
POST - creates new user
PUT/DELETE not supported
http://example.com/users/[id]
GET - returns a full representation of a user with id = {id}
PUT - updates user, takes in any predefined media type
DELETE - deletes the user (with appropriate authorization)
POST not supported
Based on the above, my idea would be have the client application GET on the user listing, filtering by username. The service will return the hashed password and salt to the client, the client will perform the authentication.
Thoughts?
If I understand your question correctly, you are looking to implement a generic service that will handle authentication, so that you can re-use it for different applications.
I suggest you take a look at OAuth which has been built for precisely this problem domain.
Passing the username and the salt back is unnecessary and a real security risk.
Perhaps you could consider this approach:
Have the client pass the username and password to the server via Basic Authentication
The server fetches the encrypted password for the username along wiht the salt
The server encrypts the given password using some encryption method, using the salt to assist the algorithm (Ruby code follows):
def User.authenticate(login, password)
ok = false
user = User.find_by_login(login)
if user
#
# user contains the salt, it isn't passed from the client
#
expected_password = hash_password(password, user.salt)
ok = (user.password == expected_password)
end
return ok
end
There are multiple places to use this kind of approach but I like to do it in Rack.
Last point, do it all on a HTTPS connection
Stormpath
Stormpath company dedicated to providing a user login management API and service for developers. They use a REST JSON approach.
There are some other companies that seem to dabble in this new area of authentication-as-a-service, but Stormpath is the only one I know of that is dedicated to it.
First, you don't want the client to perform the authentication, as it then would be trivial to write a client that breaks into your service.
Instead, just use an authentication mechanism like HTTP Basic or HTTP Digest.
Note that if you're using Java, the Restlet framework provides interceptors, called Guards, which support these and other mechanisms. I highly recommend Restlet.
Mozilla Persona
Since this question was posted, the Mozilla Foundation (the maker of the Firefox browser) has taken on the problem of simple user authentication. Their solution is Mozilla Persona, "a sign-in system for the Web". Designed to be easy for users and for developers. The user's identity is an email address. See Wikipedia article.
Update
Mozilla has basically given up work on Persona but not quite killed the project.