Ok, here are examples of implementing a Web PEP using JBossXACML.
Tell me if you find this code useful. If you have any other requirements, do tell me.
package org.jboss.test.security.xacml.bindings.web;
import java.net.URI;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.jboss.security.xacml.core.model.context.ActionType;
import org.jboss.security.xacml.core.model.context.AttributeType;
import org.jboss.security.xacml.core.model.context.EnvironmentType;
import org.jboss.security.xacml.core.model.context.RequestType;
import org.jboss.security.xacml.core.model.context.ResourceType;
import org.jboss.security.xacml.core.model.context.SubjectType;
import org.jboss.security.xacml.factories.RequestAttributeFactory;
import org.jboss.security.xacml.factories.RequestResponseContextFactory;
import org.jboss.security.xacml.interfaces.RequestContext;
/**
* PEP for the web layer
* @author Anil.Saldhana
*/
public class WebPEP
{
String ACTION_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:action:action-id";
String CURRENT_TIME_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:environment:current-time";
String RESOURCE_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
String SUBJECT_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
String SUBJECT_ROLE_IDENTIFIER = "urn:oasis:names:tc:xacml:2.0:subject:role";
@SuppressWarnings("unchecked")
public RequestContext createXACMLRequest(HttpServletRequest request,
Principal principal, Group roleGroup) throws Exception
{
RequestContext requestCtx = RequestResponseContextFactory.createRequestCtx();
//Create a subject type
SubjectType subject = new SubjectType();
subject.getAttribute().add(RequestAttributeFactory.createStringAttributeType(
SUBJECT_IDENTIFIER, "jboss.org", principal.getName()));
Enumeration roles = (Enumeration) roleGroup.members();
while(roles.hasMoreElements())
{
Principal rolePrincipal = roles.nextElement();
AttributeType attSubjectID = RequestAttributeFactory.createStringAttributeType(
SUBJECT_ROLE_IDENTIFIER, "jboss.org", rolePrincipal.getName());
subject.getAttribute().add(attSubjectID);
}
//Create a resource type
ResourceType resourceType = new ResourceType();
resourceType.getAttribute().add(RequestAttributeFactory.createAnyURIAttributeType(
RESOURCE_IDENTIFIER, null, new URI(request.getRequestURI())));
//Create an action type
ActionType actionType = new ActionType();
actionType.getAttribute().add(RequestAttributeFactory.createStringAttributeType(
ACTION_IDENTIFIER, "jboss.org", "read"));
//Create an Environment Type (Optional)
EnvironmentType environmentType = new EnvironmentType();
environmentType.getAttribute().add(RequestAttributeFactory.createDateTimeAttributeType(
CURRENT_TIME_IDENTIFIER, null));
//Create a Request Type
RequestType requestType = new RequestType();
requestType.getSubject().add(subject);
requestType.getResource().add(resourceType);
requestType.setAction(actionType);
requestType.setEnvironment(environmentType);
requestCtx.setRequest(requestType);
return requestCtx;
}
}
The test case for the web layer would be as follows:
package org.jboss.test.security.xacml.bindings.web;
import java.io.InputStream;
import java.security.Principal;
import java.security.acl.Group;
import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
import org.jboss.security.xacml.core.JBossPDP;
import org.jboss.security.xacml.interfaces.PolicyDecisionPoint;
import org.jboss.security.xacml.interfaces.RequestContext;
import org.jboss.security.xacml.interfaces.XACMLConstants;
import org.jboss.test.security.xacml.factories.util.XACMLTestUtil;
/**
* Unit Tests for the Web bindings
* @author Anil.Saldhana
*/
public class WebLayerUnitTestCase extends TestCase
{
public void testWebBinding() throws Exception
{
PolicyDecisionPoint pdp = getPDP();
assertNotNull("JBossPDP is != null", pdp);
Principal p = new Principal()
{
public String getName()
{
return "testuser";
}
};
//Create Role Group
Group grp = XACMLTestUtil.getRoleGroup("developer");
String requestURI = "http://test/developer-guide.html";
HttpRequestUtil util = new HttpRequestUtil();
HttpServletRequest req = util.createRequest(p, requestURI);
//Check PERMIT condition
WebPEP pep = new WebPEP();
RequestContext request = pep.createXACMLRequest(req, p, grp);
if(debug)
request.marshall(System.out);
assertEquals("Access Allowed?", XACMLConstants.DECISION_PERMIT,
XACMLTestUtil.getDecision(pdp,request));
}
public void testNegativeAccessWebBinding() throws Exception
{
PolicyDecisionPoint pdp = getPDP();
assertNotNull("JBossPDP is != null", pdp);
Principal p = new Principal()
{
public String getName()
{
return "testuser";
}
};
//Create Role Group
Group grp = XACMLTestUtil.getRoleGroup("imposter");
String requestURI = "http://test/developer-guide.html";
HttpRequestUtil util = new HttpRequestUtil();
HttpServletRequest req = util.createRequest(p, requestURI);
//Check DENY condition
WebPEP pep = new WebPEP();
RequestContext request = pep.createXACMLRequest(req, p, grp);
if(debug)
request.marshall(System.out);
assertEquals("Access Disallowed?", XACMLConstants.DECISION_DENY,
XACMLTestUtil.getDecision(pdp,request));
}
private PolicyDecisionPoint getPDP()
{
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
InputStream is = tcl.getResourceAsStream("test/config/webConfig.xml");
assertNotNull("InputStream != null", is);
return new JBossPDP(is);
}
}
Now here is the util class that creates a test HttpServletRequest:
package org.jboss.test.security.xacml.bindings.web;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Utility class for the web binding
* @author Anil.Saldhana
*/
public class HttpRequestUtil
{
public HttpServletRequest createRequest(final Principal gp, final String uri)
{
return new HttpServletRequest(){
public String getAuthType() {
return null;
}
public String getContextPath() {
return null;
}
public Cookie[] getCookies() {
return null;
}
public long getDateHeader(String arg0) {
return 0;
}
public String getHeader(String arg0) {
return null;
}
@SuppressWarnings("unchecked")
public Enumeration getHeaderNames() {
return null;
}
@SuppressWarnings("unchecked")
public Enumeration getHeaders(String arg0) {
return null;
}
public int getIntHeader(String arg0) {
return 0;
}
public String getMethod() {
return "GET";
}
public String getPathInfo() {
return null;
}
public String getPathTranslated() {
return null;
}
public String getQueryString() {
return null;
}
public String getRemoteUser() {
return null;
}
public String getRequestURI() {
return uri;
}
public StringBuffer getRequestURL() {
return null;
}
public String getRequestedSessionId() {
return null;
}
public String getServletPath() {
return null;
}
public HttpSession getSession() {
return null;
}
public HttpSession getSession(boolean arg0) {
return null;
}
public Principal getUserPrincipal() {
return gp;
}
public boolean isRequestedSessionIdFromCookie() {
return false;
}
public boolean isRequestedSessionIdFromURL() {
return false;
}
public boolean isRequestedSessionIdFromUrl() {
return false;
}
public boolean isRequestedSessionIdValid() {
return false;
}
public boolean isUserInRole(String arg0) {
return false;
}
public Object getAttribute(String arg0) {
return null;
}
@SuppressWarnings("unchecked")
public Enumeration getAttributeNames() {
return null;
}
public String getCharacterEncoding() {
return null;
}
public int getContentLength() {
return 0;
}
public String getContentType() {
return null;
}
public ServletInputStream getInputStream() throws IOException {
return null;
}
public String getLocalAddr() {
return null;
}
public String getLocalName() {
return null;
}
public int getLocalPort() {
return 0;
}
public Locale getLocale() {
return null;
}
@SuppressWarnings("unchecked")
public Enumeration getLocales() {
return null;
}
public String getParameter(String arg0) {
return null;
}
@SuppressWarnings("unchecked")
public Map getParameterMap() {
return null;
}
@SuppressWarnings("unchecked")
public Enumeration getParameterNames() {
return null;
}
public String[] getParameterValues(String arg0) {
return null;
}
public String getProtocol() {
return null;
}
public BufferedReader getReader() throws IOException {
return null;
}
public String getRealPath(String arg0) {
return null;
}
public String getRemoteAddr() {
return null;
}
public String getRemoteHost() {
return null;
}
public int getRemotePort() {
return 0;
}
public RequestDispatcher getRequestDispatcher(String arg0) {
return null;
}
public String getScheme() {
return null;
}
public String getServerName() {
return null;
}
public int getServerPort() {
return 0;
}
public boolean isSecure() {
return false;
}
public void removeAttribute(String arg0) {
}
public void setAttribute(String arg0, Object arg1) {
}
public void setCharacterEncoding(String arg0)
throws UnsupportedEncodingException {
}};
}
}
Here is the XACMLTestUtil class:
package org.jboss.test.security.xacml.factories.util;
import java.io.InputStream;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
import java.util.Vector;
import junit.framework.TestCase;
import org.jboss.security.xacml.factories.RequestResponseContextFactory;
import org.jboss.security.xacml.interfaces.PolicyDecisionPoint;
import org.jboss.security.xacml.interfaces.RequestContext;
import org.jboss.security.xacml.interfaces.ResponseContext;
import org.jboss.security.xacml.interfaces.XACMLConstants;
/**
* Utility class for the JBossXACML Tests
* @author Anil.Saldhana
*/
public class XACMLTestUtil
{
//Enable for request trace
private static boolean debug = "true".equals(System.getProperty("debug","false"));
/**
* Get the decision from the PDP
* @param pdp
* @param requestFileLoc a file where the xacml request is stored
* @return
* @throws Exception
*/
public static int getDecision(PolicyDecisionPoint pdp,
String requestFileLoc) throws Exception
{
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
InputStream is = tcl.getResourceAsStream(requestFileLoc);
RequestContext request = RequestResponseContextFactory.createRequestCtx();
request.readRequest(is);
ResponseContext response = pdp.evaluate(request);
if(response == null)
throw new RuntimeException("Response is null");
return response.getDecision();
}
/**
* Get the decision from the PDP
* @param pdp
* @param request RequestContext containing the request
* @return
* @throws Exception
*/
public static int getDecision(PolicyDecisionPoint pdp, RequestContext request)
throws Exception
{
ResponseContext response = pdp.evaluate(request);
if(debug)
response.marshall(System.out);
TestCase.assertNotNull("Response is not null", response);
return response.getDecision();
}
/**
* Get a Group with the passed rolename
* @param roleName rolename which will be placed as a principal
* @return
*/
public static Group getRoleGroup( final String roleName)
{
return new Group() {
private Vector vect = new Vector();
public boolean addMember(final Principal principal)
{
return vect.add(principal);
}
public boolean isMember(Principal principal)
{
return vect.contains(principal);
}
public Enumeration members()
{
vect.add(new Principal()
{
public String getName()
{
return roleName;
}});
return vect.elements();
}
public boolean removeMember(Principal principal)
{
return vect.remove(principal);
}
public String getName()
{
return "ROLES";
}
};
}
}