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;
}
}
}

Leave a Reply