You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by cs...@apache.org on 2013/08/06 19:36:42 UTC

svn commit: r1511048 - in /cxf/trunk/rt/security/src: main/java/org/apache/cxf/rt/security/xacml/ main/java/org/apache/cxf/rt/security/xacml/pdp/api/ test/java/org/apache/cxf/rt/security/xacml/

Author: cschneider
Date: Tue Aug  6 17:36:42 2013
New Revision: 1511048

URL: http://svn.apache.org/r1511048
Log:
CXF-5121 Introduce  XACMLAuthorizingInterceptor

Added:
    cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptor.java
      - copied, changed from r1502553, cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java
    cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyPDP.java
      - copied, changed from r1502553, cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyXACMLAuthorizingInterceptor.java
Removed:
    cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/pdp/api/PDPException.java
    cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyXACMLAuthorizingInterceptor.java
Modified:
    cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java
    cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptorTest.java

Modified: cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java?rev=1511048&r1=1511047&r2=1511048&view=diff
==============================================================================
--- cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java (original)
+++ cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java Tue Aug  6 17:36:42 2013
@@ -54,7 +54,10 @@ import org.opensaml.xacml.ctx.StatusType
  * statement. 
  * 
  * This class must be subclassed to actually perform the request to the PDP.
+ * 
+ * @deprecated: Use XACMLAuthorizingInterceptor instead
  */
