Take the application realm from the SAML AuthnRequest Issuer

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

Branch: refs/heads/master
Commit: 6abaf2715c007a5d1a14f89c4ec859b4dd30b6aa
Parents: d1adf65
Author: Colm O hEigeartaigh <cohei...@apache.org>
Authored: Tue Mar 15 15:29:42 2016 +0000
Committer: Colm O hEigeartaigh <cohei...@apache.org>
Committed: Tue Mar 15 15:29:42 2016 +0000

----------------------------------------------------------------------
 .../service/idp/beans/STSClientAction.java      |  24 +-
 .../beans/samlsso/AuthnRequestRealmParser.java  |  81 +++++
 .../flows/federation-validate-request.xml       |   2 +-
 .../WEB-INF/flows/saml-validate-request.xml     |   8 +-
 systests/samlsso/out.txt                        | 312 ++++++++++---------
 .../apache/cxf/fediz/systests/idp/IdpTest.java  |  47 ++-
 .../test/resources/realma/entities-realma.xml   |   5 -
 7 files changed, 300 insertions(+), 179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/6abaf271/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java
 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java
index 6b4e07d..3efd103 100644
--- 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java
@@ -177,16 +177,14 @@ public class STSClientAction {
     }
     
     /**
-     * @param context
-     *            the webflow request context
+     * @param realm The client/application realm
+     * @param context the webflow request context
      * @return a serialized RP security token
      * @throws Exception
      */
-    public String submit(RequestContext context)
+    public String submit(String realm, RequestContext context)
         throws Exception {
         
-        String wtrealm = (String)WebUtils.getAttributeFromFlowScope(context, 
FederationConstants.PARAM_TREALM);
-
         SecurityToken idpToken = getSecurityToken(context);
 
         Idp idpConfig = (Idp) WebUtils.getAttributeFromFlowScope(context, 
IDP_CONFIG);
@@ -196,9 +194,9 @@ public class STSClientAction {
         IdpSTSClient sts = new IdpSTSClient(cxfBus);
         sts.setAddressingNamespace(HTTP_WWW_W3_ORG_2005_08_ADDRESSING);
         
-        Application serviceConfig = idpConfig.findApplication(wtrealm);
+        Application serviceConfig = idpConfig.findApplication(realm);
         if (serviceConfig == null) {
-            LOG.warn("No service config found for " + wtrealm);
+            LOG.warn("No service config found for " + realm);
             throw new ProcessingException(TYPE.BAD_REQUEST);
         }
         
@@ -245,7 +243,7 @@ public class STSClientAction {
             sts.setWspNamespace(serviceConfig.getPolicyNamespace());
         }
         
-        LOG.debug("TokenType {} set for realm {}", sts.getTokenType(), 
wtrealm);
+        LOG.debug("TokenType {} set for realm {}", sts.getTokenType(), realm);
         
         sts.setKeyType(stsKeyType);
         if 
(HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_PUBLICKEY.equals(stsKeyType)) {
@@ -273,22 +271,22 @@ public class STSClientAction {
 
         if (serviceConfig.getRequestedClaims() != null && 
serviceConfig.getRequestedClaims().size() > 0) {
             addClaims(sts, serviceConfig.getRequestedClaims());
-            LOG.debug("Requested claims set for {}", wtrealm);
+            LOG.debug("Requested claims set for {}", realm);
         }
         
         sts.setEnableLifetime(true);
-        setLifetime(sts, serviceConfig, wtrealm);
+        setLifetime(sts, serviceConfig, realm);
         
         sts.setOnBehalfOf(idpToken.getToken());
         if (!(serviceConfig.getProtocol() == null
             || 
FederationConstants.WS_FEDERATION_NS.equals(serviceConfig.getProtocol()))) {
-            LOG.error("Protocol {} not supported for realm {} ", 
serviceConfig.getProtocol(), wtrealm);
+            LOG.error("Protocol {} not supported for realm {} ", 
serviceConfig.getProtocol(), realm);
             throw new ProcessingException(TYPE.BAD_REQUEST);
         }
         
         String rpToken = null;
         try {
-            rpToken = sts.requestSecurityTokenResponse(wtrealm);
+            rpToken = sts.requestSecurityTokenResponse(realm);
         } catch (SoapFault ex) {
             LOG.error("Error in retrieving a token", ex.getMessage());
             if (ex.getFaultCode() != null 
@@ -302,7 +300,7 @@ public class STSClientAction {
             String id = getIdFromToken(rpToken);
             
             LOG.info("[RP_TOKEN={}] successfully created for realm [{}] on 
behalf of [IDP_TOKEN={}]",
-                     id, wtrealm, idpToken.getId());
+                     id, realm, idpToken.getId());
         }
         return StringEscapeUtils.escapeXml11(rpToken);
     }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/6abaf271/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
new file mode 100644
index 0000000..8319821
--- /dev/null
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestRealmParser.java
@@ -0,0 +1,81 @@
+/**
+ * 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/6abaf271/services/idp/src/main/webapp/WEB-INF/flows/federation-validate-request.xml
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/webapp/WEB-INF/flows/federation-validate-request.xml 
b/services/idp/src/main/webapp/WEB-INF/flows/federation-validate-request.xml
index 8c020df..b22f48e 100644
--- a/services/idp/src/main/webapp/WEB-INF/flows/federation-validate-request.xml
+++ b/services/idp/src/main/webapp/WEB-INF/flows/federation-validate-request.xml
@@ -136,7 +136,7 @@
     <!-- produce RP security token (as String type) -->
     <action-state id="requestRpToken">
         <on-entry>
-            <evaluate 
expression="stsClientForRpAction.submit(flowRequestContext)"
+            <evaluate 
expression="stsClientForRpAction.submit(flowScope.wtrealm, flowRequestContext)"
                       result="flowScope.rpToken"/>
         </on-entry>
         <evaluate 
expression="signinParametersCacheAction.storeRPConfigInSession(flowRequestContext)"
 />

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/6abaf271/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 8070ecd..f5734b6 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
@@ -37,8 +37,8 @@
 
     <subflow-state id="signinSAMLRequest" subflow="signinSAMLRequest">
         <input name="idpConfig" value="flowScope.idpConfig" />
-        <input name="wauth" value="flowScope.wauth" />
-        <input name="whr" value="flowScope.whr" />
+        <input name="SAMLRequest" value="flowScope.SAMLRequest" />
+        <input name="RelayState" value="flowScope.RelayState" />
 
         <output name="whr" />
         <output name="idpToken" />
@@ -58,7 +58,9 @@
     <!-- produce RP security token (as String type) -->
     <action-state id="requestRpToken">
         <on-entry>
-            <evaluate 
expression="stsClientForRpAction.submit(flowRequestContext)"
+            <evaluate 
expression="authnRequestRealmParser.retrieveRealm(flowRequestContext)" 
+                      result="flowScope.realm"/>
+            <evaluate expression="stsClientForRpAction.submit(flowScope.realm, 
flowRequestContext)"
                       result="flowScope.rpToken"/>
         </on-entry>
         <evaluate 
expression="signinParametersCacheAction.storeRPConfigInSession(flowRequestContext)"/>

Reply via email to