Java Restful Web Services (jax rs) authentication pattern

Viewed 3826

I have started using JAX-RS to created a simple restful interface to my web application. Currently, it is only being used (read only) by one internal client which has access to all application data, and I am using http basic authentication for access. I would like to start using it as part of the view layer of my app, and certain operations will only be allowed if a user is logged in via the web app. I am struggling to find a pattern that allows me to use both forms of authentication in an elegant way, without repeating a lot of code. Here is roughly what I have come up with:

First a util class for loading an application session, which is stored in the database.

public class RestUtil {
    public static AppSession getAuthenticatedSession(HttpServletRequest request) {
        AppSession session;
        String remoteUser = request.getRemoteUser();
        if (remoteUser != null) {
            session = SessionRepository.loadSessionByRemoteUser(remoteUser);
        } else {
            session = SessionRepository.loadSessionById(request.getSession().getId());
        }
        return session;
    }
}

Here's our resource, with one method that is only accessible to an authenticated user, or our http basic auth client:

@Path("/protected/resource")
public class ProtectedResource {
    @GET
    @Produces(MediaType.TEXT_JSON)
    @Path("{userId}")
    public String getProtectedResourceJson(@Context HttpServletRequest request, @PathParam("userId") Integer userId) {
        // Return Charity List XML
        AppSession session = RestUtil.getAuthenticatedSession(request);

        if (session.canAccessUser(userId))  //get Json...
    }
}

Here's the most basic view of the AppSession, for the purpose of this question:

public class AppSession {
    User authenticatedUser;
    String remoteUser;

    public boolean canAccessUser(Integer userId) {
        if (remoteUser != null) {
            //this client has access to all users
            return true;
        } else if (authenticatedUser.getId().equals(userId)) {
            //this is local client, calling the service from a view
            //only has access to authenticatedUser
            return true;
        } else {
            return false;
        }
    }
}

Furthermore, for services that do not require any sort of authentication, how do I prevent unauthorized third parties from just pointing at the url, and grabbing the data at their leisure?

1 Answers
Related