I am working on a REST system, and am about to start developing a way in which a user authenticates in order to use the service. After researching hashing methods, I have read WikiPedia - Basic Authentication
However I have some questions about implementation. If I understand correctly, the username and password will be encoded into base 64 and sent in to the server. This is where my confusion lies.
Once the server receives such a request, I assume I must decide the base64 and check it against the hash. However, once this is done, I don't understand what must be done to verify the user for future requests.
Must I check this base64 sent on every communication? I don't want to save the base64 on the server to prevent against having to check the password every time because this would defeat the purpose of only having hashed passwords. In addition, my service is SSL only, so is there any down side to passing in the username and password as a parameter in the rest request as a means of authentication, instead of in http headers?
Basic auth is just a standard way to send username and password from a client via HTTP to a server. It doesn't define whether to use underlying SSL, or whether this is the first of several calls.
What I want to say: you can decide.
However, REST is meant to be stateless, thus you should rather send it every time you connect to the server, instead of creating some kind of session.
The advantage of basic auth over REST-params is, that the former is part of almost every web-framework (e.g. Java EE, Spring Security). While the latter will add the extra params to all your requests and needing you to check it every time yourself.
Related
My Java app server is about to integrate with a RESTful web service and will be polling it for content (JSON) to display to my users.
My users login with their usernames/passwords, which I must then hash + salt and then forward on to the web service with each call. The web service takes the hashed/salted login info and authenticates it (again, each call).
Assuming that I can't change anything on the web service end, and that the webservice expects hashed/salted login credentials as input parameters (along with the API endpoint, HTTP body, etc.), what are some security measures I can take on the client-side to keep the user-supplied username/password safe.
The worst thing I could probably do is just keep them in memory. What are my other options?
The main question is "against what do you want protection". Your user already know they username and passwords, so you can consider that keeping them client side is mostly secure (at least, you don't need to protect those credentials against the user). The salted + hashed password can be used as credential against the web service, so they have the same value as a username / password. Your user already send its password to your server, so implicitly, it already trust your server.
Conclusion : keeping hashes directly in memory is fairly safe in this context.
To limit risk, you should probably not store this hash in permanent storage (database, file on disk, ...).
If you want to ensure that your application stay stateless, it is not a bad idea to store this hash on the client itself (in a cookie). We might argue that this reduce the security somewhat, as it is opens the hash to client side attacks as well.
What's the real problem here ?
The real problem, is that the client needs to trust your server, so you need to take the burden of ensuring that trust is kept. That's why solutions like OpenId are interesting : they limit the trust given to a third party.
I'm trying to build a soap service based on JAX-WS (using JBoss AS 7.1.1) and I need to implement security as well. The data is going to be sensitive, so it will be over HTTPS. However, I need to identify the client, and make sure that only they can perform operations for their organization.
From the looks of it, all I have seen on the JBoss documentation (and other JAX-WS providers documentation) indicates that multiple .xml files need to be edited (some at the app server layer).
I'm really looking for a way that I could just have a class in my service called with the SOAP headers, and I could perform the validation/authentication/authorization there. Would really appreciate someone being able to point me in the right direction.
You can always send authentication data explicitly along with the request (user and password, for example, in addition to the normal arguments). You have to make sure that the connection is encrypted.
You can refine this by using public/private keys: So first the server sends its public key, the client encrypts the user/password with that public key, and the server can decrypt it using its private key. As this might be too expensive on a request basis, the server could issue a token for a certain time which the client can send in the following requests (so a token is a means to establish a session).
That being said, and I know how cumbersome JBoss security setup is sometimes, you have to implement and test it very carefully, otherwise you might open some security holes (tokens may leak, sessions might be captured, token invalidation, SSL connection is terminated in web server, clear text passsword remains in RAM and is paged out on the disk etc.).
What is the value of using a authentication token when using a REST webservice instead of sending a username, password over HTTPS/Encryption each time you make a request?
I understand that for instance OAUTH has some benefits cause you don't need to give away your password to 3rd parties, you can pass a token to trusted 3rd parties whom you dont want to share the username/password..etc
But other than this special benefits above which I certainly dont need in my case, why would I use tokens instead of sending username/password everytime.
This might be to make life easy for client, and it does not have to send the username/password everytime. Well ok but then now client has to remember my token and send me the token on every request. So instead of remembering/sending username/password now it will do the same for tokens! So client implementation code does not get any less.
So what is the real value here?
It really depends on the scenario - it's hard to tell without knowing more about the API - but usage of "authentication tokens" is far from universal, you're right that many APIs don't need (and don't use) them. Many APIs simply require an API key to be sent with every request (often via HTTPS to prevent it from being intercepted), or require an API key to identify the user and also a digital signature with a "secret key" to prove the user's identity (see When working with most APIs, why do they require two types of authentication, namely a key and a secret? ).
Usernames/passwords are not often used in public APIs because they're not flexible enough and do not provide enough "separation" between the user identity and the application identity. E.g. you register as a developer to use the Flickr API and create an iPhone app that uses that API - would you really want your developer username/password to be built into the app? What if you change your password later? What if you want to develop 5 apps and track usage for them separately and be able to shut off any app at any time without affecting the others?
However, for cases where you truly want to identify a human user only, not an appplication (e.g. a private API back-end that will only serve your own applications, not a public API), in most scenarios I don't see anything wrong with what you suggested, i.e. username/password over HTTPS with every request. Oh, by the way, auth tokens have the added advantage of being "restrictable" (can expire at a certain time, can be restricted to certain actions only, etc), but obviously this is only useful in very specific scenarios.
ALSO: As user "Dan" pointed out above, when designing an API that requires sending the username/password with every request (or with any request really, even if it's just the login request), be careful how you do it. If you're using a technique which browsers support by default (e.g. HTTP Basic Auth), you're preventing yourself from ever exposing the API safely to cross-domain users (i.e. most likely your API can never be safely called directly from the browser, i.e. from AJAX / Flash / Silverlight code).
This is a complex topic which can't be explained fully here, but just remember that if your API is relying on any security credentials that the browser can remember and then "silently" inject in every request (e.g. HTTP Basic Auth, cookies), then it's NOT safe to enable cross-domain access to that API using any cross-domain technique (CORS, JSONP, crossdomain.xml, etc).
The best way I can answer this is to point you to this page describing REST security. It belongs to the restlet wiki, not to Jersey, but it can be applied to Jersey as well as they are both REST implementations.
This is extracted from the link I provided:
"For the most resistance, the server can present the client with an application level authorization token, an opaque value that the server can verify belongs to the right authenticated user.
Such a token should be be difficult for a third party to calculate, e.g. a server-salted MD5 or SHA1 hash of the user's identification credential.
To defeat XSRF, this application-level token needs to be transmitted by means that the user-agent does not automatically return with each request. For example, it can be sent in the HTML of a form as a hidden field, and returned via POST in the encoded form entity."
I am in the middle of developing a PHP social media web application which will be supported by various web services each operating a REST API. Web services will probably be implemented in Java with MySQL data layer but the whole point of what I am trying to do is make it really easy to implement modules in different languages/data stores depending on what is approriate.
So for example when the user logs into the application via a login form the PHP code connects to a web service and POSTs the username and password to check if they should be authenticated. I would normally at this point start a session and store it in a session data store.
Another example could be if a user sends a private message to another user. The message would be POSTed to the private messaging web service which would take care of all the storage. Similarly the web service could be contacted to retrieve messages for a user.
Although I understand how to implement the REST web service in Java and make the connection to it in PHP I am totally unsure as to how to secure the data being passed and make sure that it is the users data being returned. If for example I want to get all of user As private messages how does the web service know to return that users. I could pass that users identifier as part of the GET url but then surely any old user could just figure out the GET url and use it to look up other peoples messages. I thought maybe I could pass over the session identifier and IP address which would allow me to check the session data store and make sure it is the correct user?
To secure the data that is important - like the username/password I thought I would just pass it over SSL.
Hope this explains my problem better.
Thanks
Take a look at HTTP Digest authentication. Most clients should support it, and it means the auth details can be passed securely with each request as part of the headers without interfering with the payload of the request itself.
I think requiring OAuth is a good choice. Your end users should appreciate that other websites don't need to ask usernames and passwords to access their data. As far as SSL, it's clearly worth doing if you can. You'll have to see if the performance trade-off is acceptable.
Keep in mind that your api must mimic the HTTP protocol.
Http is stateless, and by adding any Sessions or so, you're trying to fake an "Alwaysconnected" method.
With a LoginForm, it's like I'll have to send two requests for each calls ;)
These are basically 2 questions.
When privacy is a concern I'd go for the safest option: Serve data over SSL (via HTTPS).
As far as authentication is concerned, there are several possibilities. Basic over SSL is one of them, but a simple login form with a cookie can be another one. (ASP.Net Forms Authentication for example.) This all depends on how you want to implement your authentication mechanism.
I've created a RESTful server app that sits and services requests at useful URLs such as www.site.com/get/someinfo. It's built in Spring.
However, these accesses are password protected. I'm now building a client app that will connect to this RESTful app and request data via a URL. How can I pass the credentials across? Currently, it just pops up the user/password box to the user, but I want the user to be able to type the username and password into a box on the client app, and have the client app give the credentials to the RESTful app when it requests data. The client is built using Struts.
Cheers
EDIT - I don't think I made the question clear enough. I'm already forcing HTTPS, my question is more, in-code, when I'm requesting data from www.site.com/get/someinfo, how do I pass my credentials alongside making the request?
You more or less have 3 choices:
HTTP Auth
Roll your own protocol, ideally HMAC challenge/response based
OAuth
OAuth is currently susceptible to a variation of a phishing attack, one that is largely undetectable to the target. As such I wouldn't recommend it until the protocol is modified.
OAuth should also be a lesson about how difficult it is to design secure protocols, and so I'm hesitant to reccomend the roll your own route.
That leaves HTTP auth, which is likely best if you can use it.
All that said, almost everything on the internet uses form based authentication, and many don't even bother with https for transport level security, so perhaps simply sending the password text in the clear is "good enough" for your purposes. Even still I'd encourage using https, as that at least reduces the dangers to a man in the middle attack.
If you can add HTTP headers to your requests you can just add the Authorization header:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where you're using basic authentication and the QWxhZGRpbjpvcGVuIHNlc2FtZQ== bit is "username:password" base64 encoded (without the quotes). RFC 2617
Well, https has nothing to do with authentication, it's just transport-level encryption.
if you interact with an HTTP api, be it that it's https or not, and the dialog box pops up, it means its using HTTP authentication, either basic or digest. If your client instantiates an http client to read data from those "services", then you can pass those credentials when you instantiate the object.
If you use client-side script, XmlHttpRequest supports http authentication as well.
So in terms of code, how you pass the credentials to the RESTful services is dependent on the http client you're using (the object you instantiate to retrieve the data). You can simply collect such a username / password yourself from the client, and use it to call the other service.
look at existing solutions. In this case, oauth