4

I'm developing a restful web service that will be consumed by an Android application later on.

Right now, I'm seeking a way to secure the access to my resources:

I found several ways for implementing that on the net, but I can't figure out what is the most appropriate one.
For example, I found that Oauth specifications are more convenient for third-party applications which is not my case.

So what are the most suitable ways for securing jersey APIs, and I'll be glad if someone can provide me with any tutorials/documentations on that.


  • I'm using a Glassfish v4 server and the Jersey JAX-RS implementation.
Amine Chikhaoui
  • 345
  • 1
  • 11
  • typically your app would require a form of authentication, possibly by authenticating your user directly or using oauth. your authentication can also be an api key. you just need to find a way to transfer the key to the application that suits your use case. – njzk2 Jul 22 '14 at 20:56
  • That's a nice question, I asked this very same question a time ago but haven't had an appropriate answer though... – Leonardo Jul 22 '14 at 21:00
  • Are you looking for user based authentication or a shared token that all the android clients would share? Does the authentication apply to all endpoints (resources/urls)? Reference this http://stackoverflow.com/questions/785973/what-is-the-most-appropriate-way-to-store-user-settings-in-android-application/6393502#6393502 – David W Jul 22 '14 at 23:30

2 Answers2

1

After looking at different options I used an authentication filter and basic auth. Very easy to implement.

Some example code:

You need a filter

public class AuthFilter implements ResourceFilter, ContainerRequestFilter {
  ...
}

And a security context:

public class MySecurityContext implements SecurityContext {
  ...
}

And a user class:

public class User implements Serializable, Principal {
  ...
}

Finally, you can add the filters you need like so: (pass your ResourceConfig object to this function)

private void prepareFilters(ResourceConfig rc) {
  rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
          getClassListing(new Class[]{
            AuthFilter.class
          }));

  rc.getProperties().put("com.sun.jersey.spi.container.ContainerResponseFilters",
          getClassListing(new Class[]{
            CORSFilter.class, //You might not need this
            GZIPContentEncodingFilter.class //You might not need this
          }));

  rc.getProperties().put("com.sun.jersey.spi.container.ResourceFilters",
          getClassListing(new Class[]{
            RolesAllowedResourceFilterFactory.class
          }));
}

BTW, you can add @Context SecurityContext securityContext; to your resource class(es) or the individual methods for more fine grained access control. The SecurityContext will be injected into the context of your resource so you can access the User object per request with

With this setup you can annotate your REST methods with @PermitAll, @RolesAllowed, etc which gives you a good level of control over your RESTful interface.

I just finished my stateless (without sessions) user auth and management with Jersey. Let me know if you want a full example or if you want to give it a try yourself ;)

0

The simplest way would be using the Java EE build-in Container Managed Security model to secure your rest resources as described in this tutorial. It allows you to configure the security based on users and roles stored in a database or file realm in the web.xml or the the classes themselves. The disadvantage would be that you must start a session, extract the JSESSIONID and send it in each of your requests so that the server can verify it, but that makes your services more 'stateful' and violates the statelessness of the rest architecture. Another way would be implementing custom security by using WebFilters, like sending the user name and password with each of your requests and verity them based on the information in a special db. If the information doesn't match the information stored in the database a redirect or a special error code can be returend in the Response object.

The best approach I think is using OAuth2 as described in this specification. Dependend on what kind of client you are using (desktop, web page, mobile client) there are different workflows and apart from that lots of benefits like creating tokens for special scopes of your application (read-only or full access,...). Google provides many different apis that can be accessed by the same account. If an applications only needs data from the calendar api, the requested token only gives you access to this special api and not to the entire resources of the account (like mail data, notes, etc). Another point would be that the security handling is decoupled from the client and no password must be stored in the client application. You can either implement everything on your own or use a open source project like this. It provides a description on how it works and the code is very good but it has many dependencies to spring frameworks. For my use case I've startend replacing them by vanilla Java EE 7 code and create a solution based on the idea of this open source project. The reason behind the replacements was that it's more future-proof and it avoids class loader problems during the deployment.

In the Android app a Authenticator can be implemented for secure storing of the token.

Community
  • 1
  • 1
Patrick Leitermann
  • 2,144
  • 2
  • 13
  • 13