Google Site Search

Google
 

Friday, February 22, 2008

Web layer enforcement using JBossXACML

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


}

No comments: