Set the Form "action" from the AuthnRequest AssertionConsumerURL

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

Branch: refs/heads/master
Commit: feae9f28afb273b21dc5dcf8ce9f064137fea664
Parents: 6abaf27
Author: Colm O hEigeartaigh <[email protected]>
Authored: Tue Mar 15 17:02:10 2016 +0000
Committer: Colm O hEigeartaigh <[email protected]>
Committed: Tue Mar 15 17:02:10 2016 +0000

----------------------------------------------------------------------
 .../cxf/fediz/service/idp/IdpConstants.java     |   5 +
 .../idp/beans/samlsso/AuthnRequestParser.java   | 104 ++++++
 .../beans/samlsso/AuthnRequestRealmParser.java  |  81 -----
 .../WEB-INF/flows/saml-validate-request.xml     |  41 +--
 systests/samlsso/out.txt                        | 325 -------------------
 .../apache/cxf/fediz/systests/idp/IdpTest.java  |  12 +-
 6 files changed, 131 insertions(+), 437 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/feae9f28/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpConstants.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpConstants.java 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpConstants.java
index c754a38..2b007dd 100644
--- 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpConstants.java
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpConstants.java
@@ -28,6 +28,11 @@ public final class IdpConstants {
      */
     public static final String TRUSTED_IDP_CONTEXT = "trusted_idp_context";
     
+    /**
+     * A key used to store a parsed SAMLRequest as an OpenSAML AuthnRequest 
Object
+     */
+    public static final String SAML_AUTHN_REQUEST = "saml_authn_request";
+    
     private IdpConstants() {
         // complete
     }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/feae9f28/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java
 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java
new file mode 100644
index 0000000..52bfecd
--- /dev/null
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.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.fediz.service.idp.beans.samlsso;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.fediz.service.idp.IdpConstants;
+import org.apache.cxf.fediz.service.idp.util.WebUtils;
+import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
+import org.apache.cxf.rs.security.saml.sso.SSOConstants;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.wss4j.common.util.DOM2Writer;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.webflow.execution.RequestContext;
+
+/**
+ * Parse the received SAMLRequest into an OpenSAML AuthnRequest
+ */
+@Component
+public class AuthnRequestParser {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(AuthnRequestParser.class);
+
+    public void parseSAMLRequest(RequestContext context) {
+        String samlRequest = 
context.getFlowScope().getString(SSOConstants.SAML_REQUEST);
+        LOG.debug("Received SAML Request: {}", samlRequest);
+
+        if (samlRequest == null) {
+            WebUtils.removeAttributeFromFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST);
+        } else {
+            try {
+                AuthnRequest parsedRequest = extractRequest(samlRequest);
+                WebUtils.putAttributeInFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST, parsedRequest);
+                LOG.debug("SAML Request with id '{}' successfully parsed", 
parsedRequest.getID());
+            } catch (Exception ex) {
+                LOG.warn("Error parsing request: {}", ex.getMessage());
+            }
+        }
+    }
+    
+    public String retrieveRealm(RequestContext context) {
+        AuthnRequest authnRequest = 
+            (AuthnRequest)WebUtils.getAttributeFromFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST);
+        if (authnRequest != null && authnRequest.getIssuer() != null) {
+            String issuer = authnRequest.getIssuer().getValue();
+            LOG.debug("Parsed SAML AuthnRequest Issuer: {}", issuer);
+            return issuer;
+        }
+        
+        LOG.debug("No AuthnRequest available to be parsed");
+        return null;
+    }
+    
+    public String retrieveConsumerURL(RequestContext context) {
+        AuthnRequest authnRequest = 
+            (AuthnRequest)WebUtils.getAttributeFromFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST);
+
+        if (authnRequest != null && 
authnRequest.getAssertionConsumerServiceURL() != null) {
+            String consumerURL = authnRequest.getAssertionConsumerServiceURL();
+            LOG.debug("Parsed SAML AuthnRequest Consumer URL: {}", 
consumerURL);
+            return consumerURL;
+        }
+        
+        LOG.debug("No AuthnRequest available to be parsed");
+        return null;
+    }
+    
+    private AuthnRequest extractRequest(String samlRequest) throws Exception {
+        byte[] deflatedToken = Base64Utility.decode(samlRequest);
+        InputStream tokenStream = new 
DeflateEncoderDecoder().inflateToken(deflatedToken);
+
+        Document responseDoc = StaxUtils.read(new 
InputStreamReader(tokenStream, "UTF-8"));
+        AuthnRequest request = 
+            
(AuthnRequest)OpenSAMLUtil.fromDom(responseDoc.getDocumentElement());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(DOM2Writer.nodeToString(responseDoc));
+        }
+        return request;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/feae9f28/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestRealmParser.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestRealmParser.java
 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestRealmParser.java
