Jax-rs rest webservice authentication and authorization

I have a web application that should allow users to use different web clients (browser, their own mobile application, etc.) for registration. After logging in, they can access limited content or their own content (for example, the records they create, etc.).

What I have done so far: I created the jax-rs rests web service (I place my application on a glass shawl) which provides the following methods:

  • register - POST user his desired username / password / email / etc; if the username / email address is unique, an entry for that user is created in the database (I use Hibernate to save)
  • login - POST username and password. If they are ok, a UUID is created and returned to the user (this will be used as a token for future requests). I have a table called logedusers, with user id, token, validSince as columns.

That's where it gets confusing for me.

Let's say that I have another getUserEntries method that should return all entries made by the user. To make this clearer, there will be an Entry table with the following fields: entryId, userId, text.

What is the best approach here?

What I am doing now, I make a request for receipt and pass the token as follows:

localhost:8080/myApp/getUserEntries?token=erf34c34

Subsequently, if the token is valid, I get the user ID from the logedusers table and based on this userId, I get all the entries and return them as json.

Something like that:

 @GET @Path("getUserEntries") @Produces(MediaType.APPLICATION_JSON) public Response getUserEntries(@QueryParam("token") String token) { String userId=getUserIdFromToken(token); if (userId == null){ return Response.status(Response.Status.UNAUTHORIZED).build(); } else { //get some data associated with that userId, put it in the response object and send it back return Response.ok().entity(response).build(); } } 

However, what happens if I have more methods that provide data if called by a valid user?

I need to do this check at the beginning of each method.

I want to make this authorization process transparent

So, two main questions:

  • Is this design good? All authentication with a user / password, the server creates and saves and sends the token to the user, the user sends the token in future requests.
  • What should I do if I have many endpoints that should determine the identity of the caller? Can I mark them with some annotations, use some kind of security provider / authenticator (where I can add my own logic for verification - for example, verify that there is no token token no older than 5 days, etc.).

thanks

+7
source share
1 answer

Is the design good? All authentication with a user / password, the server creates and saves and sends the token to the user, the user sends the token to future requests.

This is somewhat OK. The conceptual level is not so bad (provided that you are in order with self-registration in general), but the interface needs a lot of customization. Although yes, the POST for registering and logging in is correct, for the rest of your webapp you must pull the authentication information out of context, if you need it, and use role-based access control at the method level where you can.

Please note that your container has a built-in authentication and authorization mechanism. Use them.

What should I do if I have many endpoints that should determine the identity of the caller? Can I mark them with some annotations, use some kind of security provider / authenticator (where I can add my own logic for verification - for example, to check if a token is not more than 5 days old, etc.).

Do they need identification? Or do they just need to know that the user is allowed access to them? If the last, easiest way is to put the appropriate @RolesAllowed annotation on this method with which (with the appropriate configuration, see JEE5 security docs ). If the first one, you need to get the HttpServletRequest object for the current action and call its getUserPrincipal() method to get the user ID (or null if they are not already logged in). This SO question describes how to get a request object; There are several possible ways to do this, but I recommend injection using the @Resource annotation.

What I would not do is allow users to usually provide their identity through @QueryParam ; which is just wildly open to abuse. You can let them ask about other users in this way, but then you need to decide whether you will tell them something or not, based on whether the current user is allowed to know something about another user. This is a complex security issue that arises in a real application, and this is a good time to need a current verified user ID.

+2
source

All Articles