How to authenticate a Lift REST web service client? - web-services

I am developing a REST web service with Scala and LIFT and nave hardly any good idea on how to authenticate a client. I was thinking about a standard HTTP authentication, but found out it is very insecure as it passes passwords over a network in b64-encoded plain text. So how do I better do it?

If you want authentication to be secure against being observed in transit, your only realistic option is HTTPS. Technically, there are key-exchange protocols like Diffie-Hellman, but they aren't widely supported.
But the problem of observing packets in flight is almost a nonexistent one. In a shared LAN, it is possible, though not necessarily easy, to use a tap like FireSheep -- but it typically would be easier and more effective to walk over to the guy's computer and install a key-logger.

Basic authentication will pass password and user name in (nearly) clear text. If you use digest authentication instead it will still be prone to man-in-the-middle eavesdropping, but you should be safer from password theft and session takeover. This chapter in Exploring Lift have some information about digest authentication in lift: http://exploring.liftweb.net/master/index-9.html

Related

Security about a simple REST web service

Here is my little API with two URL :
/api/location/list -> GET
/api/location/detail -> GET
I'm looking for a process to secure this service with authentication. For now, it can be accessed by only one user (me).
I think oAuth is too complex in my case and I found this resource for designing a simple API.
I understand the principle of private/public key and HMAC but I have a big concern about this :
Say my webservice is consumed by an ajax request with GET verb. I have something like /api/location/list?apikkey=userid&hash=abcde.
A end user can easily sniffed the network during the request (via a simple chrome console), capture full url and access directly to the service multiple times (I think it's a case of replay attacks).
Differents resources talk about timestamp or nonce to make a request unique but I'm a bit lost with implementation.
Any ideas ?
You can try JWToken auth specs, simpler than Oauth, but avoid authorization data as url parameter if possible and use Header's request instead.
If needed consider also ssl encryption at tcp level.
Perhaps you could try to use a token-based approach for security, as described in this blog post:
Implementing authentication with tokens for RESTful applications - https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
The idea is to authenticate to an authentication resource (that can be part of your application) to get temporary token that can be refreshed with a refresh token when expired.
With the use of HTTPS, it seems to be appropriate.
I think that it depends on the security level you expect. Signature-based authentication (the AWS approach) is great but is a bit complex to implement by hand.
Hope it helps you,
Thierry

How can I implement security in web service?

I have a REST service that is called by a mobile app; I need the user to login, then the service generates a unique token associated to user id and this pair of userId/token is passed to every subsequent call to the WS.
I don't like too much this solution because, even if very difficult, if I change the uid and get the right token I can "login" as another user, so I'm trying to understand which is the best practice to handle web service authentication for a mobile (and non) application.
Your issue is not with the methodology, but the fact your service is not checking the combination of UID and token, but rather the token. That is a programming issue, not a methodology issue.
How secure do you need the service to be? Are you talking top secret level of security? Banking? My soccer club site? For high levels of security, you can use digital certificates, but it makes for a much more complex provisioning methodology. But ... Even if you are going to change from UID/Token (or AppId, User, etc), you still need to fix the fact that correct token + wrong UID works. That is a mistake if two-form authentication is a must. Changing methods will solve nothing if you don't have the proper programming on the server side to avoid circumventing the system.
You may also want to look at how you provision the Token. Should this be offline, or is one REST sign up method acceptable. This leads back to the level of security your require.
You might want to forget the token/id solution and consider going the SSL/basic authentication route. SSL will provide the encryption and secure communication, but will not secure the access to your specific web-services on the server side.
For that you can try standard basic http user/password authentication on every call. This way you do not need to worry maintaining state through each REST call. Each call will have an explicit reference to the user. Yes, you will need to re-authenticate the user with each call which is a bit of a pain, but you can cache your results.
However, I am far from an expert on the subject.

Authentication for Both Webapplication and WebService

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.

Should services ask for credentials at each request?

I wonder what is the optimal authentication method for services and webservices:
user/password is sent on each request
user/password is sent once to obtain an authentication code that will be sent on each request
Is there any alternative? Which is better? Why?
Depends on the protocol.
If the service requests are in the clear (http), then you might want to consider a secure (https) logon transaction, which gains you a limited-time token to authorise future requests (a session cookie, in effect). Then at least eavesdroppers don't get credentials that work forever, just for a limited period.
Likewise even if the logon transaction isn't secure, at least if it only happens once it's slightly harder to eavesdrop. It's also slightly harder to use.
If you don't care about security, I wouldn't even use a username/password, just an API key. Amounts to the same thing, but if the user doesn't choose it then at least it won't be similar to any of their other passwords, so it doesn't affect anything else when it's stolen.
If you care about security sufficiently that everything is done over https, then it doesn't really make a lot of difference what identification mechanism you use, AFAIK. So do something simple.
Finally, you might care about the security of the authentication, but not about the secrecy of the requests themselves. So, you don't mind eavesdroppers seeing the data in flight, you just don't want them to be able to issue requests of their own (or spoof responses). In that case, you could sign the requests (and responses) using a public/private keypair or a shared secret with HMAC. That might (or might not) be easier to set up and lower bandwidth than SSL. Beware replay attacks.
By optimal are you thinking about performance ? I would suggest to send credentials and authenticate on each request unless you really find this to be a bottleneck. SSL is not enough at all, it only provides encryption and authentication of the web service. But think about client authentication (a client cert can help here) and authorisation, may be not all users of the web service is not allowed to call all methods and all methods calls needs to be logged for auditing. In this case the user identity needs to presented for each call.
I develop and maintain a SOA based core system web service developed in WCF that authenticates and authorises against .Net based clients using windows identity and uses 2-way certs authentication against Java clients and I have no performance problem.
Steve Jessop clarified things for me:
if the credentials are memorized I should provide a transient authentication cookie after they are received,
but if the credentials are digitally stored then I should only use an API key, because anyone who can access the credential storage wouldn't need to access the cookie

Web Services authentication - best practices?

We have SOAP web services in production that are relying on SOAP Headers (containing plain client credentials) for the authentication. The WS are used in heterogeneous environments with .NET/Java/PHP/Python/C++ clients both web app or desktop app.
We are considering a v2 for those WS and I am wondering what are considered as the best practices for WS SOAP authentication? (reasonably secure, yet easy to handle on a wide variety of platforms).
The easiest way to handle it across a variety of platforms is to use HTTP basic authentication and HTTPS for the transport layer. WS-Security would be good if your needs go beyond simple username/password but the support is going to vary quite a bit between platforms. HTTP authentication is supported by every decent SOAP implementation.
If you have to roll it all yourself and can't use HTTPS, I'd suggest the hash-based UsernameToken portion of WS-Security. It's pretty secure and fairly easy to implement as long as your libraries have the hashing functions.
If you're doing web services, I wouldn't rely on HTTP for authentication.
WS-Security as a whole is way too big.
The way I have tackled this in the past is to use the standard WS-* features.
Instead of using the authentication feature we set the message header integrity feature on. This requires both sides of the dialog have access to public/private key pair and detects any tampering of the username field in the header. So you can be sure whoever sent the message and set the user id has access to the private key.
This provides a reasonable level of integrity if the keys are managed properly.