+@Deprecated
 public abstract class AbstractXACMLAuthorizingInterceptor extends AbstractPhaseInterceptor<Message> {
     
     private static final Logger LOG = LogUtils.getL7dLogger(AbstractXACMLAuthorizingInterceptor.class);

Copied: cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptor.java (from r1502553, cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptor.java?p2=cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptor.java&p1=cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java&r1=1502553&r2=1511048&rev=1511048&view=diff
==============================================================================
--- cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/AbstractXACMLAuthorizingInterceptor.java (original)
+++ cxf/trunk/rt/security/src/main/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptor.java Tue Aug  6 17:36:42 2013
@@ -19,145 +19,69 @@
 
 package org.apache.cxf.rt.security.xacml;
 
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.DOMUtils;
-import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.interceptor.security.AccessDeniedException;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.phase.AbstractPhaseInterceptor;
-import org.apache.cxf.phase.Phase;
-import org.apache.cxf.security.LoginSecurityContext;
-import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.rt.security.xacml.pdp.api.PolicyDecisionPoint;
+import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.saml.OpenSAMLUtil;
-import org.apache.wss4j.common.util.DOM2Writer;
-import org.opensaml.xacml.ctx.DecisionType.DECISION;
 import org.opensaml.xacml.ctx.RequestType;
 import org.opensaml.xacml.ctx.ResponseType;
-import org.opensaml.xacml.ctx.ResultType;
-import org.opensaml.xacml.ctx.StatusType;
-
 
 /**
- * An abstract interceptor to perform an XACML authorization request to a remote PDP,
+ * An interceptor to perform an XACML authorization request to a remote PDP,
  * and make an authorization decision based on the response. It takes the principal and roles
  * from the SecurityContext, and uses the XACMLRequestBuilder to construct an XACML Request
  * statement. 
- * 
- * This class must be subclassed to actually perform the request to the PDP.
  */
-public abstract class AbstractXACMLAuthorizingInterceptor extends AbstractPhaseInterceptor<Message> {
-    
-    private static final Logger LOG = LogUtils.getL7dLogger(AbstractXACMLAuthorizingInterceptor.class);
-    
-    private XACMLRequestBuilder requestBuilder = new DefaultXACMLRequestBuilder();
-    
-    public AbstractXACMLAuthorizingInterceptor() {
-        super(Phase.PRE_INVOKE);
-        org.apache.wss4j.common.saml.OpenSAMLUtil.initSamlEngine();
-    }
-    
-    public void handleMessage(Message message) throws Fault {
-        SecurityContext sc = message.get(SecurityContext.class);
-        
-        if (sc instanceof LoginSecurityContext) {
-            Principal principal = sc.getUserPrincipal();
-            
-            LoginSecurityContext loginSecurityContext = (LoginSecurityContext)sc;
-            Set<Principal> principalRoles = loginSecurityContext.getUserRoles();
-            List<String> roles = new ArrayList<String>();
-            if (principalRoles != null) {
-                for (Principal p : principalRoles) {
-                    if (p != principal) {
-                        roles.add(p.getName());
-                    }
-                }
-            }
-            
-            try {
-                if (authorize(principal, roles, message)) {
-                    return;
-                }
-            } catch (Exception e) {
-                LOG.log(Level.FINE, "Unauthorized: " + e.getMessage(), e);
-                throw new AccessDeniedException("Unauthorized");
-            }
-        } else {
-            LOG.log(
-                Level.FINE,
-                "The SecurityContext was not an instance of LoginSecurityContext. No authorization "
-                + "is possible as a result"
-            );
+@SuppressWarnings("deprecation")
+public class XACMLAuthorizingInterceptor extends AbstractXACMLAuthorizingInterceptor {
+    private PolicyDecisionPoint pdp;
+    
+    public XACMLAuthorizingInterceptor(PolicyDecisionPoint pdp) {
+        super();
+        this.pdp = pdp;
+    }
+
+    @Override
+    public ResponseType performRequest(RequestType request, Message message) throws Exception {
+        Source requestSource = requestType2Source(request);
+        Source responseSource = this.pdp.evaluate(requestSource);
+        return responseSourceToResponseType(responseSource);
+    }
+    
+    private Source requestType2Source(RequestType request) {
+        Document doc = DOMUtils.createDocument();
+        Element requestElement;
+        try {
+            requestElement = OpenSAMLUtil.toDom(request, doc);
+        } catch (WSSecurityException e) {
+            throw new RuntimeException("Error converting PDP RequestType to Dom", e);
         }
-        
-        throw new AccessDeniedException("Unauthorized");
-    }
-    
-    public XACMLRequestBuilder getRequestBuilder() {
-        return requestBuilder;
+        return new DOMSource(requestElement);
     }
 
-    public void setRequestBuilder(XACMLRequestBuilder requestBuilder) {
-        this.requestBuilder = requestBuilder;
-    }
-
-    /**
-     * Perform a (remote) authorization decision and return a boolean depending on the result
-     */
-    protected boolean authorize(
-        Principal principal, List<String> roles, Message message
-    ) throws Exception {
-        RequestType request = requestBuilder.createRequest(principal, roles, message);
-        if (LOG.isLoggable(Level.FINE)) {
-            Document doc = DOMUtils.createDocument();
-            Element requestElement = OpenSAMLUtil.toDom(request, doc);
-            LOG.log(Level.FINE, DOM2Writer.nodeToString(requestElement));
-        }
-        
-        ResponseType response = performRequest(request, message);
-        
-        ResultType result = response.getResult();
-        
-        // Handle any Obligations returned by the PDP
-        handleObligations(request, principal, message, result);
-        
-        if (result == null) {
-            return false;
-        }
-
-        DECISION decision = result.getDecision() != null ? result.getDecision().getDecision() : DECISION.Deny; 
-        String code = "";
-        String statusMessage = "";
-        if (result.getStatus() != null) {
-            StatusType status = result.getStatus();
-            code = status.getStatusCode() != null ? status.getStatusCode().getValue() : "";
-            statusMessage = status.getStatusMessage() != null ? status.getStatusMessage().getValue() : "";
+    private ResponseType responseSourceToResponseType(Source responseSource) {
+        try {
+            Transformer trans = TransformerFactory.newInstance().newTransformer();
+            DOMResult res = new DOMResult();
+            trans.transform(responseSource, res);
+            Node nd = res.getNode();
+            if (nd instanceof Document) {
+                nd = ((Document)nd).getDocumentElement();
+            }
+            return (ResponseType)OpenSAMLUtil.fromDom((Element)nd);
+        } catch (Exception e) {
+            throw new RuntimeException("Error converting pdp response to ResponseType", e);
         }
-        LOG.fine("XACML authorization result: " + decision + ", code: " + code + ", message: " + statusMessage);
-        return decision == DECISION.Permit;
     }
-    
-    public abstract ResponseType performRequest(RequestType request, Message message) throws Exception;
-    
-    /**
-     * Handle any Obligations returned by the PDP
-     */
-    protected void handleObligations(
-        RequestType request,
-        Principal principal,
-        Message message,
-        ResultType result
-    ) throws Exception {
-        // Do nothing by default
-    }
-    
 }

Copied: cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyPDP.java (from r1502553, cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyXACMLAuthorizingInterceptor.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyPDP.java?p2=cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyPDP.java&p1=cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyXACMLAuthorizingInterceptor.java&r1=1502553&r2=1511048&rev=1511048&view=diff
==============================================================================
--- cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyXACMLAuthorizingInterceptor.java (original)
+++ cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/DummyPDP.java Tue Aug  6 17:36:42 2013
@@ -21,7 +21,20 @@ package org.apache.cxf.rt.security.xacml
 
 import java.util.List;
 
-import org.apache.cxf.message.Message;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.rt.security.xacml.pdp.api.PolicyDecisionPoint;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
 import org.opensaml.Configuration;
 import org.opensaml.xacml.XACMLObjectBuilder;
 import org.opensaml.xacml.ctx.AttributeType;
@@ -35,18 +48,45 @@ import org.opensaml.xacml.ctx.StatusType
 import org.opensaml.xacml.ctx.SubjectType;
 import org.opensaml.xml.XMLObjectBuilderFactory;
 
-
 /**
  * A test implementation of AbstractXACMLAuthorizingInterceptor. It just mocks up a Response
  * object based on the role of the Subject. If the role is "manager" then it permits the
  * request, otherwise it denies it.
  */
-public class DummyXACMLAuthorizingInterceptor extends AbstractXACMLAuthorizingInterceptor {
+public class DummyPDP implements PolicyDecisionPoint {
 
-    public ResponseType performRequest(RequestType request, Message message) throws Exception {
+    public Source evaluate(Source requestSource) {
+        RequestType request = requestSourceToRequestType(requestSource); 
         String role = getSubjectRole(request);
         DECISION decision = "manager".equals(role) ? DecisionType.DECISION.Permit : DecisionType.DECISION.Deny;        
-        return createResponse(decision);
+        ResponseType response = createResponse(decision);
+        return responseType2Source(response);
+    }
+    
+    private RequestType requestSourceToRequestType(Source requestSource) {
+        try {
+            Transformer trans = TransformerFactory.newInstance().newTransformer();
+            DOMResult res = new DOMResult();
+            trans.transform(requestSource, res);
+            Node nd = res.getNode();
+            if (nd instanceof Document) {
+                nd = ((Document)nd).getDocumentElement();
+            }
+            return (RequestType)OpenSAMLUtil.fromDom((Element)nd);
+        } catch (Exception e) {
+            throw new RuntimeException("Error converting pdp response to ResponseType", e);
+        }
+    }
+    
+    private Source responseType2Source(ResponseType response) {
+        Document doc = DOMUtils.createDocument();
+        Element responseElement;
+        try {
+            responseElement = OpenSAMLUtil.toDom(response, doc);
+        } catch (WSSecurityException e) {
+            throw new RuntimeException("Error converting PDP RequestType to Dom", e);
+        }
+        return new DOMSource(responseElement);
     }
 
     private ResponseType createResponse(DECISION decision) {
@@ -110,5 +150,5 @@ public class DummyXACMLAuthorizingInterc
         }
         return null;
     }
-    
+
 }

Modified: cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptorTest.java?rev=1511048&r1=1511047&r2=1511048&view=diff
==============================================================================
--- cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptorTest.java (original)
+++ cxf/trunk/rt/security/src/test/java/org/apache/cxf/rt/security/xacml/XACMLAuthorizingInterceptorTest.java Tue Aug  6 17:36:42 2013
@@ -28,6 +28,7 @@ import javax.xml.namespace.QName;
 
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.rt.security.xacml.pdp.api.PolicyDecisionPoint;
 import org.apache.cxf.security.LoginSecurityContext;
 import org.apache.cxf.security.SecurityContext;
 
@@ -41,6 +42,7 @@ public class XACMLAuthorizingInterceptor
         org.apache.wss4j.common.saml.OpenSAMLUtil.initSamlEngine();
     }
 
+    @SuppressWarnings("deprecation")
     @org.junit.Test
     public void testPermit() throws Exception {
         // Mock up a Security Context
@@ -55,11 +57,12 @@ public class XACMLAuthorizingInterceptor
         msg.put(Message.REQUEST_URI, resourceURI);
         msg.put(SecurityContext.class, sc);
         
-        AbstractXACMLAuthorizingInterceptor authorizingInterceptor = 
-            new DummyXACMLAuthorizingInterceptor();
+        PolicyDecisionPoint pdp = new DummyPDP();
+        XACMLAuthorizingInterceptor authorizingInterceptor = new XACMLAuthorizingInterceptor(pdp);
         authorizingInterceptor.handleMessage(msg);
     }
     
+    @SuppressWarnings("deprecation")
     @org.junit.Test
     public void testDeny() throws Exception {
         // Mock up a Security Context
@@ -74,8 +77,8 @@ public class XACMLAuthorizingInterceptor
         msg.put(Message.REQUEST_URI, resourceURI);
         msg.put(SecurityContext.class, sc);
         
-        AbstractXACMLAuthorizingInterceptor authorizingInterceptor = 
-            new DummyXACMLAuthorizingInterceptor();
+        PolicyDecisionPoint pdp = new DummyPDP();
+        XACMLAuthorizingInterceptor authorizingInterceptor = new XACMLAuthorizingInterceptor(pdp);
         
         try {
             authorizingInterceptor.handleMessage(msg);