cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject [4/4] cxf git commit: Adding a new cxf-rt-security-saml module to remove OpenSAML dependencies from cxf-rt-security
Date Mon, 13 Apr 2015 12:04:53 GMT
Adding a new cxf-rt-security-saml module to remove OpenSAML dependencies from cxf-rt-security


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/c04c2720
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/c04c2720
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/c04c2720

Branch: refs/heads/master
Commit: c04c27200226b564108b4fe58b8ac70ca5ec7638
Parents: 71e9ada
Author: Colm O hEigeartaigh <coheigea@apache.org>
Authored: Mon Apr 13 13:04:26 2015 +0100
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Mon Apr 13 13:04:26 2015 +0100

----------------------------------------------------------------------
 .../features/src/main/resources/features.xml    |  10 +-
 rt/pom.xml                                      |   1 +
 .../grants/saml/Saml2BearerGrantHandler.java    |   2 +-
 .../saml/sso/AbstractServiceProviderFilter.java |  10 +-
 .../authorization/ClaimsAuthorizingFilter.java  |   4 +-
 .../SecurityContextProviderImpl.java            |   6 +-
 rt/security-saml/pom.xml                        |  60 ++++
 .../cxf/rt/security/saml/claims/ClaimBean.java  |  51 +++
 .../cxf/rt/security/saml/claims/SAMLClaim.java  |  68 ++++
 .../saml/claims/SAMLSecurityContext.java        | 104 +++++++
 .../ClaimsAuthorizingInterceptor.java           | 244 +++++++++++++++
 .../cxf/rt/security/saml/utils/SAMLUtils.java   | 141 +++++++++
 .../AbstractXACMLAuthorizingInterceptor.java    | 170 ++++++++++
 .../security/saml/xacml/CXFMessageParser.java   |  97 ++++++
 .../saml/xacml/DefaultXACMLRequestBuilder.java  | 217 +++++++++++++
 .../saml/xacml/RequestComponentBuilder.java     | 183 +++++++++++
 .../saml/xacml/SamlRequestComponentBuilder.java | 118 +++++++
 .../saml/xacml/XACMLAuthorizingInterceptor.java |  86 ++++++
 .../rt/security/saml/xacml/XACMLConstants.java  | 206 +++++++++++++
 .../saml/xacml/XACMLRequestBuilder.java         |  62 ++++
 .../saml/xacml/pdp/api/PolicyDecisionPoint.java |  35 +++
 .../rt/security/saml/claims/SAMLClaimsTest.java | 212 +++++++++++++
 .../saml/claims/SamlCallbackHandler.java        |  99 ++++++
 .../ClaimsAuthorizingInterceptorTest.java       | 298 ++++++++++++++++++
 .../cxf/rt/security/saml/xacml/DummyPDP.java    | 153 +++++++++
 .../saml/xacml/RequestComponentBuilderTest.java | 222 ++++++++++++++
 .../xacml/SamlRequestComponentBuilderTest.java  | 153 +++++++++
 .../xacml/XACMLAuthorizingInterceptorTest.java  | 127 ++++++++
 .../saml/xacml/XACMLRequestBuilderTest.java     | 307 +++++++++++++++++++
 rt/security/pom.xml                             |  10 -
 .../cxf/rt/security/claims/ClaimBean.java       |  51 ---
 .../claims/ClaimsAuthorizingInterceptor.java    | 242 ---------------
 .../cxf/rt/security/claims/SAMLClaim.java       |  66 ----
 .../rt/security/saml/SAMLSecurityContext.java   | 104 -------
 .../apache/cxf/rt/security/saml/SAMLUtils.java  | 141 ---------
 .../AbstractXACMLAuthorizingInterceptor.java    | 170 ----------
 .../cxf/rt/security/xacml/CXFMessageParser.java |  97 ------
 .../xacml/DefaultXACMLRequestBuilder.java       | 217 -------------
 .../security/xacml/RequestComponentBuilder.java | 183 -----------
 .../xacml/SamlRequestComponentBuilder.java      | 118 -------
 .../xacml/XACMLAuthorizingInterceptor.java      |  87 ------
 .../cxf/rt/security/xacml/XACMLConstants.java   | 206 -------------
 .../rt/security/xacml/XACMLRequestBuilder.java  |  62 ----
 .../xacml/pdp/api/PolicyDecisionPoint.java      |  35 ---
 .../ClaimsAuthorizingInterceptorTest.java       | 295 ------------------
 .../cxf/rt/security/saml/SAMLClaimsTest.java    | 212 -------------
 .../rt/security/saml/SamlCallbackHandler.java   |  99 ------
 .../apache/cxf/rt/security/xacml/DummyPDP.java  | 153 ---------
 .../xacml/RequestComponentBuilderTest.java      | 222 --------------
 .../xacml/SamlRequestComponentBuilderTest.java  | 153 ---------
 .../xacml/XACMLAuthorizingInterceptorTest.java  | 127 --------
 .../security/xacml/XACMLRequestBuilderTest.java | 307 -------------------
 rt/ws/security/pom.xml                          |   2 +-
 .../trust/AuthPolicyValidatingInterceptor.java  |   5 +-
 .../cxf/ws/security/trust/STSLoginModule.java   |   3 +-
 .../wss4j/StaxSecurityContextInInterceptor.java |   4 +-
 .../wss4j/UsernameTokenInterceptor.java         |   4 +-
 .../ws/security/wss4j/WSS4JInInterceptor.java   |   5 +-
 .../token/validator/DefaultSAMLRoleParser.java  |   4 +-
 .../security/oauth2/SamlCallbackHandler.java    |   2 +-
 .../security/oauth2/SamlCallbackHandler2.java   |   2 +-
 .../security/saml/SamlCallbackHandler.java      |   2 +-
 .../ws/saml/PolicyDecisionPointMockImpl.java    |   4 +-
 .../org/apache/cxf/systest/ws/saml/server.xml   |   2 +-
 .../apache/cxf/systest/ws/saml/stax-server.xml  |   2 +-
 65 files changed, 3451 insertions(+), 3393 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/osgi/karaf/features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/osgi/karaf/features/src/main/resources/features.xml b/osgi/karaf/features/src/main/resources/features.xml
index 33b418d..0705424 100644
--- a/osgi/karaf/features/src/main/resources/features.xml
+++ b/osgi/karaf/features/src/main/resources/features.xml
@@ -119,14 +119,18 @@
         <feature version="${project.version}">cxf-ws-addr</feature>
         <bundle start-level="40" dependency="true">mvn:net.sf.ehcache/ehcache/${cxf.ehcache.version}</bundle>
         <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-ws-security/${project.version}</bundle>
