package com.plexobject.rbac.service.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.commons.validator.GenericValidator; import org.apache.log4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.plexobject.rbac.ServiceFactory; import com.plexobject.rbac.http.RestClient; import com.plexobject.rbac.jmx.JMXRegistrar; import com.plexobject.rbac.jmx.impl.ServiceJMXBeanImpl; import com.plexobject.rbac.security.PermissionManager; import com.plexobject.rbac.security.PermissionRequest; import com.plexobject.rbac.service.AuthorizationService; import com.plexobject.rbac.utils.CurrentRequest; import com.sun.jersey.spi.inject.Inject; @Path("/authorize") @Component("authorizationService") @Scope("singleton") public class AuthorizationServiceImpl implements AuthorizationService, InitializingBean { private static final Logger LOGGER = Logger .getLogger(AuthorizationServiceImpl.class); @Autowired @Inject PermissionManager permissionManager = ServiceFactory.getPermissionManager(); private final ServiceJMXBeanImpl mbean; public AuthorizationServiceImpl() { mbean = JMXRegistrar.getInstance().register(getClass()); } @GET @Produces(MediaType.APPLICATION_JSON) @Consumes( { MediaType.WILDCARD }) @Path("/{domain}") @Override public Response authorize(@Context UriInfo ui, @PathParam("domain") String domain, @QueryParam("operation") String operation, @QueryParam("target") String target) { if (ui == null) { throw new IllegalArgumentException("null uriinfo"); } if (GenericValidator.isBlankOrNull(domain)) { return Response.status(RestClient.CLIENT_ERROR_BAD_REQUEST).type( "text/plain").entity("domain not specified").build(); } if (GenericValidator.isBlankOrNull(operation)) { return Response.status(RestClient.CLIENT_ERROR_BAD_REQUEST).type( "text/plain").entity("operation not specified").build(); } if (GenericValidator.isBlankOrNull(target)) { return Response.status(RestClient.CLIENT_ERROR_BAD_REQUEST).type( "text/plain").entity("target not specified").build(); } MultivaluedMap<String, String> mmSubjectContext = ui .getQueryParameters(); if (mmSubjectContext == null) { throw new IllegalArgumentException("null query parameters"); } try { final Map<String, Object> subjectContext = new HashMap<String, Object>(); for (Entry<String, List<String>> e : mmSubjectContext.entrySet()) { subjectContext.put(e.getKey(), e.getValue().get(0)); } PermissionRequest request = new PermissionRequest(domain, CurrentRequest.getSubjectName(), operation, target, subjectContext); permissionManager.check(request); mbean.incrementRequests(); return Response.status(RestClient.OK).entity("granted").build(); } catch (SecurityException e) { LOGGER.error("permission failed when accessing " + domain + "/" + operation + "/" + target + ": " + e.toString()); mbean.incrementError(); return Response.status(RestClient.CLIENT_ERROR_UNAUTHORIZED).type( "text/plain").entity("denied").build(); } catch (Exception e) { LOGGER.error("permission failed unexpectedly while accessing " + domain + "/" + operation + "/" + target, e); mbean.incrementError(); return Response.status(RestClient.SERVER_INTERNAL_ERROR).type( "text/plain").entity("denied").build(); } } @Override public void afterPropertiesSet() throws Exception { if (permissionManager == null) { throw new IllegalStateException("permissionManager not set"); } } /** * @return the permissionManager */ public PermissionManager getPermissionManager() { return permissionManager; } /** * @param permissionManager * the permissionManager to set */ public void setPermissionManager(PermissionManager permissionManager) { this.permissionManager = permissionManager; } }