5

I am developing a REST API with Java using Jersey and what is the best way of securing it? I looked at various things from password based authentication, Servlet Context , and I heard about tokenization and so on. But what is the industry standard way to secure it and make sure nobody can get data from a GET request by just typing the URL in browser, simply make a POST calll from PostMan and so on? Any learning materials on implementing this best way?

In simple English, what i am asking is, how can I secure my REST API by making sure the API is accesible only to our app?. The method of doing it can be anything from password to token. I am learning it now trying to implement it, but before I need to know what to learn, because I am looking for the best practice and industry standard way of doing so.

PeakGen
  • 21,894
  • 86
  • 261
  • 463
  • It is pretty unclear what your question is. Which form of token to use (JWT, UUID, ...)? Which form of passing the token to use: header, cookie or param? How to implement authentication/authorization in Jersey? Or what? – user3707125 Mar 09 '17 at 12:36
  • @user3707125: I am asking how can I secure my REST API by making sure the API is accesible only to our app. The method of doing it can be anything what you mentioned. I am learning it now trying to implement it, but before I need to know what to learn. – PeakGen Mar 09 '17 at 12:47
  • "the API is accesible only to our app" - it's impossible, because a client can monitor communication with server, and imitate it. In web you usually design your back-end with an understanding that the front-end is another app, and when thinking about security you keep in mind that the app would be not yours. – user3707125 Mar 09 '17 at 12:52
  • I know, I just made that statement to make clear of what I am looking for. It didn't mean only we can access it, it means we can access because we have prmission to do so. How do you authorise and secure your REST API? – PeakGen Mar 09 '17 at 12:54
  • After authentication client obtains a token, by which roles can be determined. For consecutive requests user passes token as a header. In Jersey I have a filter (?) (don't really remember the term) that will reject/pass requests depending on user's role and request's path. – user3707125 Mar 09 '17 at 13:28
  • How do you authenticate? Basic username -password authentication? Also how the REST API know about this Random token and TO whom kr belong to? Regarding the authentication, you do it everytime with a request or only once and then when session expires or something? Our mobile app is fully based on this API so lot of calls up and down. – PeakGen Mar 09 '17 at 13:56
  • If you use JWT, then token contains roles already, otherwise you need to implement some custom approach. Authenticate once, authorize everytime (that's why you pass the header). – user3707125 Mar 09 '17 at 14:12
  • @user3707125: `ContainerRequestFilter` ? I think that is a good idea. Maybe this is the way to go? - http://stackoverflow.com/questions/29766673/custom-jax-rs-authorization-using-jwt-in-each-request – PeakGen Mar 16 '17 at 04:48

1 Answers1

5

Here is pretty good place to start to secure your API:

  1. Use HTTPS
  2. Use username/password for authentication
  3. When user successfully logs in, you generate a token for them
  4. Assign the token to that user (easy way is to save it in a DB)
  5. Require the user to send that token with every request
  6. Validate the token before responding to any request

That being said there are some concerns. You should research how to achieve these:

  • Store credentials in your DB in an encrypted form in case your DB is compromised.

  • If you store your tokens in a DB, validation requires a DB lookup, will that be an issue, are you expecting heavy load?

  • If you use a stateless authentication, for example a JWT then how do you revoke access if you need to. (Hint: look into access+refresh token scheme + a blacklist)

  • How do you transport your token(s), header, cookie?

  • Protect your API from cross site scripting(a.k.a. XSS) and cross site request forgery(a.k.a. CSRF or XSRF).

NOTE: these are just some quick thoughts off the top of my head, you can find a lot of information about these online.

Norbert Bicsi
  • 1,562
  • 2
  • 19
  • 33
  • Thanks. I was googling and it said oAuth2 is the best? Maybe it does everything we talk about? – PeakGen Mar 09 '17 at 14:56
  • OAuth2 is not very friendly but yeah, it is good if you can implement it. You Could look into out of the box solutions like Auth0 or Stormpath. – Norbert Bicsi Mar 09 '17 at 15:03
  • Your explanation is really clear. I have few questions. 1. By "Use username/password for authentication" you mean allow the user to login to the app using his credentials? Like a FB user login to Facebook by rypomg username,password? – PeakGen Mar 09 '17 at 15:30
  • Yes, logging the user in with username and password is the most straight forward way of doing auth. – Norbert Bicsi Mar 10 '17 at 08:32
  • O.K., so this is normal user login to application using his credentials he made at application sign up , I thought some sort of hard codes password. I have more questions. – PeakGen Mar 10 '17 at 17:53
  • 2. The token is a random generated string right? It should expire after sometime? When saving it in a DB, you create a table, save user id in one column and token in another? 3. From the mobile phone's side, how do you send this token to server? Via REST header? 4. When it comes to validation of token, what you do is get the user ID and token from the REST request, search the `token` table and see whether the token assigned to that particular user matches with the token came with the REST call right? 5. Any security requirements to follow when creating this token? – PeakGen Mar 10 '17 at 18:08
  • You should consider JWT instead of a random token. – Norbert Bicsi Mar 12 '17 at 14:00
  • Thanks. I read about it, it seems I don't have to store this token anywhere in server (because it is stateless) but it will validate what it receives anyway?? I actually went through this - https://github.com/auth0/java-jwt – PeakGen Mar 14 '17 at 12:46
  • Yes a JWT is stateless and you can validate it without saving a copy. Drawback is it will be a valid token until the timestamp you attached to it expires. Now the question is how do you log out a user? Or how do you invalidate that token if you need to? – Norbert Bicsi Mar 15 '17 at 07:06
  • 1) `Token invalidation` - Maybe set a short expiry time? Like 2 days? 2) `Logout` - Not sure, any help please? – PeakGen Mar 16 '17 at 04:45
  • Other issue I am facing now is adding the `java-jwt` project into my `netbeans web project` because that GitHub project is marven based! – PeakGen Mar 16 '17 at 05:20