-        <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-security/${project.version}</bundle>
+        <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-security-saml/${project.version}</bundle>
     </feature>
     <feature name="cxf-rt-security" version="${project.version}" resolver="(obr)">
         <feature version="${project.version}">cxf-core</feature>
         <feature version="${project.version}">cxf-wsdl</feature>
-        <feature version="${cxf.wss4j.version}">wss4j</feature>
         <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-security/${project.version}</bundle>
     </feature>
+    <feature name="cxf-rt-security-saml" version="${project.version}" resolver="(obr)">
+        <feature version="${project.version}">cxf-rt-security</feature>
+        <feature version="${cxf.wss4j.version}">wss4j</feature>
+        <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-security-saml/${project.version}</bundle>
+    </feature>
     <feature name="cxf-http" version="${project.version}" resolver="(obr)">
         <feature version="${project.version}">cxf-core</feature>
         <bundle start-level="40">mvn:${cxf.servlet-api.group}/${cxf.servlet-api.artifact}/${cxf.servlet-api.version}</bundle>
@@ -189,7 +193,7 @@
     </feature>
     <feature name="cxf-rs-security-xml" version="${project.version}" resolver="(obr)">
         <feature version="${project.version}">cxf-jaxrs</feature>
-        <feature version="${project.version}">cxf-rt-security</feature>
+        <feature version="${project.version}">cxf-rt-security-saml</feature>
         <bundle start-level="40">mvn:org.apache.cxf/cxf-rt-rs-security-xml/${project.version}</bundle>
     </feature>
     <feature name="cxf-rs-security-sso-saml" version="${project.version}" resolver="(obr)">

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/pom.xml
----------------------------------------------------------------------
diff --git a/rt/pom.xml b/rt/pom.xml
index fd9da64..2458834 100644
--- a/rt/pom.xml
+++ b/rt/pom.xml
@@ -75,5 +75,6 @@
         <module>management-web</module>
         <module>javascript</module>
         <module>security</module>
+        <module>security-saml</module>
     </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/rs/security/oauth-parent/oauth2-saml/src/main/java/org/apache/cxf/rs/security/oauth2/grants/saml/Saml2BearerGrantHandler.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-saml/src/main/java/org/apache/cxf/rs/security/oauth2/grants/saml/Saml2BearerGrantHandler.java b/rt/rs/security/oauth-parent/oauth2-saml/src/main/java/org/apache/cxf/rs/security/oauth2/grants/saml/Saml2BearerGrantHandler.java
index 9dbc021..6a29910 100644
--- a/rt/rs/security/oauth-parent/oauth2-saml/src/main/java/org/apache/cxf/rs/security/oauth2/grants/saml/Saml2BearerGrantHandler.java
+++ b/rt/rs/security/oauth-parent/oauth2-saml/src/main/java/org/apache/cxf/rs/security/oauth2/grants/saml/Saml2BearerGrantHandler.java
@@ -52,7 +52,7 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
 import org.apache.cxf.rs.security.saml.authorization.SecurityContextProvider;
 import org.apache.cxf.rs.security.saml.authorization.SecurityContextProviderImpl;
-import org.apache.cxf.rt.security.saml.SAMLSecurityContext;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.security.transport.TLSSessionInfo;
 import org.apache.cxf.staxutils.StaxUtils;

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
index d3ccfac..b4afac4 100644
--- a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
+++ b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
@@ -55,7 +55,7 @@ import org.apache.cxf.rs.security.saml.assertion.Subject;
 import org.apache.cxf.rs.security.saml.sso.state.RequestState;
 import org.apache.cxf.rs.security.saml.sso.state.ResponseState;
 import org.apache.cxf.rt.security.claims.ClaimCollection;
-import org.apache.cxf.rt.security.saml.SAMLSecurityContext;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.ws.security.SecurityConstants;
@@ -193,16 +193,16 @@ public abstract class AbstractServiceProviderFilter extends AbstractSSOSpHandler
                 roleAttributeName = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role";
             }
             ClaimCollection claims = 
-                org.apache.cxf.rt.security.saml.SAMLUtils.getClaims(assertionWrapper);
+                org.apache.cxf.rt.security.saml.utils.SAMLUtils.getClaims(assertionWrapper);
             Set<Principal> roles = 
