PRIYANK SINHA
PRIYANK SINHA

Reputation: 111

JAX-RS security and Authentication

I am developing REST webService , and some of my client will use my webservices , so for identify the genuine client , I have decided to give them a unique Application Token to each genuine client . The client will encode this Token and they will put this Token in Request header and I have configure a REST filter in my REST webservices to verify Token . I dont want to use https . My problem is that any one can take that Token from my client site and can consume my REST webservices . How I can stop this ?

Upvotes: 0

Views: 1033

Answers (3)

Sunil Namdev
Sunil Namdev

Reputation: 11

Use the checksum to secure the messages as below

MD5 or SHA1 checksum should be used to validate a password without passing the actual password.

The server sends a random string to the client.
The client appends his password to the random string, and returns an MD5/SHA1 sum of the result to the server.
On the server, do the same and compare the MD5/SHA1 sums.
If both MD5/SHA1 are identicals then the password is good and message is not changed.

Upvotes: 0

Mathieu Fortin
Mathieu Fortin

Reputation: 1048

Since you dont want to use https, I assume confidentiality is not an issue here, and that you only want to authorize requests based on who is making them. Instead of passing a plain token, which could get stolen, you should ask your clients to sign their requests. You have a good explanation over here:

In short, and taken from Implementing HMAC authentication for REST API with Spring Security:

  1. Client and server share a secret access key and a public access key.
  2. Client create a request that contains three fundamental elements: the public key header (in plain text), a date header, a signature string calculated hashing some data of the request with the secret access key. This hash usually contains the http method, the uri path, the value of the date header (for reply attacks), all the content of the request (for POST and PUT methods) and the content type.
  3. Client send the request to the server.
  4. Server read the public key header and use it to retrieve the corresponding private access key.
  5. Server use the private access key to calculate the signature in the same way as the client did.
  6. Server check if the just-calculated signature matches with the one sent by the client.
  7. (OPTIONAL) To prevent reply attacks, server checks that the value in the date header is within an acceptable limit (usually between 5 and 15 minutes to account clock discrepancy). The value cannot be manipulated by malicious attacker because the date it's used as part of the signature. If someone change the date header, the server will calculated a different signature of that calculated by the client, so step 6 will fail.

This logic can be implemented using any programming language. Following is a pseudo-code signature example in java:

//clientId is the public client identifier
//secretKey is the key shared between server and client
//requestContent is a string representation of the HTTP request (HTTP verb, body, etc.

//init signing key and mac
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);

//sign the request content
byte[] rawHmac = mac.doFinal(requestContent.getBytes());

//encode to base64
String result = base64(rawHmac);

//store in header
request.setHeader("Authorization", "MyAPI " + clientId + ":" + result);

On the server side, when you receive that request, you extract the clientId and signature from the header, retrieve the secret key corresponding to the clientId received, re-compute the signature (exactly as above) and compare the results. It it matches client is authorized, if not you return an HTTP 403 (or whatever error you want).


There is then no more "secrets" to steal for a potential man in the middle, BUT there are still keys that need to be securely stored on both the clients and the server. Leaking those keys will compromise the whole system.

Upvotes: 1

Bhisham Balani
Bhisham Balani

Reputation: 228

As token cannot be securely transmitted on HTTP layer one can easily get this token. You can ask genuine client to encrypt this token by combining some logic having timestamp so that every time token is encrypted using some different algorithm and on server side you should follow similar algorithm to decrypt it. This way even if someone get hold of token that can't be reused. One way is to club this encryption logic with Google Authenticator. (http://www.techrepublic.com/blog/google-in-the-enterprise/use-google-authenticator-to-securely-login-to-non-google-sites/)

Upvotes: 0

Related Questions