
Sometimes you might need to return custom response types in your SecurityContext implementation when using Jersey RESTFul web services. Basically, there are two options available to do so:
- Use javax.ws.rs.core.Response and throw a WebApplicationException
- or write your own ExceptionMapper
Throw WebApplicationException
import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import java.security.Principal; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.SecurityContext; public class MySecurityContext implements SecurityContext { private final User user; private final Session session; public MySecurityContext(User user, Session session) { this.user = user; this.session = session; } public String getAuthenticationScheme() { return SecurityContext.BASIC_AUTH; } public Principal getUserPrincipal() { return user; } public boolean isSecure() { return false; } public boolean isUserInRole(String role) { JSONObject jsonObj = JSONFactoryUtil.createJSONObject(); if (null == session || !session.isActive()) { jsonObj.put("status", "failed"); jsonObj.put("message", "Authentication failed"); javax.ws.rs.core.Response denied = javax.ws.rs.core.Response .status(javax.ws.rs.core.Response.Status.FORBIDDEN) .type("application/json; charset=utf-8") .entity(jsonObj.toString()).build(); throw new WebApplicationException(denied); } try { return user.getRoles().contains(role); } catch (Exception e) { e.printStackTrace(); } return false; } }
Custom ExceptionMapper
The other (even nicer option) is to write your own ExceptionMapper:
@Provider public MyMapper implements ExceptionMapper<WebApplicationException> { public Response toResponse(WebApplicationException ex) { Response r = ex.getResponse(); if (r.getStatus() == 403 && r.getEntity() == null) { return Response.fromResponse(r).entity( new Viewable("/403response", null)).build(); } else { return r; } } }