-                org.apache.cxf.rt.security.saml.SAMLUtils.parseRolesFromClaims(
+                org.apache.cxf.rt.security.saml.utils.SAMLUtils.parseRolesFromClaims(
                     claims, roleAttributeName, null);
 
             SAMLSecurityContext context = 
                 new SAMLSecurityContext(new SimplePrincipal(name), roles, claims);
-            context.setIssuer(org.apache.cxf.rt.security.saml.SAMLUtils.getIssuer(assertionWrapper));
+            context.setIssuer(org.apache.cxf.rt.security.saml.utils.SAMLUtils.getIssuer(assertionWrapper));
             context.setAssertionElement(
-                org.apache.cxf.rt.security.saml.SAMLUtils.getAssertionElement(assertionWrapper));
+                org.apache.cxf.rt.security.saml.utils.SAMLUtils.getAssertionElement(assertionWrapper));
             m.put(SecurityContext.class, context);
         }
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/ClaimsAuthorizingFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/ClaimsAuthorizingFilter.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/ClaimsAuthorizingFilter.java
index f373d91..09c3d26 100644
--- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/ClaimsAuthorizingFilter.java
+++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/ClaimsAuthorizingFilter.java
@@ -28,8 +28,8 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.interceptor.security.AccessDeniedException;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.rt.security.claims.ClaimBean;
-import org.apache.cxf.rt.security.claims.ClaimsAuthorizingInterceptor;
+import org.apache.cxf.rt.security.saml.claims.ClaimBean;
+import org.apache.cxf.rt.security.saml.interceptor.ClaimsAuthorizingInterceptor;
 
 public class ClaimsAuthorizingFilter implements ContainerRequestFilter {
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java
index 604efb5..9899085 100644
--- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java
+++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java
@@ -25,9 +25,9 @@ import org.w3c.dom.Element;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.saml.assertion.Subject;
 import org.apache.cxf.rt.security.claims.ClaimCollection;
-import org.apache.cxf.rt.security.claims.SAMLClaim;
-import org.apache.cxf.rt.security.saml.SAMLSecurityContext;
-import org.apache.cxf.rt.security.saml.SAMLUtils;
+import org.apache.cxf.rt.security.saml.claims.SAMLClaim;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
+import org.apache.cxf.rt.security.saml.utils.SAMLUtils;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.common.saml.builder.SAML2Constants;

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/pom.xml
----------------------------------------------------------------------
diff --git a/rt/security-saml/pom.xml b/rt/security-saml/pom.xml
new file mode 100644
index 0000000..d740e27
--- /dev/null
+++ b/rt/security-saml/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>cxf-rt-security-saml</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache CXF Runtime SAML Security functionality</name>
+    <description>Apache CXF Runtime SAML Security functionality</description>
+    <url>http://cxf.apache.org</url>
+    <parent>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-parent</artifactId>
+        <version>3.1.0-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+    <properties>
+        <cxf.osgi.import>
+            org.opensaml*,
+        </cxf.osgi.import>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-security</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.wss4j</groupId>
+            <artifactId>wss4j-ws-security-common</artifactId>
+            <version>${cxf.wss4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/ClaimBean.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/ClaimBean.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/ClaimBean.java
new file mode 100644
index 0000000..4d9606f
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/ClaimBean.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rt.security.saml.claims;
+
+import org.apache.cxf.security.claims.authorization.ClaimMode;
+
+public class ClaimBean {
+    private SAMLClaim claim;
+    private ClaimMode claimMode;
+    private boolean matchAll;
+    
+    public ClaimBean(SAMLClaim claim) {
+        this.claim = claim;
+    }
+    
+    public ClaimBean(SAMLClaim claim,
+                     ClaimMode claimMode, 
+                     boolean matchAll) {
+        this.claim = claim;
+        this.claimMode = claimMode;
+        this.matchAll = matchAll;
+    }
+    
+    public SAMLClaim getClaim() {
+        return claim;
+    }
+    
+    public boolean isMatchAll() {
+        return matchAll;
+    }
+    
+    public ClaimMode getClaimMode() {
+        return claimMode;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLClaim.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLClaim.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLClaim.java
new file mode 100644
index 0000000..5fb080d
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLClaim.java
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.claims;
+
+import org.apache.cxf.rt.security.claims.Claim;
+
+
+/**
+ * This represents a Claim that is coupled to a SAML Assertion
+ */
+public class SAMLClaim extends Claim {
+    
+    /**
+     * This configuration tag specifies the default attribute name where the roles are present
+     * The default is "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role".
+     */
+    public static final String SAML_ROLE_ATTRIBUTENAME_DEFAULT =
+        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role";
+    
+    private static final long serialVersionUID = 5530712294179589442L;
+
+    private String nameFormat;
+    private String name;
+    private String friendlyName;
+    
+    public String getNameFormat() {
+        return nameFormat;
+    }
+    
+    public void setNameFormat(String nameFormat) {
+        this.nameFormat = nameFormat;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getFriendlyName() {
+        return friendlyName;
+    }
+
+    public void setFriendlyName(String friendlyName) {
+        this.friendlyName = friendlyName;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLSecurityContext.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLSecurityContext.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLSecurityContext.java
new file mode 100644
index 0000000..b9b012a
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/claims/SAMLSecurityContext.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rt.security.saml.claims;
+
+import java.security.Principal;
+import java.util.Set;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.rt.security.claims.ClaimCollection;
+import org.apache.cxf.rt.security.claims.ClaimsSecurityContext;
+
+public class SAMLSecurityContext implements ClaimsSecurityContext {
+    
+    private final Principal principal;
+    private Set<Principal> roles;
+    private Element assertionElement;
+    private String issuer;
+    private ClaimCollection claims;
+    
+    public SAMLSecurityContext(Principal principal) {
+        this(principal, null);
+    }
+    
+    public SAMLSecurityContext(
+        Principal principal, 
+        Set<Principal> roles
+    ) {
+        this(principal, roles, null);
+    }
+    
+    public SAMLSecurityContext(
+        Principal principal, 
+        Set<Principal> roles,
+        ClaimCollection claims
+    ) {
+        this.principal = principal;
+        this.roles = roles;
+        this.claims = claims;
+    }
+    
+    public ClaimCollection getClaims() {
+        return claims;
+    }
+    
+    public Principal getUserPrincipal() {
+        return principal;
+    }
+
+    public boolean isUserInRole(String role) {
+        if (roles == null) {
+            return false;
+        }
+        for (Principal principalRole : roles) {
+            if (principalRole.getName().equals(role)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public javax.security.auth.Subject getSubject() {
+        return null;
+    }
+
+    public void setUserRoles(Set<Principal> userRoles) {
+        this.roles = userRoles;
+    }
+    
+    public Set<Principal> getUserRoles() {
+        return roles;
+    }
+    
+    public void setAssertionElement(Element assertionElement) {
+        this.assertionElement = assertionElement;
+    }
+    
+    public Element getAssertionElement() {
+        return assertionElement;
+    }
+    
+    public void setIssuer(String issuer) {
+        this.issuer = issuer;
+    }
+    
+    public String getIssuer() {
+        return issuer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/interceptor/ClaimsAuthorizingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/interceptor/ClaimsAuthorizingInterceptor.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/interceptor/ClaimsAuthorizingInterceptor.java
new file mode 100644
index 0000000..c0244ea
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/interceptor/ClaimsAuthorizingInterceptor.java
@@ -0,0 +1,244 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rt.security.saml.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ClassHelper;
+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.rt.security.saml.claims.ClaimBean;
+import org.apache.cxf.rt.security.saml.claims.SAMLClaim;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.security.claims.authorization.Claim;
+import org.apache.cxf.security.claims.authorization.ClaimMode;
+import org.apache.cxf.security.claims.authorization.Claims;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.invoker.MethodDispatcher;
+import org.apache.cxf.service.model.BindingOperationInfo;
+
+
+public class ClaimsAuthorizingInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ClaimsAuthorizingInterceptor.class);
+    
+    private static final Set<String> SKIP_METHODS;
+    static {
+        SKIP_METHODS = new HashSet<>();
+        SKIP_METHODS.addAll(Arrays.asList(
+            new String[] {"wait", "notify", "notifyAll", 
+                          "equals", "toString", "hashCode"}));
+    }
+    
+    private Map<String, List<ClaimBean>> claims = new HashMap<>();
+    private Map<String, String> nameAliases = Collections.emptyMap();
+    private Map<String, String> formatAliases = Collections.emptyMap();
+    
+    public ClaimsAuthorizingInterceptor() {
+        super(Phase.PRE_INVOKE);
+    }
+    
+    public void handleMessage(Message message) throws Fault {
+        SecurityContext sc = message.get(SecurityContext.class);
+        if (!(sc instanceof SAMLSecurityContext)) {
+            throw new AccessDeniedException("Security Context is unavailable or unrecognized");
+        }
+        
+        Method method = getTargetMethod(message);
+        
+        if (authorize((SAMLSecurityContext)sc, method)) {
+            return;
+        }
+        
+        throw new AccessDeniedException("Unauthorized");
+    }
+    
+    public void setClaims(Map<String, List<ClaimBean>> claimsMap) {
+        claims.putAll(claimsMap);
+    }
+    
+    protected Method getTargetMethod(Message m) {
+        BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class);
+        if (bop != null) {
+            MethodDispatcher md = (MethodDispatcher) 
+                m.getExchange().get(Service.class).get(MethodDispatcher.class.getName());
+            return md.getMethod(bop);
+        } 
+        Method method = (Method)m.get("org.apache.cxf.resource.method");
+        if (method != null) {
+            return method;
+        }
+        throw new AccessDeniedException("Method is not available : Unauthorized");
+    }
+
+    protected boolean authorize(SAMLSecurityContext sc, Method method) {
+        List<ClaimBean> list = claims.get(method.getName());
+        org.apache.cxf.rt.security.claims.ClaimCollection actualClaims = sc.getClaims();
+        
+        for (ClaimBean claimBean : list) {
+            org.apache.cxf.rt.security.claims.Claim claim = claimBean.getClaim();
+            org.apache.cxf.rt.security.claims.Claim matchingClaim = null;
+            for (org.apache.cxf.rt.security.claims.Claim cl : actualClaims) {
+                if (cl instanceof SAMLClaim
+                    && ((SAMLClaim)cl).getName().equals(((SAMLClaim)claim).getName())
+                    && ((SAMLClaim)cl).getNameFormat().equals(((SAMLClaim)claim).getNameFormat())) {
+                    matchingClaim = cl;
+                    break;
+                }
+            }
+            if (matchingClaim == null) {
+                if (claimBean.getClaimMode() == ClaimMode.STRICT) {
+                    return false;
+                } else {
+                    continue;
+                }
+            }
+            List<Object> claimValues = claim.getValues();
+            List<Object> matchingClaimValues = matchingClaim.getValues();
+            if (claimBean.isMatchAll() 
+                && !matchingClaimValues.containsAll(claimValues)) {    
+                return false;
+            } else {
+                boolean matched = false;
+                for (Object value : matchingClaimValues) {
+                    if (claimValues.contains(value)) {
+                        matched = true;    
+                        break;
+                    }
+                }
+                if (!matched) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    
+    public void setSecuredObject(Object object) {
+        Class<?> cls = ClassHelper.getRealClass(object);
+        findClaims(cls);
+        if (claims.isEmpty()) {
+            LOG.warning("The claims list is empty, the service object is not protected");
+        }
+    }
+
+    protected void findClaims(Class<?> cls) {
+        if (cls == null || cls == Object.class) {
+            return;
+        }
+        List<ClaimBean> clsClaims = 
+            getClaims(cls.getAnnotation(Claims.class), cls.getAnnotation(Claim.class));
+        for (Method m : cls.getMethods()) {
+            if (SKIP_METHODS.contains(m.getName())) {
+                continue;
+            }
+            List<ClaimBean> methodClaims = 
+                getClaims(m.getAnnotation(Claims.class), m.getAnnotation(Claim.class));
+            
+            List<ClaimBean> allClaims = new ArrayList<>(methodClaims);
+            for (ClaimBean bean : clsClaims) {
+                if (isClaimOverridden(bean, methodClaims)) {
+                    continue;
+                }
+                allClaims.add(bean);
+            }
+            
+            claims.put(m.getName(), allClaims);
+        }
+        if (!claims.isEmpty()) {
+            return;
+        }
+        
+        findClaims(cls.getSuperclass());
+        
+        if (!claims.isEmpty()) {
+            return;
+        }
+        
+        for (Class<?> interfaceCls : cls.getInterfaces()) {
+            findClaims(interfaceCls);
+        }
+    }
+    
+    private static boolean isClaimOverridden(ClaimBean bean, List<ClaimBean> mClaims) {
+        for (ClaimBean methodBean : mClaims) {    
+            if (bean.getClaim().getName().equals(methodBean.getClaim().getName())
+                && bean.getClaim().getNameFormat().equals(methodBean.getClaim().getNameFormat())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private List<ClaimBean> getClaims(
+            Claims claimsAnn, Claim claimAnn) {
+        List<ClaimBean> claimsList = new ArrayList<>();
+        
+        List<Claim> annClaims = new ArrayList<>();
+        if (claimsAnn != null) {
+            annClaims.addAll(Arrays.asList(claimsAnn.value()));
+        } else if (claimAnn != null) {
+            annClaims.add(claimAnn);
+        }
+        for (Claim ann : annClaims) {
+            SAMLClaim claim = new SAMLClaim();
+            
+            String claimName = ann.name();
+            if (nameAliases.containsKey(claimName)) {
+                claimName = nameAliases.get(claimName);
+            }
+            String claimFormat = ann.format();
+            if (formatAliases.containsKey(claimFormat)) {
+                claimFormat = formatAliases.get(claimFormat);
+            }
+            
+            claim.setName(claimName);
+            claim.setNameFormat(claimFormat);
+            for (String value : ann.value()) {
+                claim.addValue(value);
+            }
+            
+            claimsList.add(new ClaimBean(claim, ann.mode(), ann.matchAll()));
+        }
+        return claimsList;
+    }
+
+    public void setNameAliases(Map<String, String> nameAliases) {
+        this.nameAliases = nameAliases;
+    }
+
+    public void setFormatAliases(Map<String, String> formatAliases) {
+        this.formatAliases = formatAliases;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java
new file mode 100644
index 0000000..5cb5bd6
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java
@@ -0,0 +1,141 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rt.security.saml.utils;
+
+import java.net.URI;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.rt.security.claims.Claim;
+import org.apache.cxf.rt.security.claims.ClaimCollection;
+import org.apache.cxf.rt.security.saml.claims.SAMLClaim;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.saml.common.SAMLVersion;
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.core.AttributeStatement;
+
+public final class SAMLUtils {
+    
+    private SAMLUtils() {
+        
+    }
+    
+    /**
+     * Extract Claims from a SAML Assertion
+     */
+    public static ClaimCollection getClaims(SamlAssertionWrapper assertion) {
+        ClaimCollection claims = new ClaimCollection();
+        
+        if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)) {
+            List<AttributeStatement> statements = assertion.getSaml2().getAttributeStatements();
+            for (AttributeStatement as : statements) {
+                for (Attribute atr : as.getAttributes()) {
+                    SAMLClaim claim = new SAMLClaim();
+                    claim.setClaimType(URI.create(atr.getName()));
+                    
+                    claim.setName(atr.getName());
+                    claim.setNameFormat(atr.getNameFormat());
+                    claim.setFriendlyName(atr.getFriendlyName());
+                    
+                    for (XMLObject o : atr.getAttributeValues()) {
+                        String attrValue = o.getDOM().getTextContent();
+                        claim.getValues().add(attrValue);
+                    }
+                    
+                    claims.add(claim);
+                }
+            }
+        } else {
+            List<org.opensaml.saml.saml1.core.AttributeStatement> attributeStatements = 
+                assertion.getSaml1().getAttributeStatements();
+            
+            for (org.opensaml.saml.saml1.core.AttributeStatement statement : attributeStatements) {
+                for (org.opensaml.saml.saml1.core.Attribute atr : statement.getAttributes()) {
+                    SAMLClaim claim = new SAMLClaim();
+                    
+                    String claimType = atr.getAttributeName();
+                    if (atr.getAttributeNamespace() != null) {
+                        claimType = atr.getAttributeNamespace() + "/" + claimType;
+                    }
+                    claim.setClaimType(URI.create(claimType));
+
+                    claim.setName(atr.getAttributeName());
+                    claim.setNameFormat(atr.getAttributeNamespace());
+
+                    for (XMLObject o : atr.getAttributeValues()) {
+                        String attrValue = o.getDOM().getTextContent();
+                        claim.getValues().add(attrValue);
+                    }
+
+                    claims.add(claim);
+                }
+            } 
+        }
+        
+        return claims;
+    }
+    
+    /**
+     * Extract roles from the given Claims
+     */
+    public static Set<Principal> parseRolesFromClaims(
+        ClaimCollection claims,
+        String name,
+        String nameFormat
+    ) {
+        String roleAttributeName = name;
+        if (roleAttributeName == null) {
+            roleAttributeName = SAMLClaim.SAML_ROLE_ATTRIBUTENAME_DEFAULT;
+        }
+        
+        Set<Principal> roles = new HashSet<>();
+        
+        for (Claim claim : claims) {
+            if (claim instanceof SAMLClaim && ((SAMLClaim)claim).getName().equals(name)
+                && (nameFormat == null 
+                    || claim instanceof SAMLClaim && nameFormat.equals(((SAMLClaim)claim).getNameFormat()))) {
+                for (Object claimValue : claim.getValues()) {
+                    if (claimValue instanceof String) {
+                        roles.add(new SimpleGroup((String)claimValue));
+                    }
+                }
+                if (claim.getValues().size() > 1) {
+                    // Don't search for other attributes with the same name if > 1 claim value
+                    break;
+                }
+            }
+        }
+        
+        return roles;
+    }
+    
+    public static String getIssuer(Object assertion) {
+        return ((SamlAssertionWrapper)assertion).getIssuerString();
+    }
+
+    public static Element getAssertionElement(Object assertion) {
+        return ((SamlAssertionWrapper)assertion).getElement();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/AbstractXACMLAuthorizingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/AbstractXACMLAuthorizingInterceptor.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/AbstractXACMLAuthorizingInterceptor.java
new file mode 100644
index 0000000..590b324
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/AbstractXACMLAuthorizingInterceptor.java
@@ -0,0 +1,170 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.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 org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+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.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,
+ * 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.
+ * 
+ * @deprecated: Use XACMLAuthorizingInterceptor instead
+ */
+@Deprecated
+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<>();
+            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"
+            );
+        }
+        
+        throw new AccessDeniedException("Unauthorized");
+    }
+    
+    public XACMLRequestBuilder getRequestBuilder() {
+        return requestBuilder;
+    }
+
+    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);
+        
+        List<ResultType> results = response.getResults();
+        
+        if (results == null) {
+            return false;
+        }
+        
+        for (ResultType result : results) {
+            // Handle any Obligations returned by the PDP
+            handleObligations(request, principal, message, result);
+            
+            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() : "";
+            }
+            LOG.fine("XACML authorization result: " + decision + ", code: " + code + ", message: " + statusMessage);
+            return decision == DECISION.Permit;
+        }
+        
+        return false;
+    }
+    
+    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
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/CXFMessageParser.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/CXFMessageParser.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/CXFMessageParser.java
new file mode 100644
index 0000000..1af0f5e
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/CXFMessageParser.java
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rt.security.saml.xacml;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+
+public class CXFMessageParser {
+    private Message message;
+
+    /**
+     * @param message
+     */
+    public CXFMessageParser(Message message) {
+        this.message = message;
+    }
+    
+    public boolean isSOAPService() {
+        return getWSDLOperation() != null;
+    }
+
+    public QName getWSDLOperation() {
+        if (message != null && message.get(Message.WSDL_OPERATION) != null) {
+            return (QName)message.get(Message.WSDL_OPERATION);
+        }
+        return null;
+    }
+    
+    public QName getWSDLService() {
+        if (message != null && message.get(Message.WSDL_SERVICE) != null) {
+            return (QName)message.get(Message.WSDL_SERVICE);
+        }
+        return null;
+    }
+    
+    /**
+     * @param fullRequestURL Whether to send the full Request URL as the resource or not. If set to true, the
+     *        full Request URL will be sent for both a JAX-WS and JAX-RS service. If set to false (the
+     *        default), a JAX-WS service will send the "{namespace}operation" QName, and a JAX-RS service
+     *        will send the RequestURI (i.e. minus the initial https:<ip> prefix)
+     */
+    public String getResourceURI(boolean fullRequestURL) {
+        String property = fullRequestURL ? Message.REQUEST_URL : Message.REQUEST_URI;
+        if (message != null && message.get(property) != null) {
+            return (String)message.get(property);
+        }
+        return null;
+    }
+
+    public String getAction(String defaultSOAPAction) {
+        String actionToUse = defaultSOAPAction;
+        // For REST use the HTTP Verb
+        if (message.get(Message.WSDL_OPERATION) == null && message.get(Message.HTTP_REQUEST_METHOD) != null) {
+            actionToUse = (String)message.get(Message.HTTP_REQUEST_METHOD);
+        }
+        return actionToUse;
+    }
+
+    /**
+     * Get the Issuer of the SAML Assertion
+     */
+    public String getIssuer() throws WSSecurityException {
+        SecurityContext sc = message.get(SecurityContext.class);
+
+        if (sc instanceof SAMLSecurityContext) {
+            Element assertionElement = ((SAMLSecurityContext)sc).getAssertionElement();
+            if (assertionElement != null) {
+                SamlAssertionWrapper wrapper = new SamlAssertionWrapper(assertionElement);
+                return wrapper.getIssuerString();
+            }
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/DefaultXACMLRequestBuilder.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/DefaultXACMLRequestBuilder.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/DefaultXACMLRequestBuilder.java
new file mode 100644
index 0000000..02d115f
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/DefaultXACMLRequestBuilder.java
@@ -0,0 +1,217 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.xacml;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.message.Message;
+import org.joda.time.DateTime;
+import org.opensaml.xacml.ctx.ActionType;
+import org.opensaml.xacml.ctx.AttributeType;
+import org.opensaml.xacml.ctx.AttributeValueType;
+import org.opensaml.xacml.ctx.EnvironmentType;
+import org.opensaml.xacml.ctx.RequestType;
+import org.opensaml.xacml.ctx.ResourceType;
+import org.opensaml.xacml.ctx.SubjectType;
+
+/**
+ * This class constructs an XACML Request given a Principal, list of roles and MessageContext, 
+ * following the SAML 2.0 profile of XACML 2.0. The principal name is inserted as the Subject ID,
+ * and the list of roles associated with that principal are inserted as Subject roles. The action
+ * to send defaults to "execute". 
+ * 
+ * For a SOAP Service, the resource-id Attribute refers to the 
+ * "{serviceNamespace}serviceName#{operationNamespace}operationName" String (shortened to
+ * "{serviceNamespace}serviceName#operationName" if the namespaces are identical). The 
+ * "{serviceNamespace}serviceName", "{operationNamespace}operationName" and resource URI are also
+ * sent to simplify processing at the PDP side.
+ * 
+ * For a REST service the request URL is the resource. You can also configure the ability to 
+ * send the truncated request URI instead for a SOAP or REST service. The current DateTime is 
+ * also sent in an Environment, however this can be disabled via configuration.
+ */
+public class DefaultXACMLRequestBuilder implements XACMLRequestBuilder {
+
+    private boolean sendDateTime = true;
+    private String action = "execute";
+    private boolean sendFullRequestURL = true;
+
+    /**
+     * Create an XACML Request given a Principal, list of roles and Message.
+     */
+    public RequestType createRequest(Principal principal, List<String> roles, Message message)
+        throws Exception {
+        CXFMessageParser messageParser = new CXFMessageParser(message);
+        String issuer = messageParser.getIssuer();
+        
+        String actionToUse = messageParser.getAction(action);
+
+        SubjectType subjectType = createSubjectType(principal, roles, issuer);
+        ResourceType resourceType = createResourceType(messageParser);
+        AttributeType actionAttribute = createAttribute(XACMLConstants.ACTION_ID, XACMLConstants.XS_STRING,
+                                                        null, actionToUse);
+        ActionType actionType = RequestComponentBuilder.createActionType(Collections.singletonList(actionAttribute));
+
+        return RequestComponentBuilder.createRequestType(Collections.singletonList(subjectType),
+                                                         Collections.singletonList(resourceType), 
+                                                         actionType,
+                                                         createEnvironmentType());
+    }
+
+    private ResourceType createResourceType(CXFMessageParser messageParser) {
+        List<AttributeType> attributes = new ArrayList<>();
+        
+        // Resource-id
+        String resourceId = null;
+        boolean isSoapService = messageParser.isSOAPService();
+        if (isSoapService) {
+            QName serviceName = messageParser.getWSDLService();
+            QName operationName = messageParser.getWSDLOperation();
+            
+            if (serviceName != null) {
+                resourceId = serviceName.toString() + "#";
+                if (serviceName.getNamespaceURI() != null 
+                    && serviceName.getNamespaceURI().equals(operationName.getNamespaceURI())) {
+                    resourceId += operationName.getLocalPart();
+                } else {
+                    resourceId += operationName.toString();
+                }
+            } else {
+                resourceId = operationName.toString();
+            }
+        } else {
+            resourceId = messageParser.getResourceURI(sendFullRequestURL);
+        }
+        
+        attributes.add(createAttribute(XACMLConstants.RESOURCE_ID, XACMLConstants.XS_STRING, null,
+                                           resourceId));
+        
+        if (isSoapService) {
+            // WSDL Service
+            QName wsdlService = messageParser.getWSDLService();
+            if (wsdlService != null) {
+                attributes.add(createAttribute(XACMLConstants.RESOURCE_WSDL_SERVICE_ID, XACMLConstants.XS_STRING, null,
+                                           wsdlService.toString()));
+            }
+            
+            // WSDL Operation
+            QName wsdlOperation = messageParser.getWSDLOperation();
+            attributes.add(createAttribute(XACMLConstants.RESOURCE_WSDL_OPERATION_ID, XACMLConstants.XS_STRING, null,
+                                           wsdlOperation.toString()));
+            
+            // WSDL Endpoint
+            String endpointURI = messageParser.getResourceURI(sendFullRequestURL);
+            attributes.add(createAttribute(XACMLConstants.RESOURCE_WSDL_ENDPOINT, XACMLConstants.XS_STRING, null,
+                                           endpointURI));
+        }
+        
+        return RequestComponentBuilder.createResourceType(attributes, null);
+    }
+
+    private EnvironmentType createEnvironmentType() {
+        if (sendDateTime) {
+            List<AttributeType> attributes = new ArrayList<>();
+            AttributeType environmentAttribute = createAttribute(XACMLConstants.CURRENT_DATETIME,
+                                                                 XACMLConstants.XS_DATETIME, null,
+                                                                 new DateTime().toString());
+            attributes.add(environmentAttribute);
+            return RequestComponentBuilder.createEnvironmentType(attributes);
+        }
+        
+        List<AttributeType> attributes = Collections.emptyList();
+        return RequestComponentBuilder.createEnvironmentType(attributes);
+    }
+
+    private SubjectType createSubjectType(Principal principal, List<String> roles, String issuer) {
+        List<AttributeType> attributes = new ArrayList<>();
+        attributes.add(createAttribute(XACMLConstants.SUBJECT_ID, XACMLConstants.XS_STRING, issuer,
+                                       principal.getName()));
+
+        if (roles != null) {
+            List<AttributeValueType> roleAttributes = new ArrayList<>();
+            for (String role : roles) {
+                if (role != null) {
+                    AttributeValueType subjectRoleAttributeValue = 
+                        RequestComponentBuilder.createAttributeValueType(role);
+                    roleAttributes.add(subjectRoleAttributeValue);
+                }
+            }
+
+            if (!roleAttributes.isEmpty()) {
+                AttributeType subjectRoleAttribute = 
+                    createAttribute(
+                        XACMLConstants.SUBJECT_ROLE,
+                        XACMLConstants.XS_ANY_URI,
+                        issuer,
+                        roleAttributes
+                    );
+                attributes.add(subjectRoleAttribute);
+            }
+        }
+
+        return RequestComponentBuilder.createSubjectType(attributes, null);
+    }
+
+    private AttributeType createAttribute(String id, String type, String issuer, List<AttributeValueType> values) {
+        return RequestComponentBuilder.createAttributeType(id, type, issuer, values);
+    }
+    
+    private AttributeType createAttribute(String id, String type, String issuer, String value) {
+        return createAttribute(id, type, issuer, 
+                               Collections.singletonList(RequestComponentBuilder.createAttributeValueType(value)));
+    }
+
+    /**
+     * Set a new Action String to use
+     */
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public void setSendDateTime(boolean sendDateTime) {
+        this.sendDateTime = sendDateTime;
+    }
+
+    /**
+     * Whether to send the full Request URL as the resource or not. If set to true,
+     * the full Request URL will be sent for both a JAX-WS and JAX-RS service. If set
+     * to false (the default), a JAX-WS service will send the "{namespace}operation" QName,
+     * and a JAX-RS service will send the RequestURI (i.e. minus the initial https:<ip> prefix).
+     */
+    public void setSendFullRequestURL(boolean sendFullRequestURL) {
+        this.sendFullRequestURL = sendFullRequestURL;
+    }
+
+    @Override
+    public List<String> getResources(Message message) {
+        throw new IllegalAccessError("Deprecated");
+    }
+
+    @Override
+    public String getResource(Message message) {
+        throw new IllegalAccessError("Deprecated");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/RequestComponentBuilder.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/RequestComponentBuilder.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/RequestComponentBuilder.java
new file mode 100644
index 0000000..08f8da8
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/RequestComponentBuilder.java
@@ -0,0 +1,183 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.xacml;
+
+import java.util.List;
+
+import org.opensaml.core.xml.XMLObjectBuilderFactory;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.xacml.XACMLObjectBuilder;
+import org.opensaml.xacml.ctx.ActionType;
+import org.opensaml.xacml.ctx.AttributeType;
+import org.opensaml.xacml.ctx.AttributeValueType;
+import org.opensaml.xacml.ctx.EnvironmentType;
+import org.opensaml.xacml.ctx.RequestType;
+import org.opensaml.xacml.ctx.ResourceContentType;
+import org.opensaml.xacml.ctx.ResourceType;
+import org.opensaml.xacml.ctx.SubjectType;
+
+/**
+ * A set of utility methods to construct XACML 2.0 Request statements
+ */
+public final class RequestComponentBuilder {
+    private static volatile XACMLObjectBuilder<AttributeValueType> attributeValueTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<AttributeType> attributeTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<SubjectType> subjectTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<ResourceType> resourceTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<ActionType> actionTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<EnvironmentType> environmentTypeBuilder;
+    
+    private static volatile XACMLObjectBuilder<RequestType> requestTypeBuilder;
+    
+    private static volatile XMLObjectBuilderFactory builderFactory = 
+        XMLObjectProviderRegistrySupport.getBuilderFactory();
+    
+    private RequestComponentBuilder() {
+        // complete
+    }
+
+    @SuppressWarnings("unchecked")
+    public static AttributeValueType createAttributeValueType(
+        String value
+    ) {
+        if (attributeValueTypeBuilder == null) {
+            attributeValueTypeBuilder = (XACMLObjectBuilder<AttributeValueType>)
+                builderFactory.getBuilder(AttributeValueType.DEFAULT_ELEMENT_NAME);
+        }
+        AttributeValueType attributeValue = attributeValueTypeBuilder.buildObject();
+        attributeValue.setValue(value);
+        
+        return attributeValue;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static AttributeType createAttributeType(
+        String attributeId,
+        String dataType,
+        String issuer,
+        List<AttributeValueType> attributeValues
+    ) {
+        if (attributeTypeBuilder == null) {
+            attributeTypeBuilder = (XACMLObjectBuilder<AttributeType>)
+                builderFactory.getBuilder(AttributeType.DEFAULT_ELEMENT_NAME);
+        }
+        AttributeType attributeType = attributeTypeBuilder.buildObject();
+        attributeType.setAttributeID(attributeId);
+        attributeType.setDataType(dataType);
+        attributeType.setIssuer(issuer);
+        attributeType.getAttributeValues().addAll(attributeValues);
+        
+        return attributeType;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static SubjectType createSubjectType(
+        List<AttributeType> attributes,
+        String subjectCategory
+    ) {
+        if (subjectTypeBuilder == null) {
+            subjectTypeBuilder = (XACMLObjectBuilder<SubjectType>)
+                builderFactory.getBuilder(SubjectType.DEFAULT_ELEMENT_NAME);
+        }
+        SubjectType subject = subjectTypeBuilder.buildObject();
+        if (attributes != null) {
+            subject.getAttributes().addAll(attributes);
+        }
+        subject.setSubjectCategory(subjectCategory);
+        
+        return subject;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static ResourceType createResourceType(
+        List<AttributeType> attributes,
+        ResourceContentType resourceContent
+    ) {
+        if (resourceTypeBuilder == null) {
+            resourceTypeBuilder = (XACMLObjectBuilder<ResourceType>)
+                builderFactory.getBuilder(ResourceType.DEFAULT_ELEMENT_NAME);
+        }
+        ResourceType resource = resourceTypeBuilder.buildObject();
+        if (attributes != null) {
+            resource.getAttributes().addAll(attributes);
+        }
+        resource.setResourceContent(resourceContent);
+        
+        return resource;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static ActionType createActionType(
+        List<AttributeType> attributes
+    ) {
+        if (actionTypeBuilder == null) {
+            actionTypeBuilder = (XACMLObjectBuilder<ActionType>)
+                builderFactory.getBuilder(ActionType.DEFAULT_ELEMENT_NAME);
+        }
+        ActionType action = actionTypeBuilder.buildObject();
+        if (attributes != null) {
+            action.getAttributes().addAll(attributes);
+        }
+        
+        return action;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static EnvironmentType createEnvironmentType(
+        List<AttributeType> attributes
+    ) {
+        if (environmentTypeBuilder == null) {
+            environmentTypeBuilder = (XACMLObjectBuilder<EnvironmentType>)
+                builderFactory.getBuilder(EnvironmentType.DEFAULT_ELEMENT_NAME);
+        }
+        EnvironmentType enviroment = environmentTypeBuilder.buildObject();
+        if (attributes != null) {
+            enviroment.getAttributes().addAll(attributes);
+        }
+        
+        return enviroment;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static RequestType createRequestType(
+        List<SubjectType> subjects,
+        List<ResourceType> resources,
+        ActionType action,
+        EnvironmentType environment
+    ) {
+        if (requestTypeBuilder == null) {
+            requestTypeBuilder = (XACMLObjectBuilder<RequestType>)
+                builderFactory.getBuilder(RequestType.DEFAULT_ELEMENT_NAME);
+        }
+        RequestType request = requestTypeBuilder.buildObject();
+        request.getSubjects().addAll(subjects);
+        request.getResources().addAll(resources);
+        request.setAction(action);
+        request.setEnvironment(environment);
+        
+        return request;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/SamlRequestComponentBuilder.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/SamlRequestComponentBuilder.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/SamlRequestComponentBuilder.java
new file mode 100644
index 0000000..c0d8255
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/SamlRequestComponentBuilder.java
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.xacml;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.opensaml.core.xml.XMLObjectBuilderFactory;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.saml.common.SAMLObjectBuilder;
+import org.opensaml.saml.common.SAMLVersion;
+import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.xacml.XACMLObjectBuilder;
+import org.opensaml.xacml.ctx.RequestType;
+import org.opensaml.xacml.profile.saml.SAMLProfileConstants;
+import org.opensaml.xacml.profile.saml.XACMLAuthzDecisionQueryType;
+
+/**
+ * A set of utility methods to construct XACML SAML Request statements, based on the
+ * SAML 2.0 profile of XACML v2.0 specification.
+ */
+public final class SamlRequestComponentBuilder {
+    private static volatile XACMLObjectBuilder<XACMLAuthzDecisionQueryType> xacmlAuthzDecisionQueryTypeBuilder;
+    
+    private static volatile SAMLObjectBuilder<Issuer> issuerBuilder;
+    
+    private static volatile XMLObjectBuilderFactory builderFactory = 
+        XMLObjectProviderRegistrySupport.getBuilderFactory();
+    
+    private SamlRequestComponentBuilder() {
+        // complete
+    }
+    
+    /**
+     * Create an AuthzDecisionQuery using the defaults
+     */
+    public static XACMLAuthzDecisionQueryType createAuthzDecisionQuery(
+        String issuerValue,
+        RequestType request,
+        String namespace
+    ) {
+        return createAuthzDecisionQuery(false, false, issuerValue, request, namespace);
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static XACMLAuthzDecisionQueryType createAuthzDecisionQuery(
+        boolean inputContextOnly,
+        boolean returnContext,
+        String issuerValue,
+        RequestType request,
+        String namespace
+    ) {
+        if (xacmlAuthzDecisionQueryTypeBuilder == null) {
+            xacmlAuthzDecisionQueryTypeBuilder = (XACMLObjectBuilder<XACMLAuthzDecisionQueryType>)
+                builderFactory.getBuilder(XACMLAuthzDecisionQueryType.DEFAULT_ELEMENT_NAME_XACML20);
+        }
+        XACMLAuthzDecisionQueryType authzQuery = 
+            xacmlAuthzDecisionQueryTypeBuilder.buildObject(
+                namespace,
+                XACMLAuthzDecisionQueryType.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLProfileConstants.SAML20XACMLPROTOCOL_PREFIX
+            );
+        authzQuery.setID("_" + UUID.randomUUID().toString());
+        authzQuery.setVersion(SAMLVersion.VERSION_20);
+        authzQuery.setIssueInstant(new DateTime());
+        authzQuery.setInputContextOnly(Boolean.valueOf(inputContextOnly));
+        authzQuery.setReturnContext(Boolean.valueOf(returnContext));
+        
+        if (issuerValue != null) {
+            Issuer issuer = createIssuer(issuerValue);
+            authzQuery.setIssuer(issuer);
+        }
+        
+        authzQuery.setRequest(request);
+        
+        return authzQuery;
+    }
+    
+    
+    /**
+     * Create an Issuer object
+     *
+     * @param issuerValue of type String
+     * @return an Issuer object
+     */
+    @SuppressWarnings("unchecked")
+    public static Issuer createIssuer(String issuerValue) {
+        if (issuerBuilder == null) {
+            issuerBuilder = (SAMLObjectBuilder<Issuer>) 
+                builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
+            
+        }
+        Issuer issuer = issuerBuilder.buildObject();
+        //
+        // The SAML authority that is making the claim(s) in the assertion. The issuer SHOULD 
+        // be unambiguous to the intended relying parties.
+        issuer.setValue(issuerValue);
+        return issuer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c04c2720/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/XACMLAuthorizingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/XACMLAuthorizingInterceptor.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/XACMLAuthorizingInterceptor.java
new file mode 100644
index 0000000..065c5a9
--- /dev/null
+++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/xacml/XACMLAuthorizingInterceptor.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rt.security.saml.xacml;
+
+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.message.Message;
+import org.apache.cxf.rt.security.saml.xacml.pdp.api.PolicyDecisionPoint;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.opensaml.xacml.ctx.RequestType;
+import org.opensaml.xacml.ctx.ResponseType;
+
+/**
+ * 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. 
+ */
+@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);
+        }
+        return new DOMSource(requestElement);
+    }
+
+    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);
+        }
+    }
+}


Mime
View raw message