Jersey Security

Create request authentication filter

We know that JAX-RS 2.0 has filters for pre and post request handling, so we will be using ContainerRequestFilter interface

@Provider
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter {
	@Context
	private ResourceInfo resourceInfo;
	private static final String AUTHORIZATION_PROPERTY = "Authorization";
	private static final String AUTHENTICATION_SCHEME = "Basic";
	private static final String ACCESS_DENIED = "You cannot access this resource";
	private static final String ACCESS_FORBIDDEN = "Access blocked for all users !!";

	private Response buildResponse(Object entity) {
		return Response.status(Response.Status.UNAUTHORIZED).entity(entity).build();
	}

	@Override
	public void filter(ContainerRequestContext requestContext) {
		UriInfo uriInfo = requestContext.getUriInfo();
		String path = uriInfo.getPath();
		if (path.contains(Globals.PATH_FILTER)) {
			Method method = resourceInfo.getResourceMethod();
			// Access allowed for all
			if (!method.isAnnotationPresent(PermitAll.class)) {
				// Access denied for all
				if (method.isAnnotationPresent(DenyAll.class)) {
					requestContext.abortWith(buildResponse(ACCESS_FORBIDDEN));
					return;
				}
				// Get request headers
				final MultivaluedMap<String, String> headers = requestContext.getHeaders();
				// Fetch authorization header
				final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
				// If no authorization information present; block access
				if (authorization == null || authorization.isEmpty()) {
					requestContext.abortWith(buildResponse(ACCESS_DENIED));
					return;
				}
				// Get encoded username and password
				final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
				// Decode username and password
				String usernameAndPassword = new String(Base64.decodeBase64(encodedUserPassword.getBytes()));
				// Split username and password tokens
				final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
				final String username = tokenizer.nextToken();
				final String password = tokenizer.nextToken();
				// Verifying Username and password
				// System.out.println(username);
				// System.out.println(password);
				// Verify user access
				if (method.isAnnotationPresent(RolesAllowed.class)) {
					RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
					Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
					// Is user valid?
					if (!isUserAllowed(username, password, rolesSet)) {
						requestContext.abortWith(buildResponse(ACCESS_DENIED));
						return;
					}
				}
			}
		}
	}

	private boolean isUserAllowed(final String username, final String password,
			final Set<String> rolesSet) {
		boolean isAllowed = false;
		// Step 1. Fetch password from database and match with password in argument
		// If both match then get the defined role for user from database and continue; else return isAllowed [false]
		// Access the database and do this part yourself
		// String userRole = userMgr.getUserRole(username);
		if (username.equals(Globals.T5750)
				&& password.equals(Globals.PASSWORD)) {
			String userRole = "ADMIN";
			// Step 2. Verify user role
			if (rolesSet.contains(userRole)) {
				isAllowed = true;
			}
		}
		return isAllowed;
	}
}

Register AuthenticationFilter with ResourceConfig

Now you will need to register above filter with ResourceConfig instance

public class JerseyApplication extends ResourceConfig {
	public JerseyApplication() {
		packages("t5750.rest.jersey.resources", "t5750.rest.jersey.service");
		register(GsonMessageBodyHandler.class);
		register(AuthenticationFilter.class);
	}
}

Secure REST APIs

Use standard JAX-RS annotations

@Path("/employees")
public class JerseyService {
	@RolesAllowed("ADMIN")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	public Employees getAllEmployees() {
		Employees list = new Employees();
		list.setEmployeeList(new ArrayList<Employee>());
		list.getEmployeeList().add(new Employee(1, "Lokesh Gupta"));
		list.getEmployeeList().add(new Employee(2, "Alex Kolenchiskey"));
		list.getEmployeeList().add(new Employee(3, "David Kameron"));
		return list;
	}
}

References