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.
Related
I am starting to work on an authentication system for an angular 2 Single Page Application using django-rest framework as back-end. I'd also like to have some kind of "remember me" functionality that is going to keep users logged in for a certain amount of time.
From what I have read so far, it seems that the best authentication method for this kind of Angular 2 SPA/REST API is using jwt (json web token). For jwt authentication, I looked at the django-rest-framework-jwt (https://github.com/GetBlimp/django-rest-framework-jwt).
The problem that I see is that the token needs to have a short life span (few minutes to a few hours...) in order to minimize security issues if the token get stolen. The token now needs to be refreshed frequently to avoid the user from being disconnected while using the application. In this case, a "remember me" functionality is posing problem since the token have a short life span.
I thought about a solution involving a second token that would serve as a refresh token. It would be opaque, have a longer life span and would contain information specific to the user (ip address or something like that) so that if it get stolen, the information specific to the user being different would render this refresh token invalid.
So here are my questions:
1- I would like to know if they are existing solutions addressing this problem. As any security/authentication issues, I prefer to rely on well tested solutions to avoid getting my API compromised.
2- Would the refresh token based on specific user infos be a good idea?
3- Any other ideas how I could implement what I want?
For your situation, you really need a way to store issued tokens.
I always use an OAuth2.0 server setup that manages the auth and returns tokens the OAuth setup uses a database to manage everything so it's easy to manage and revoke tokens.
The database schema would be like this http://imgur.com/a/oRbP2 the problem with using just JWT without any management over the issued tokens with long expiration you have that security issue of not being able to revoke easily.
I would advise against including any such thing as a password in the JWT and requiring them to change it what if they use that password everywhere, then they would have to change that everywhere.
Updated from comments
Sessions Authentication use session_id which most the time is stored in a cookie and this is attached to every outgoing request. It is stateful. It is nothing more than a unique identifier that associates a user account that the server has in memory/database. For example, this can course problems when running multiple servers/instances when scaling your infrastructure.
Token Authentication no session is persisted on the server so this means it is stateless. It normally uses the header Authorization: Bearer REPLACE-WITH-TOKEN . This means that this token can be passed to multiple different servers/instances because the authentication is not limited to the server that you initiated the authentication on. This helps with scaling your infrastructure. Tokens can also be passed to other clients.
RESTful API's are stateless so there must not be a session state stored on the server. Instead, it must the handled entirely by the client so that's why token authentication is used.
I had the exact problem when trying to use JWT with an application that needed a lot more than JWT was designed for. OAuth2.0 has a lot more options that I believe are necessary to meet your requirement in the safest manner possible and even features that you may find very useful in the future as your Application may grow and need more features with regards authentication.
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
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
I want to develop a REST API. REST guidelines specify that the state mustn't be stored on the server side.
But the REST methods I want to implement imply user connection management. In order to respect the statelessness, do I need to give the user credentials in each REST method request ? I find that quite inefficient... Isn't there an other more effective way ??
Statelessness is one of the main constrains of a REST architecture, as can be read in the original publication:
5.1.3 Stateless
We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
So for the credentials you mentioned, you should provide them in each call separately (i.e. Basic Auth + SSL). Of course, this is were "the real world" comes in, and applications start to differ. You might also use OAuth, fixed tokens, etc. but remember that you're then weakening the "RESTfulness" of your API.
Authenticating on every request does not necessarily require passing the username and password on every request. Some systems will take the user name and password, verify it and then create some kind of security token that can be passed on every request instead.
The idea is that the token should be quicker to authenticate than doing a full username password check. Obviously depending on how sophisticated the token generation and verification is you may be opening other security holes but you have to decide how critical that is.
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