deleted file mode 100644
index 8319821..0000000
--- 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestRealmParser.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * 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.fediz.service.idp.beans.samlsso;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-import org.w3c.dom.Document;
-
-import org.apache.cxf.common.util.Base64Utility;
-import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
-import org.apache.cxf.rs.security.saml.sso.SSOConstants;
-import org.apache.cxf.staxutils.StaxUtils;
-import org.apache.wss4j.common.saml.OpenSAMLUtil;
-import org.apache.wss4j.common.util.DOM2Writer;
-import org.opensaml.saml.saml2.core.AuthnRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.webflow.execution.RequestContext;
-
-/**
- * Parse the received AuthnRequest and extract the home realm of the request 
from the Issuer
- * value.
- */
-@Component
-public class AuthnRequestRealmParser {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(AuthnRequestRealmParser.class);
-
-    public String retrieveRealm(RequestContext context) {
-        String samlRequest = 
context.getFlowScope().getString(SSOConstants.SAML_REQUEST);
-        LOG.debug("Received SAML Request: {}", samlRequest);
-
-        if (samlRequest != null) {
-            try {
-                AuthnRequest parsedRequest = extractRequest(samlRequest);
-                if (parsedRequest.getIssuer() != null) {
-                    String issuer = parsedRequest.getIssuer().getValue();
-                    LOG.debug("Parsed SAML AuthnRequest Issuer: {}", issuer);
-                    return issuer;
-                }
-            } catch (Exception ex) {
-                LOG.warn("Error parsing request: {}", ex.getMessage());
-                return null;
-            }
-        }
-        
-        LOG.debug("No SamlRequest available to be parsed");
-        return null;
-    }
-    
-    private AuthnRequest extractRequest(String samlRequest) throws Exception {
-        byte[] deflatedToken = Base64Utility.decode(samlRequest);
-        InputStream tokenStream = new 
DeflateEncoderDecoder().inflateToken(deflatedToken);
-
-        Document responseDoc = StaxUtils.read(new 
InputStreamReader(tokenStream, "UTF-8"));
-        AuthnRequest request = 
-            
(AuthnRequest)OpenSAMLUtil.fromDom(responseDoc.getDocumentElement());
-        if (LOG.isDebugEnabled()) {
-            LOG.debug(DOM2Writer.nodeToString(responseDoc));
-        }
-        return request;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/feae9f28/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml 
b/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
index f5734b6..55f97d6 100644
--- a/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
+++ b/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
@@ -32,8 +32,13 @@
         <if test="requestParameters.RelayState == null or 
requestParameters.RelayState.length() == 0"
             then="viewBadRequest" />
         <if test="requestParameters.SAMLRequest != null and 
!requestParameters.SAMLRequest.isEmpty()"
-            then="signinSAMLRequest" else="viewBadRequest" />
+            then="parseSAMLRequest" else="viewBadRequest" />
     </decision-state>
+    
+    <action-state id="parseSAMLRequest">
+        <evaluate 
expression="authnRequestParser.parseSAMLRequest(flowRequestContext)" />
+        <transition to="signinSAMLRequest"/>
+    </action-state>
 
     <subflow-state id="signinSAMLRequest" subflow="signinSAMLRequest">
         <input name="idpConfig" value="flowScope.idpConfig" />
@@ -58,15 +63,15 @@
     <!-- produce RP security token (as String type) -->
     <action-state id="requestRpToken">
         <on-entry>
-            <evaluate 
expression="authnRequestRealmParser.retrieveRealm(flowRequestContext)" 
+            <evaluate 
expression="authnRequestParser.retrieveRealm(flowRequestContext)" 
                       result="flowScope.realm"/>
             <evaluate expression="stsClientForRpAction.submit(flowScope.realm, 
flowRequestContext)"
                       result="flowScope.rpToken"/>
+            <evaluate 
expression="authnRequestParser.retrieveConsumerURL(flowRequestContext)" 
+                      result="flowScope.consumerURL"/>
         </on-entry>
         <evaluate 
expression="signinParametersCacheAction.storeRPConfigInSession(flowRequestContext)"/>
-        <transition to="formResponseView" >
-            <set name="flowScope.signinResponseUrl" value="flowScope.wreply" />
-        </transition>
+        <transition to="formResponseView" />
         <transition 
on-exception="org.apache.cxf.fediz.core.exception.ProcessingException" 
to="viewBadRequest" />
         <transition on-exception="java.lang.Throwable" 
to="scInternalServerError" />
     </action-state>
@@ -75,7 +80,7 @@
     <!-- browser redirection (self-submitted form 
'samlsigninresponseform.jsp') -->
     <end-state id="formResponseView" view="samlsigninresponseform">
         <on-entry>
-            <evaluate expression="flowScope.signinResponseUrl" 
result="requestScope.samlAction" />
+            <evaluate expression="flowScope.consumerURL" 
result="requestScope.samlAction" />
             <evaluate expression="flowScope.RelayState" 
result="requestScope.relayState" />
             <evaluate expression="flowScope.rpToken" 
result="requestScope.samlResponse" />
         </on-entry>
@@ -104,30 +109,6 @@
         </on-entry>
     </end-state>
     
-    <!-- normal exit point for logout -->
-    <view-state id="viewSignoutConfirmation" 
view="signoutconfirmationresponse">
-        <transition on="submit" to="invalidateSessionAction"/>
-        <transition on="cancel" to="redirect" />
-    </view-state>
-
-    <view-state id="redirect" view="externalRedirect:${flowScope.wreply}" />
-
-    <!-- normal exit point for logout -->
-    <end-state id="invalidateSessionAction" view="signoutresponse">
-        <on-entry>
-            <!-- store the realmConfigMap in the request map before we 
invalidate the session below.
-            Its needed in the signoutresponse.jsp page -->
-            <set name="externalContext.requestMap.realmConfigMap" 
-                value="externalContext.sessionMap.realmConfigMap"/>
-            <set name="externalContext.requestMap.wreply" 
value="flowScope.wreply"/>
-            <!-- there is no Saml token canceller in cxf STS...
-            <evaluate 
expression="stsClientForRpAction.cancelTokens(flowRequestContext)" />
-            -->
-            <evaluate 
expression="homeRealmReminder.removeCookie(flowRequestContext)" />
-            <evaluate expression="logoutAction.submit(flowRequestContext)" />
-        </on-entry>
-    </end-state>
-
     <end-state id="redirectToLocalIDP" 
view="externalRedirect:${flowScope.localIdpUrl}">
         <on-entry>
             <set name="flowScope.localIdpUrl"

Reply via email to