More refactoring of the spring webflow signin flow
Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/25471cfc Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/25471cfc Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/25471cfc Branch: refs/heads/master Commit: 25471cfcd40237f528dd948b8067fda89360d9bf Parents: 7fa6e4e Author: Colm O hEigeartaigh <[email protected]> Authored: Fri Dec 9 18:02:33 2016 +0000 Committer: Colm O hEigeartaigh <[email protected]> Committed: Fri Dec 9 18:02:33 2016 +0000 ---------------------------------------------------------------------- .../cxf/fediz/service/idp/IdpConstants.java | 18 +++++---- .../idp/beans/SigninParametersCacheAction.java | 40 ++++++++++---------- .../WEB-INF/flows/federation-signin-request.xml | 27 ++++++------- .../flows/federation-validate-request.xml | 4 +- .../WEB-INF/flows/saml-signin-request.xml | 32 ++++++---------- .../WEB-INF/flows/saml-validate-request.xml | 3 ++ 6 files changed, 58 insertions(+), 66 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/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 9a9d70f..bcc5b6f 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 @@ -22,29 +22,33 @@ package org.apache.cxf.fediz.service.idp; public final class IdpConstants { public static final String IDP_CONFIG = "idpConfig"; - + /** * A key used to store context/state when communicating with a trusted third party IdP. */ public static final String TRUSTED_IDP_CONTEXT = "trusted_idp_context"; - + /** * A key used to store the home realm for the given request. */ public static final String HOME_REALM = "home_realm"; - + /** * The SAML Authn Request */ public static final String SAML_AUTHN_REQUEST = "saml_authn_request"; - + /** * A Context variable associated with the request (independent of protocol) */ public static final String CONTEXT = "request_context"; - - - + + /** + * A key used to store the return address for the given request + */ + public static final String RETURN_ADDRESS = "return_address"; + + private IdpConstants() { // complete } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/SigninParametersCacheAction.java ---------------------------------------------------------------------- diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/SigninParametersCacheAction.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/SigninParametersCacheAction.java index 42c8873..5451508 100644 --- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/SigninParametersCacheAction.java +++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/SigninParametersCacheAction.java @@ -45,14 +45,14 @@ public class SigninParametersCacheAction { public void store(RequestContext context, String protocol) { Map<String, Object> signinParams = new HashMap<>(); String uuidKey = UUID.randomUUID().toString(); - + Object value = WebUtils.getAttributeFromFlowScope(context, IdpConstants.HOME_REALM); if (value != null) { signinParams.put(IdpConstants.HOME_REALM, value); } - + if ("wsfed".equals(protocol)) { - value = WebUtils.getAttributeFromFlowScope(context, FederationConstants.PARAM_REPLY); + value = WebUtils.getAttributeFromFlowScope(context, IdpConstants.RETURN_ADDRESS); if (value != null) { signinParams.put(FederationConstants.PARAM_REPLY, value); } @@ -75,29 +75,29 @@ public class SigninParametersCacheAction { signinParams.put(IdpConstants.SAML_AUTHN_REQUEST, value); } } - + WebUtils.putAttributeInExternalContext(context, uuidKey, signinParams); - + LOG.debug("SignIn parameters cached: {}", signinParams.toString()); WebUtils.putAttributeInFlowScope(context, IdpConstants.TRUSTED_IDP_CONTEXT, uuidKey); LOG.info("SignIn parameters cached and context set to [" + uuidKey + "]."); } - + public void restore(RequestContext context, String contextKey, String protocol) { - + if (contextKey != null) { @SuppressWarnings("unchecked") Map<String, Object> signinParams = (Map<String, Object>)WebUtils.getAttributeFromExternalContext(context, contextKey); - + if (signinParams != null) { LOG.debug("SignIn parameters restored: {}", signinParams.toString()); - + String value = (String)signinParams.get(IdpConstants.HOME_REALM); if (value != null) { WebUtils.putAttributeInFlowScope(context, IdpConstants.HOME_REALM, value); } - + if ("wsfed".equals(protocol)) { value = (String)signinParams.get(FederationConstants.PARAM_REPLY); if (value != null) { @@ -107,33 +107,33 @@ public class SigninParametersCacheAction { if (value != null) { WebUtils.putAttributeInFlowScope(context, FederationConstants.PARAM_TREALM, value); } - + WebUtils.removeAttributeFromFlowScope(context, FederationConstants.PARAM_CONTEXT); - LOG.info("SignIn parameters restored and " + FederationConstants.PARAM_CONTEXT + "[" + LOG.info("SignIn parameters restored and " + FederationConstants.PARAM_CONTEXT + "[" + contextKey + "] cleared."); - + value = (String)signinParams.get(FederationConstants.PARAM_CONTEXT); if (value != null) { WebUtils.putAttributeInFlowScope(context, FederationConstants.PARAM_CONTEXT, value); } } else if ("samlsso".equals(protocol)) { - SAMLAuthnRequest authnRequest = + SAMLAuthnRequest authnRequest = (SAMLAuthnRequest)signinParams.get(IdpConstants.SAML_AUTHN_REQUEST); if (authnRequest != null) { WebUtils.putAttributeInFlowScope(context, IdpConstants.SAML_AUTHN_REQUEST, authnRequest); } - + // TODO value = (String)signinParams.get("RelayState"); if (value != null) { WebUtils.putAttributeInFlowScope(context, "RelayState", value); } } - + } else { LOG.debug("Error in restoring security context"); } - + WebUtils.removeAttributeFromFlowScope(context, contextKey); } else { LOG.debug("Error in restoring security context"); @@ -146,15 +146,15 @@ public class SigninParametersCacheAction { Idp idpConfig = (Idp) WebUtils.getAttributeFromFlowScope(context, IdpConstants.IDP_CONFIG); if (wtrealm == null || idpConfig == null) { return; - } - + } + Application serviceConfig = idpConfig.findApplication(wtrealm); if (serviceConfig != null) { if (serviceConfig.getPassiveRequestorEndpoint() == null) { String url = guessPassiveRequestorURL(context, wtrealm); serviceConfig.setPassiveRequestorEndpoint(url); } - + @SuppressWarnings("unchecked") Map<String, Application> realmConfigMap = (Map<String, Application>)WebUtils http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/services/idp/src/main/webapp/WEB-INF/flows/federation-signin-request.xml ---------------------------------------------------------------------- diff --git a/services/idp/src/main/webapp/WEB-INF/flows/federation-signin-request.xml b/services/idp/src/main/webapp/WEB-INF/flows/federation-signin-request.xml index 8c908c7..785d6a8 100644 --- a/services/idp/src/main/webapp/WEB-INF/flows/federation-signin-request.xml +++ b/services/idp/src/main/webapp/WEB-INF/flows/federation-signin-request.xml @@ -25,12 +25,12 @@ <input name="idpConfig" /> <input name="wtrealm" /> - <input name="wreply" /> <input name="wctx" /> <input name="wfresh" /> <input name="wauth" /> <input name="home_realm" /> <input name="protocol" /> + <input name="return_address" /> <!-- ===== Home Realm Discovery ===== --> @@ -77,19 +77,17 @@ <!-- Home Realm is known then we can store it in cookie --> <decision-state id="checkIsThisIDP"> <if test="flowScope.idpConfig.realm.equals(flowScope.home_realm)" - then="checkWauthTypeSupported" else="checkIdpTokenHomeRealm" /> + then="checkWauthTypeSupported" else="checkRemoteIdpToken" /> </decision-state> - <!-- ============================================================================================================= --> + <!-- ===== Home Realm != this realm ===== --> - <!-- Is 'wresult/RP-IDP token' already received and validated (then stored - in session) from requestor IDP ? --> - <decision-state id="checkIdpTokenHomeRealm"> + <decision-state id="checkRemoteIdpToken"> <if test="externalContext.sessionMap[flowScope.home_realm] != null" - then="wfreshParserRemoteAction" else="redirectToTrustedIDP" /> + then="checkRemoteIdpTokenExpiry" else="redirectToTrustedIDP" /> </decision-state> - <action-state id="wfreshParserRemoteAction"> + <action-state id="checkRemoteIdpTokenExpiry"> <evaluate expression="idpTokenExpiredAction.isTokenExpired(flowScope.home_realm, flowRequestContext) or wfreshParser.authenticationRequired(flowScope.wfresh, flowScope.home_realm, flowRequestContext)" /> @@ -101,13 +99,13 @@ </action-state> <action-state id="validateReturnAddress"> - <evaluate expression="commonsURLValidator.isValid(flowRequestContext, flowScope.wreply) - and passiveRequestorValidator.isValid(flowRequestContext, flowScope.wreply, flowScope.wtrealm)"/> + <evaluate expression="commonsURLValidator.isValid(flowRequestContext, flowScope.return_address) + and passiveRequestorValidator.isValid(flowRequestContext, flowScope.return_address, flowScope.wtrealm)"/> <transition on="yes" to="requestRpToken" /> <transition on="no" to="viewBadRequest" /> </action-state> - <!-- ============================================================================================================= --> + <!-- ===== Home Realm == this realm ===== --> <decision-state id="checkWauthTypeSupported"> <on-entry> @@ -124,12 +122,10 @@ <decision-state id="checkIdpTokenWauth"> <!-- check presence of cached IDP token for THIS realm --> <if test="externalContext.sessionMap[flowScope.home_realm] == null" - then="cacheSecurityToken" else="wfreshParserAction" /> + then="cacheSecurityToken" else="checkLocalIdPTokenExpiry" /> </decision-state> - <!-- parse wfresh parameter, provided by resource RP, overriding ttl - from 'IDP_TOKEN' --> - <action-state id="wfreshParserAction"> + <action-state id="checkLocalIdPTokenExpiry"> <evaluate expression="idpTokenExpiredAction.isTokenExpired(flowScope.home_realm, flowRequestContext) or wfreshParser.authenticationRequired(flowScope.wfresh, flowScope.home_realm, flowRequestContext)" /> @@ -161,7 +157,6 @@ <!-- normal exit point --> <end-state id="requestRpToken"> <output name="home_realm" value="flowScope.home_realm" /> - <output name="wctx" value="flowScope.wctx" /> <output name="idpToken" value="flowScope.idpToken" /> </end-state> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/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 e42c7ee..1b0e3c2 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 @@ -94,21 +94,19 @@ <subflow-state id="signinRequest" subflow="signinRequest"> <input name="idpConfig" value="flowScope.idpConfig" /> <input name="wtrealm" value="flowScope.wtrealm" /> - <input name="wreply" value="flowScope.wreply" /> <input name="wctx" value="flowScope.wctx" /> <input name="wfresh" value="flowScope.wfresh" /> <input name="wauth" value="flowScope.wauth" /> <input name="home_realm" value="flowScope.whr" /> <input name="protocol" value="'wsfed'" /> + <input name="return_address" value="flowScope.wreply" /> <output name="home_realm" /> - <output name="wctx" /> <output name="idpToken" /> <output name="trusted_idp_context" /> <transition on="requestRpToken" to="requestRpToken"> <set name="flowScope.whr" value="currentEvent.attributes.home_realm" /> - <set name="flowScope.wctx" value="currentEvent.attributes.wctx" /> <set name="flowScope.idpToken" value="currentEvent.attributes.idpToken" /> </transition> <transition on="viewBadRequest" to="viewBadRequest" /> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/services/idp/src/main/webapp/WEB-INF/flows/saml-signin-request.xml ---------------------------------------------------------------------- diff --git a/services/idp/src/main/webapp/WEB-INF/flows/saml-signin-request.xml b/services/idp/src/main/webapp/WEB-INF/flows/saml-signin-request.xml index f167198..d0f010c 100644 --- a/services/idp/src/main/webapp/WEB-INF/flows/saml-signin-request.xml +++ b/services/idp/src/main/webapp/WEB-INF/flows/saml-signin-request.xml @@ -28,6 +28,7 @@ <input name="protocol" /> <input name="saml_authn_request" /> <input name="home_realm" /> + <input name="return_address" /> <!-- ===== Home Realm Discovery ===== --> @@ -74,19 +75,17 @@ <!-- Home Realm is known then we can store it in cookie --> <decision-state id="checkIsThisIDP"> <if test="flowScope.idpConfig.realm.equals(flowScope.home_realm)" - then="homeRealmSignInEntryPoint" else="checkIdpTokenHomeRealm" /> + then="homeRealmSignInEntryPoint" else="checkRemoteIdpToken" /> </decision-state> - <!-- ============================================================================================================= --> + <!-- ===== Home Realm != this realm ===== --> - <!-- Is 'wresult/RP-IDP token' already received and validated (then stored - in session) from requestor IDP ? --> - <decision-state id="checkIdpTokenHomeRealm"> + <decision-state id="checkRemoteIdpToken"> <if test="externalContext.sessionMap[flowScope.home_realm] != null" - then="wfreshParserRemoteAction" else="redirectToTrustedIDP" /> + then="checkRemoteIdpTokenExpiry" else="redirectToTrustedIDP" /> </decision-state> - <action-state id="wfreshParserRemoteAction"> + <action-state id="checkRemoteIdpTokenExpiry"> <evaluate expression="idpTokenExpiredAction.isTokenExpired(flowScope.home_realm, flowRequestContext) or authnRequestParser.isForceAuthentication(flowRequestContext)" /> @@ -98,17 +97,13 @@ </action-state> <action-state id="validateReturnAddress"> - <on-entry> - <evaluate expression="authnRequestParser.retrieveConsumerURL(flowRequestContext)" - result="flowScope.consumerURL"/> - </on-entry> - <evaluate expression="commonsURLValidator.isValid(flowRequestContext, flowScope.consumerURL) - and passiveRequestorValidator.isValid(flowRequestContext, flowScope.consumerURL, flowScope.realm)"/> + <evaluate expression="commonsURLValidator.isValid(flowRequestContext, flowScope.return_address) + and passiveRequestorValidator.isValid(flowRequestContext, flowScope.return_address, flowScope.realm)"/> <transition on="yes" to="requestRpToken" /> <transition on="no" to="viewBadRequest" /> </action-state> - <!-- ============================================================================================================= --> + <!-- ===== Home Realm == this realm ===== --> <decision-state id="homeRealmSignInEntryPoint"> <on-entry> @@ -119,10 +114,10 @@ then="viewBadRequest" /> <!-- check presence of cached IDP token for THIS realm --> <if test="externalContext.sessionMap[flowScope.home_realm] == null" - then="cacheSecurityToken" else="checkTokenExpiry" /> + then="cacheSecurityToken" else="checkLocalIdPTokenExpiry" /> </decision-state> - <action-state id="checkTokenExpiry"> + <action-state id="checkLocalIdPTokenExpiry"> <evaluate expression="idpTokenExpiredAction.isTokenExpired(flowScope.home_realm, flowRequestContext) or authnRequestParser.isForceAuthentication(flowRequestContext)" /> @@ -130,7 +125,7 @@ <transition on="no" to="validateEndpointAddress"> <set name="flowScope.idpToken" value="externalContext.sessionMap[flowScope.home_realm]" /> </transition> - <transition on-exception="java.lang.Throwable" to="scInternalServerError" /> + <transition on-exception="java.lang.Throwable" to="viewBadRequest" /> </action-state> <end-state id="redirectToLocalIDP"> @@ -171,9 +166,6 @@ <!-- abnormal exit point --> <end-state id="viewBadRequest" /> - <!-- abnormal exit point --> - <end-state id="scInternalServerError" /> - <!-- redirects to requestor idp --> <end-state id="redirectToTrustedIDP"> <on-entry> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/25471cfc/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 4a430d7..32de331 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 @@ -78,6 +78,8 @@ <evaluate expression="authnRequestParser.parseSAMLRequest(flowRequestContext, flowScope.idpConfig, flowScope.SAMLRequest, flowScope.Signature, flowScope.RelayState)" /> + <evaluate expression="authnRequestParser.retrieveConsumerURL(flowRequestContext)" + result="flowScope.consumerURL"/> <transition to="signinSAMLRequest"/> <transition on-exception="org.apache.cxf.fediz.core.exception.ProcessingException" to="viewBadRequest" /> </action-state> @@ -90,6 +92,7 @@ <input name="protocol" value="'samlsso'" /> <input name="saml_authn_request" value="flowScope.saml_authn_request" /> <input name="home_realm" value="null" /> + <input name="return_address" value="flowScope.consumerURL" /> <output name="home_realm" /> <output name="idpToken" />
