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
Related
I am writing an android app that connects to my server with a POST request. So far, I am using SHA-256 to hash and salt epoch time and use that as a third parameter alongside the username and password to make sure that the authentication is done from the app. However, an attacker could decompile the apk and figure out the salt that I am adding to epoch time, allowing them to make a POST request from wherever.
I am wondering if there is a way to make sure the POST request is being made from my app. Note that I cannot change the authentication method of the server from POST.
Thanks in advance.
HTTP Client authentication is an open process to allow vendors to implement different authentication schemes.
Apart from SSL (when run under HTTP protocol) having is own authentication mechanism (for servers and/or clients) the authentication task on HTTP protocol is managed by the WWW-Authenticate header in the HTTP header protocol. That field reflects if the server demands some kind of authentication and how the peer is going to be authenticated.
This allows peer protocol authentication (not only for the client, but also the server can be authenticated) but it makes HTTP method agnostic, as the authentication procedure is orthogonal to the method used to request information. You can use authentication with any (or all) the http methods (GET, POST, CONNECT, HEAD, PUT, DELETE, etc)
You need to read the RFC's docs: 7230, 7231, 7232, 7233, 7234 and 7235.
The more interesting to you is 7234 (it describes protocol authentication), and the documentation of the web server you are requesting to, and how the service has been configured, to get an idea of the authentication methods it supports or the credentials you must provide to authenticate the client.
Normally, the process is as follows:
the client makes a unauthenticated request of info for the target url.
The server denies the request, signalling authentication must be used, and proposes an authentication method and challenge.
The client redoes the request, but providing the requested credentials from the server.
The server accepts the request or denies it again.
To note is that, depending on the authentication method to use (e.g. BASIC is a simple username/password scheme, while DIGEST forces the user to produce a digest, based on used credentials and some server provided info) you can need more than one roundtrip to the server (the server can force you, while not common, to use two of these in chain to grant you access to the resources)
In the case of Java, probably a good source of documentation is the Apache HttpClient class, and it has some tutorials from Apache that show you how to make authenticated requests. A good reference is this.
I'm writing a mobile app that communicates to a remote Java service via REST. I have protected my (SpringBoot) web service with https protection (due to the nature of the data, it needs to be secure) but my question is about which user/password I use to secure the https calls.
Should the username and password I use in the https header be a service account that the client (mobile app) and Java service knows or should it be the public user's username and password? The easiest option is just to use a service account but this means the mobile app will have those details built into it and distributed publically (albeit in compiled form).
Going the other way and using the user's username and password means I'll have to have the logon REST endpoint open and unsecure (which is fine I guess), but it just makes it slightly more fiddly.
Good question, and I would reckon you to use token based authentication and authorization scheme. Firstly you should have a login page where client logs in by providing username and password which is authenticated by calling some remote login service which maintains it's own user store or may use an existing one in your organization if any. Upon a successful authentication, the auth service should provide the client with a valid token, which then be refreshed time to time. The mobile or web client should pass in the token to the downstream microservices when a request is sent and this token should be sent inside the Authorization HTTP header.
Exposing the username and password while passing it around the network normally not considered as a good solution and that's where token becomes handy too. Token is the normal procedure that people use to secure rest endpoints. Yous rest endpoint should intercept each and every request comes at it, passes the token to the auth provider and verifies that. If the token is valid it will allow the request otherwise it should deny it.
Security is a pretty much larger topic and you have X.509 certificates other than tokens to encrypt the data sent across the wire over https and so forth. I suggest you to take a look at the spring security documentation since that will be a good starting point. Spring Security gives lots of hooks for developers which can be used out of the box with some sensible defaults. You can use JWT style tokens, Oauth tokens and spring security supports all these different forms too.
we will have a website created by an outsourcing company, that website will send some information in JSON payload to our RESTful web service. The user will do login and authentication on that website, so we don't want to know the username and password of the user. And what we need is make sure the JSON where sent from is that trusted website then we will send back another JSON payload with including some info from us.
I am pretty new in the security area so I have googled a bit to find out we can use certification to encrytion/decrytion the message. But what will be the solution if we can identify the hack request in the first place and rejecting that request.
As of your description, there are coming two things in my mind immediately:
Use an SSL certificate. That already ensures that your
site is being transferred encrypted over the internet.
Use a token system. Tokens are widely used in payment solutions for example - as credit card data should never touch your own server. All tokens contain some secret information that are used to prove identity.
Use HTTP request headers eg. Basic Auth
For sure, you should have a SSL certificate. This adds already a lot of security to your site.
But what will be the solution if we can identify the hack request in the first place and rejecting that request.
Well, you have answered it yourself. If you can detect it, reject it.
A simple way to protect your restful service is something like basic auth. The application making the rest call would provide a request header like
Authorization: Basic ZWx1c3VhcmlvOnlsYWNsYXZlde
This would not be a user-based solution, but a webapp to webapp solution. All other requests would be unauthorized.
https://en.wikipedia.org/wiki/Basic_access_authentication
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."
The answer below is from this question;
The awarded answer doesn't actually address the question at all. It only mentions SSL in the context of data transfer and doesn't actually cover authentication.
You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs.
If you don't use TLS client authentication you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth or even HTTP Basic authentication (but over SSL only).
So considering I will use HTTPS without client certification
my question here is poster says if we dont use client SSL certification server does not really know whom its talking to. What I understand here is if I use a authentication-token to access to authenticate the client against the server. Then server does not know whom is sending the token even if that token is paired with a user id in my servers database.
First of all
1-is this a real problem? If I especialy use Https?(without TLS client authentication)
2- and most important, assuming that is an important security flaw; How can Http basic authentication help here as poster mentioned? Http basic authentication just sends encoded username password in a header. So when client receives a token (in return after he sends his username password) then for the rest of his requests he will use this token in this header instead of password, and everything is fine all of a sudden?
Still Server does not know from where the request is coming from, maybe server has a valid token with a matched user in its database but unknown who reallysend it.
(while I still see this very hard that the token would be stolen over https and used by someone else!)
Whenever I bring this subject I get replies.."Well..you send a token but server does not know whom send the token, not very secure" so I understand this as the browser keeps a sort of auth-certification and server knows where the request is coming from the right place THEN I can be sure that the paired user with that token (checked from my DB)is "really correct"
Or maybe what am telling here is not correct
[the] poster says if we dont use client SSL certification server does not really know whom its talking to.
That's not what I said :) This is what I said:
Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API.
alone being the key word here. Also:
If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth or even HTTP Basic authentication (but over SSL only).
In other words, TLS client authentication is one way of authenticating a REST API client. Because the original SO question was about SSL specifically, I was mentioning that TLS client authc is the only 'built in' form of authentication if you're relying on TLS alone. Therefore, if you're using TLS, and you don't leverage TLS client authc, you must use another form of authentication to authenticate your client.
There are many ways to authenticate REST Clients. TLS client authc is just one of them (the only 'built in' one for TLS and usually very secure). However, TLS is a network-level protocol and is perceived by most to be too complicated for many end-users to configure. So most REST API offerings opt for an easier-to-use application-level protocol like HTTP because it is easier for most to use (e.g. just set an HTTP header).
So, if you're going the HTTP header route, you have to use a header value to authenticate a REST client.
In HTTP authentication, you have a header, Authorization, and its value (the header name is rather unfortunate because it is usually used for authentication and not as often for access control, aka authorization). The Authorization header value is what is used by the server to perform authentication, and it is composed (usually) of three tokens
An HTTP authentication scheme name, followed by
white space (almost always a space character), followed by
The scheme-specific text value.
One common HTTP authentication Scheme is the Basic scheme, which is very... well... basic :). The scheme-specific text value is simply the following computed value:
String concatenated = username + ":" + raw_password;
String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());
So you might see a corresponding header look like this:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
The server knows how to parse the value. It says "Hey, I know the Basic scheme, so I'm going to take the trailing text value, base64 decode it, and then I'll have the username and submitted password. Then I can see if those values match what I have stored."
And that's essentially Basic authentication. Because this scheme in particular includes the submitted raw password base64 encoded, it is not considered secure unless you use a TLS connection. TLS guarantees (mostly) that prying eyes can't intercept the headers (e.g. via packet inspection) and see what the password is. This is why you should always use TLS with HTTP Basic authentication. Even in company intranet environments.
There are other even more secure HTTP Authentication schemes of course. An example is any scheme that that uses digest-based authentication.
Digest-based authentication schemes are better because their scheme text value does not contain the submitted password. Instead, a password-based-hash of certain data (often other header fields and values) is calculated and the result is put in the Authorization header value. The server calculates the same password-based-hash using the password it has stored locally. If the server's computed value matches the request's header value, the server can consider the request authenticated.
Here's why this technique is more secure: only a hash is transmitted - not the raw password itself. That means this technique can be used to authenticate requests even over clear-text (non TLS) connections (but you would only want to do this if the request data itself is not sensitive of course).
Some digest-based authentication schemes:
OAuth 1.0a, aka RFC 5849.
HTTP Digest Access authentication (used by browsers natively).
Amazon AWS's custom scheme.
Amazon's and others like it are more secure for REST than OAuth 1.0a because they always authenticate the entire request - including the request entity payload (i.e. all the stuff after the HTTP headers too). OAuth 1.0a only does this for application/x-www-form-urlencoded content which isn't relevant for REST APIs that use application/xml or application/json payloads (which are most REST APIs these days).
Interestingly, OAuth2 is not digest based - it uses something I consider less secure, called 'bearer tokens' (which are honestly fine in many scenarios but still not as good as the digest schemes used in banking, military, and government communication).
When we talk about "authenticating a user", what we really mean is "checking that the user knows something nobody else should know". That "something" might be a password, a certificate, a hardware security token or even the user's retinal pattern, but in all cases it's the access to that information that we're really checking, not the identity of the user (whatever that really means) as such.
The point is that, in principle, all these authenticators could be stolen and used to impersonate the user. A password could be logged, a certificate could be copied from the disk it's stored on, a hardware token could be stolen (and possibly reverse engineered and cloned) and even the user's retinal pattern could, in principle, be scanned, recorded and faked. the best we can do is, in each case, to try to make this as "very hard" as possible.
Maybe I'm misunderstanding the question.
The answer you have quoted says to me that if you don't use some form of authentication, whether it is client certificates, HTTP BASICAUTH, or something else, the server doesn't know with whom it is communicating.
(Maybe that's okay for your application, maybe it isn't, only you can answer that.)
Stated in other terms, if you do use some form of authentication, the server does know with whom it is communicating; it is communicating with the "person" to whom the authenticated credentials belong.
In this context, authentication is the process of establishing identity via some credentials.
Authentication does not guarantee that the credentials have not been stolen. SSL assures (I wouldn't go so far as to say it "guarantees") the credentials are secure in transit between client and server.
When you use GMail, you're using SSL, how does Google know it's talking to you?