[java-identity-provider] branch master updated: IDP-1502 - Avoid object creation in the external web flows
Scott Cantor
cantor.2 at osu.edu
Wed Sep 25 15:12:42 EDT 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=f8368495e5088c9823b80d8a3cb26d456db8fffb
The following commit(s) were added to refs/heads/master by this push:
new f836849 IDP-1502 - Avoid object creation in the external web flows
f836849 is described below
commit f8368495e5088c9823b80d8a3cb26d456db8fffb
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Sep 25 15:12:39 2019 -0400
IDP-1502 - Avoid object creation in the external web flows
https://issues.shibboleth.net/jira/browse/IDP-1502
Adapt external authentication flow design.
---
.../idp/authn/ExternalAuthentication.java | 131 +++++--
.../context/ExternalAuthenticationContext.java | 25 +-
.../idp/authn/impl/ExternalAuthenticationImpl.java | 60 +--
.../impl/ValidateExternalAuthenticationTest.java | 28 +-
.../spnego/impl/SPNEGOAuthnControllerTest.java | 436 ++++++++++-----------
.../system/flows/authn/external-authn-flow.xml | 3 +-
.../system/flows/authn/remoteuser-authn-flow.xml | 4 +-
.../system/flows/authn/spnego-authn-flow.xml | 3 +-
.../system/flows/authn/x509-authn-flow.xml | 3 +-
.../profile/interceptor/ExternalInterceptor.java | 7 +-
10 files changed, 366 insertions(+), 334 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
index 77de137..a609d23 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
@@ -24,17 +24,29 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.opensaml.profile.context.ProfileRequestContext;
+import org.springframework.webflow.context.ExternalContextHolder;
+import org.springframework.webflow.context.servlet.ServletExternalContext;
+import org.springframework.webflow.execution.FlowExecution;
+import org.springframework.webflow.execution.repository.FlowExecutionRepository;
+import org.springframework.webflow.execution.repository.FlowExecutionRepositoryException;
+import org.springframework.webflow.executor.FlowExecutorImpl;
+import com.google.common.base.Strings;
import com.google.common.net.UrlEscapers;
import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
/** Public interface supporting external authentication outside the webflow engine. */
-public class ExternalAuthentication {
+public abstract class ExternalAuthentication {
- /** Parameter supplied to identify the per-conversation structure in the session. */
+ /** Parameter supplied to locate the SWF object needed in the servlet context. */
+ @Nonnull @NotEmpty public static final String SWF_KEY = "net.shibboleth.idp.flowExecutor";
+
+ /** Parameter supplied to identify the per-conversation parameter. */
@Nonnull @NotEmpty public static final String CONVERSATION_KEY = "conversation";
/** Request attribute to which user's principal should be bound. */
@@ -144,18 +156,16 @@ public class ExternalAuthentication {
*/
@Nonnull @NotEmpty public static String startExternalAuthentication(@Nonnull final HttpServletRequest request)
throws ExternalAuthenticationException {
- final String conv = request.getParameter(CONVERSATION_KEY);
- if (conv == null || conv.isEmpty()) {
+ final String key = request.getParameter(CONVERSATION_KEY);
+ if (Strings.isNullOrEmpty(key)) {
throw new ExternalAuthenticationException("No conversation key found in request");
}
+
+ final ProfileRequestContext profileRequestContext = getProfileRequestContext(key, request);
+ final ExternalAuthenticationContext extContext = getExternalAuthenticationContext(profileRequestContext);
+ extContext.getExternalAuthentication().doStart(request, profileRequestContext, extContext);
- final Object obj = request.getSession().getAttribute(CONVERSATION_KEY + conv);
- if (obj == null || !(obj instanceof ExternalAuthentication)) {
- throw new ExternalAuthenticationException("No conversation state found in session for key (" + conv + ")");
- }
-
- ((ExternalAuthentication) obj).doStart(request);
- return conv;
+ return key;
}
/**
@@ -174,14 +184,9 @@ public class ExternalAuthentication {
@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response)
throws ExternalAuthenticationException, IOException {
- final Object obj = request.getSession().getAttribute(CONVERSATION_KEY + key);
- if (obj == null || !(obj instanceof ExternalAuthentication)) {
- throw new ExternalAuthenticationException("No conversation state found in session for key (" + key + ")");
- }
-
- request.getSession().removeAttribute(CONVERSATION_KEY + key);
-
- ((ExternalAuthentication) obj).doFinish(request, response);
+ final ProfileRequestContext profileRequestContext = getProfileRequestContext(key, request);
+ final ExternalAuthenticationContext extContext = getExternalAuthenticationContext(profileRequestContext);
+ extContext.getExternalAuthentication().doFinish(request, response, profileRequestContext, extContext);
}
/**
@@ -196,12 +201,59 @@ public class ExternalAuthentication {
@Nonnull public static ProfileRequestContext getProfileRequestContext(@Nonnull @NotEmpty final String key,
@Nonnull final HttpServletRequest request) throws ExternalAuthenticationException {
- final Object obj = request.getSession().getAttribute(CONVERSATION_KEY + key);
- if (obj == null || !(obj instanceof ExternalAuthentication)) {
- throw new ExternalAuthenticationException("No conversation state found in session");
+ final Object obj = request.getServletContext().getAttribute(SWF_KEY);
+ if (!(obj instanceof FlowExecutorImpl)) {
+ // This is a testing hook for injecting the PRC directly.
+ if (obj instanceof ProfileRequestContext) {
+ return (ProfileRequestContext) obj;
+ }
+ throw new ExternalAuthenticationException("No FlowExecutor available in servlet context");
+ }
+
+ try {
+ final FlowExecutionRepository repo = ((FlowExecutorImpl) obj).getExecutionRepository();
+ ExternalContextHolder.setExternalContext(
+ new ServletExternalContext(request.getServletContext(), request, null));
+
+ final FlowExecution execution = repo.getFlowExecution(repo.parseFlowExecutionKey(key));
+ final Object prc = execution.getConversationScope().get(ProfileRequestContext.BINDING_KEY);
+ if (!(prc instanceof ProfileRequestContext)) {
+ throw new ExternalAuthenticationException(
+ "ProfileRequestContext not available in webflow conversation scope");
+ }
+
+ return (ProfileRequestContext) prc;
+ } catch (final FlowExecutionRepositoryException e) {
+ throw new ExternalAuthenticationException("Error retrieving flow conversation", e);
+ } finally {
+ ExternalContextHolder.setExternalContext(null);
+ }
+ }
+
+ /**
+ * Utility method to access the {@link ExternalAuthenticationContext}.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return the {@link ExternalAuthenticationContext} to operate on
+ *
+ * @throws ExternalAuthenticationException if the context is missing
+ */
+ @Nonnull private static ExternalAuthenticationContext getExternalAuthenticationContext(
+ @Nonnull final ProfileRequestContext profileRequestContext) throws ExternalAuthenticationException {
+
+ final AuthenticationContext authContext = profileRequestContext.getSubcontext(AuthenticationContext.class);
+ if (authContext == null) {
+ throw new ExternalAuthenticationException("No AuthenticationContext found");
}
- return ((ExternalAuthentication) obj).getProfileRequestContext(request);
+
+ final ExternalAuthenticationContext extContext = authContext.getSubcontext(ExternalAuthenticationContext.class);
+ if (extContext == null) {
+ throw new ExternalAuthenticationException("No ExternalInterceptorContext found");
+ }
+
+ return extContext;
}
/**
@@ -209,11 +261,17 @@ public class ExternalAuthentication {
* the servlet session and exposing it as request attributes.
*
* @param request servlet request
+ * @param profileRequestContext current profile request context
+ * @param externalAuthenticationContext external authentication context
*
* @throws ExternalAuthenticationException if an error occurs
*/
- protected void doStart(@Nonnull final HttpServletRequest request) throws ExternalAuthenticationException {
- throw new ExternalAuthenticationException("Not implemented");
+ protected void doStart(@Nonnull final HttpServletRequest request,
+ @Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final ExternalAuthenticationContext externalAuthenticationContext)
+ throws ExternalAuthenticationException {
+
+ request.setAttribute(ProfileRequestContext.BINDING_KEY, profileRequestContext);
}
/**
@@ -223,26 +281,15 @@ public class ExternalAuthentication {
*
* @param request servlet request
* @param response servlet response
+ * @param profileRequestContext current profile request context
+ * @param externalAuthenticationContext external authentication context
*
* @throws ExternalAuthenticationException if an error occurs
* @throws IOException if the redirect cannot be issued
*/
- protected void doFinish(@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response)
- throws ExternalAuthenticationException, IOException {
- throw new ExternalAuthenticationException("Not implemented");
- }
-
- /**
- * Get the {@link ProfileRequestContext} associated with a request.
- *
- * @param request servlet request
- *
- * @return the profile request context
- * @throws ExternalAuthenticationException if an error occurs
- */
- @Nonnull protected ProfileRequestContext getProfileRequestContext(@Nonnull final HttpServletRequest request)
- throws ExternalAuthenticationException {
- throw new ExternalAuthenticationException("Not implemented");
- }
+ protected abstract void doFinish(@Nonnull final HttpServletRequest request,
+ @Nonnull final HttpServletResponse response, @Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final ExternalAuthenticationContext externalAuthenticationContext)
+ throws ExternalAuthenticationException, IOException;
}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
index 48a7533..bd6369e 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
@@ -28,8 +28,10 @@ import javax.security.auth.Subject;
import org.opensaml.messaging.context.BaseContext;
+import net.shibboleth.idp.authn.ExternalAuthentication;
import net.shibboleth.utilities.java.support.annotation.constraint.Live;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.logic.Constraint;
/**
* A context representing the state of an externalized authentication attempt,
@@ -40,6 +42,9 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElemen
*/
public final class ExternalAuthenticationContext extends BaseContext {
+ /** Implementation object. */
+ @Nonnull private final ExternalAuthentication externalAuthentication;
+
/** Value of flowExecutionUrl on branching from flow. */
@Nullable private String flowExecutionUrl;
@@ -70,12 +75,28 @@ public final class ExternalAuthenticationContext extends BaseContext {
/** Flag indicating this "new" result is really "old". */
private boolean previousResult;
- /** Constructor. */
- public ExternalAuthenticationContext() {
+ /**
+ * Constructor.
+ *
+ * @param authentication implementation object
+ */
+ public ExternalAuthenticationContext(@Nonnull final ExternalAuthentication authentication) {
+ externalAuthentication = Constraint.isNotNull(authentication, "ExternalAuthentication cannot be null");
authenticatingAuthorities = new ArrayList<>();
}
/**
+ * Get the {@link ExternalAuthentication} object installed in the context.
+ *
+ * @return the external authentication implementation
+ *
+ * @since 4.0.0
+ */
+ @Nonnull public ExternalAuthentication getExternalAuthentication() {
+ return externalAuthentication;
+ }
+
+ /**
* Get the flow execution URL to return control to.
*
* @return return location
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
index 5d7301d..1b4c258 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
@@ -31,8 +31,6 @@ import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.context.AttributeContext;
@@ -51,38 +49,24 @@ import net.shibboleth.utilities.java.support.primitive.DeprecationSupport.Object
* of request attributes.
*/
public class ExternalAuthenticationImpl extends ExternalAuthentication {
-
- /** Class logger. */
- @Nonnull private final Logger log = LoggerFactory.getLogger(ExternalAuthenticationImpl.class);
/** Lookup function for relying party context. */
@Nonnull private Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
- /** State of request to pull from. */
- @Nonnull private final ProfileRequestContext profileRequestContext;
-
/** Track whether we were invoked from within another login flow. */
private final boolean extendedFlow;
- /**
- * Constructor.
- *
- * @param input profile request context to expose
- */
- public ExternalAuthenticationImpl(@Nonnull final ProfileRequestContext input) {
- profileRequestContext = Constraint.isNotNull(input, "ProfileRequestContext cannot be null");
- extendedFlow = false;
- relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+ /** Constructor. */
+ public ExternalAuthenticationImpl() {
+ this(false);
}
/**
* Constructor.
*
- * @param input profile request context to expose
* @param extended called as extended flow from another login flow
*/
- public ExternalAuthenticationImpl(@Nonnull final ProfileRequestContext input, final boolean extended) {
- profileRequestContext = Constraint.isNotNull(input, "ProfileRequestContext cannot be null");
+ public ExternalAuthenticationImpl(final boolean extended) {
extendedFlow = extended;
relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
}
@@ -100,7 +84,12 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
/** {@inheritDoc} */
@Override
- protected void doStart(@Nonnull final HttpServletRequest request) throws ExternalAuthenticationException {
+ protected void doStart(@Nonnull final HttpServletRequest request,
+ @Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final ExternalAuthenticationContext externalAuthenticationContext)
+ throws ExternalAuthenticationException {
+ super.doStart(request, profileRequestContext, externalAuthenticationContext);
+
final AuthenticationContext authnContext = profileRequestContext.getSubcontext(AuthenticationContext.class);
if (authnContext == null) {
throw new ExternalAuthenticationException("No AuthenticationContext found");
@@ -108,7 +97,6 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
throw new ExternalAuthenticationException("No attempted authentication flow set");
}
- request.setAttribute(ProfileRequestContext.BINDING_KEY, profileRequestContext);
request.setAttribute(EXTENDED_FLOW_PARAM, extendedFlow);
request.setAttribute(PASSIVE_AUTHN_PARAM, authnContext.isPassive());
@@ -123,18 +111,12 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
// Checkstyle: CyclomaticComplexity|MethodLength OFF
/** {@inheritDoc} */
@Override
- protected void doFinish(@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response)
- throws ExternalAuthenticationException, IOException {
- final AuthenticationContext authnContext = profileRequestContext.getSubcontext(AuthenticationContext.class);
- if (authnContext == null) {
- throw new ExternalAuthenticationException("No AuthenticationContext found");
- }
+ protected void doFinish(@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response,
+ @Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final ExternalAuthenticationContext extContext)
+ throws ExternalAuthenticationException, IOException {
- final ExternalAuthenticationContext extContext =
- authnContext.getSubcontext(ExternalAuthenticationContext.class);
- if (extContext == null) {
- throw new ExternalAuthenticationException("No ExternalAuthenticationContext found");
- } else if (extContext.getFlowExecutionUrl() == null) {
+ if (extContext.getFlowExecutionUrl() == null) {
throw new ExternalAuthenticationException("No flow execution URL found to return control");
}
@@ -199,20 +181,12 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
attr = request.getAttribute(REVOKECONSENT_KEY);
if (attr != null && attr instanceof Boolean && ((Boolean) attr).booleanValue()) {
final ConsentManagementContext consentCtx =
- getProfileRequestContext(request).getSubcontext(ConsentManagementContext.class, true);
+ profileRequestContext.getSubcontext(ConsentManagementContext.class, true);
consentCtx.setRevokeConsent(true);
}
response.sendRedirect(extContext.getFlowExecutionUrl());
}
// Checkstyle: CyclomaticComplexity|MethodLength OFF
-
- /** {@inheritDoc} */
- @Override
- protected ProfileRequestContext getProfileRequestContext(@Nonnull final HttpServletRequest request)
- throws ExternalAuthenticationException {
- return profileRequestContext;
- }
-
-
+
}
\ No newline at end of file
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
index 3ee4c8c..8ae5cf8 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
@@ -26,6 +26,7 @@ import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import net.shibboleth.idp.authn.AuthnEventIds;
+import net.shibboleth.idp.authn.ExternalAuthentication;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.context.AuthenticationErrorContext;
import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
@@ -43,12 +44,16 @@ import org.testng.annotations.Test;
/** {@link ValidateExternalAuthentication} unit test. */
public class ValidateExternalAuthenticationTest extends BaseAuthenticationContextTest {
+ private ExternalAuthentication ext;
+
private ValidateExternalAuthentication action;
@BeforeMethod public void setUp() throws Exception {
super.setUp();
prc.getSubcontext(AuthenticationContext.class).setAttemptedFlow(authenticationFlows.get(0));
+
+ ext = new ExternalAuthenticationImpl();
action = new ValidateExternalAuthentication();
action.setHttpServletRequest((HttpServletRequest) src.getExternalContext().getNativeRequest());
@@ -69,7 +74,7 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testNoCredentials() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
final Event event = action.execute(src);
ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
@@ -77,7 +82,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testPrincipalName() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setPrincipalName("foo");
final Event event = action.execute(src);
@@ -90,7 +96,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testPrincipal() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setPrincipal(new TestPrincipal("foo"));
final Event event = action.execute(src);
@@ -103,7 +110,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testSubject() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
final Subject subject = new Subject();
eac.setSubject(subject);
subject.getPrincipals().add(new TestPrincipal("foo"));
@@ -118,7 +126,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testAuthnInstant() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setPrincipalName("foo");
final Instant ts = Instant.now().minusSeconds(3600);
eac.setAuthnInstant(ts);
@@ -133,7 +142,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testAuthnAuthorities() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setPrincipalName("foo");
eac.getAuthenticatingAuthorities().addAll(Arrays.asList("foo", "bar", "baz"));
eac.setPreviousResult(true);
@@ -150,7 +160,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testException() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setAuthnException(new LoginException("foo"));
final Event event = action.execute(src);
@@ -162,7 +173,8 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
@Test public void testError() {
final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
- final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
eac.setAuthnError("foo");
final Event event = action.execute(src);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnControllerTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnControllerTest.java
index d77e8df..d557d12 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnControllerTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnControllerTest.java
@@ -21,8 +21,6 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import java.io.IOException;
-import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -30,26 +28,34 @@ import java.util.Map;
import javax.annotation.Nonnull;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.login.LoginException;
+import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.ExternalAuthentication;
import net.shibboleth.idp.authn.ExternalAuthenticationException;
import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
+import net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.idp.profile.RequestContextBuilder;
import net.shibboleth.utilities.java.support.codec.Base64Support;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSName;
import org.mockito.ArgumentMatchers;
+import org.opensaml.messaging.context.BaseContext;
import org.opensaml.profile.context.ProfileRequestContext;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletContext;
import org.springframework.web.servlet.ModelAndView;
+import org.springframework.webflow.execution.RequestContext;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -83,144 +89,128 @@ public class SPNEGOAuthnControllerTest {
}
@Test(expectedExceptions = {ExternalAuthenticationException.class})
- public void withoutConversationKeyParameter_startSPNEGO_shouldThrowExternalAuthenticationException()
- throws ExternalAuthenticationException, IOException {
- MockHttpServletRequest req = new MockHttpServletRequest();
- controller.startSPNEGO(TEST_CONVERSATION_KEY, req, null);
+ public void withoutConversationKeyParameter_startSPNEGO_shouldThrowExternalAuthenticationException() throws Exception {
+ controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (HttpServletRequest) buildConversationRequestContext(null).getExternalContext().getNativeRequest(), null);
}
@Test(expectedExceptions = ExternalAuthenticationException.class)
- public void givenMismatchedKeys_startSPNEGO_shouldThrowExternalAuthenticationException()
- throws ExternalAuthenticationException, IOException {
+ public void givenMismatchedKeys_startSPNEGO_shouldThrowExternalAuthenticationException() throws Exception {
controller.startSPNEGO("e1s2",
- buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, new StubExternalAuthentication()), null);
+ (HttpServletRequest) buildConversationRequestContext(TEST_CONVERSATION_KEY).getExternalContext().getNativeRequest(), null);
}
@Test(expectedExceptions = ExternalAuthenticationException.class)
- public void givenNullKey_startSPNEGO_shouldReturnAuthenticationException() throws ExternalAuthenticationException,
- IOException {
- MockHttpServletRequest req = buildConversationHttpServletRequest(null, new StubExternalAuthentication());
- controller.startSPNEGO(TEST_CONVERSATION_KEY, req, null);
+ public void givenNullKey_startSPNEGO_shouldReturnAuthenticationException() throws Exception {
+ RequestContext req = buildConversationRequestContext(null);
+ controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
}
@Test
- public void withoutSPNEGOContext_startSPNEGO_shouldReturnAuthenticationError()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- prc.addSubcontext(new AuthenticationContext());
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
- ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY, req, new MockHttpServletResponse());
+ public void withoutSPNEGOContext_startSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
+ ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
assertAuthenticationError(req, mv, AuthnEventIds.INVALID_AUTHN_CTX);
}
@Test
- public void withoutKerberosSettings_startSPNEGO_shouldReturnAuthenticationError()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- AuthenticationContext ac = new AuthenticationContext();
+ public void withoutKerberosSettings_startSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
+ final ProfileRequestContext prc =
+ (ProfileRequestContext) req.getConversationScope().get(ProfileRequestContext.BINDING_KEY);
+ final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
SPNEGOContext sc = new SPNEGOContext();
ac.addSubcontext(sc);
- prc.addSubcontext(ac);
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
- ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY, req, new MockHttpServletResponse());
+ ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
assertAuthenticationError(req, mv, AuthnEventIds.INVALID_AUTHN_CTX);
}
@Test
- public void givenKerberosSettings_startSPNEGO_shouldReturnModelAndView() throws ExternalAuthenticationException,
- IOException {
- MockHttpServletRequest req = buildKerberosContextHttpServletRequest();
- ModelAndView modelAndView = controller.startSPNEGO(TEST_CONVERSATION_KEY, req, new MockHttpServletResponse());
- assertModelAndView(modelAndView, req);
+ public void givenKerberosSettings_startSPNEGO_shouldReturnModelAndView() throws Exception {
+ RequestContext req = buildKerberosContextRequestContext();
+ ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertModelAndView(mv, req);
}
@Test
- public void givenKerberosSettings_startSPNEGO_shouldPreserveQueryString() throws ExternalAuthenticationException,
- IOException {
- MockHttpServletRequest req = buildKerberosContextHttpServletRequest();
- req.setQueryString("dummy query string");
- ModelAndView modelAndView = controller.startSPNEGO(TEST_CONVERSATION_KEY, req, new MockHttpServletResponse());
- assertModelAndView(modelAndView, req);
+ public void givenKerberosSettings_startSPNEGO_shouldPreserveQueryString() throws Exception {
+ RequestContext req = buildKerberosContextRequestContext();
+ ((MockHttpServletRequest) req.getExternalContext().getNativeRequest()).setQueryString("dummy query string");
+ ModelAndView mv = controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertModelAndView(mv, req);
}
@Test
- public void givenKerberosSettings_startSPNEGO_shouldReplyUnauthorizedNegotiate()
- throws ExternalAuthenticationException, IOException {
- MockHttpServletRequest req = buildKerberosContextHttpServletRequest();
- MockHttpServletResponse res = new MockHttpServletResponse();
- controller.startSPNEGO(TEST_CONVERSATION_KEY, req, res);
- assertResponseUnauthorizedNegotiate(res);
+ public void givenKerberosSettings_startSPNEGO_shouldReplyUnauthorizedNegotiate() throws Exception {
+ RequestContext req = buildKerberosContextRequestContext();
+ controller.startSPNEGO(TEST_CONVERSATION_KEY,
+ (MockHttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (MockHttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertResponseUnauthorizedNegotiate(req);
}
@Test
- public void withoutNegotiateToken_continueSPNEGO_shouldReturnModelAndView() throws ExternalAuthenticationException,
- IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
+ public void withoutNegotiateToken_continueSPNEGO_shouldReturnModelAndView() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
ModelAndView mv =
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate", req, new MockHttpServletResponse());
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate",
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertModelAndView(mv, req);
}
@Test
- public void withoutNegotiateToken_continueSPNEGO_shouldPreserveQueryString()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
- req.setQueryString("dummy query string");
+ public void withoutNegotiateToken_continueSPNEGO_shouldPreserveQueryString() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
+ ((MockHttpServletRequest) req.getExternalContext().getNativeRequest()).setQueryString("dummy query string");
ModelAndView mv =
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate", req, new MockHttpServletResponse());
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate",
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertModelAndView(mv, req);
}
@Test
- public void withoutNegotiateToken_continueSPNEGO_shouldReplyUnauthorizedNegotiate()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
- MockHttpServletResponse res = new MockHttpServletResponse();
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate", req, res);
- assertResponseUnauthorizedNegotiate(res);
+ public void withoutNegotiateToken_continueSPNEGO_shouldReplyUnauthorizedNegotiate() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate",
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertResponseUnauthorizedNegotiate(req);
}
@Test
- public void withoutSPNEGOContext_continueSPNEGO_shouldReturnAuthenticationError()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- prc.addSubcontext(new AuthenticationContext());
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
+ public void withoutSPNEGOContext_continueSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
ModelAndView mv =
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, null);
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertAuthenticationError(req, mv, AuthnEventIds.INVALID_AUTHN_CTX);
}
@Test
- public void withoutKerberosSettings_continueSPNEGO_shouldReturnAuthenticationError()
- throws ExternalAuthenticationException, IOException {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ProfileRequestContext prc = new ProfileRequestContext();
- ea.setProfileRequestContext(prc);
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
+ public void withoutKerberosSettings_continueSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ final RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
ModelAndView mv =
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, null);
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertAuthenticationError(req, mv, AuthnEventIds.INVALID_AUTHN_CTX);
}
@Test
- public void givenFailedGSSContextAcceptorInstantiation_continueSPNEGO_shouldReturnAuthenticationException()
- throws ExternalAuthenticationException, IOException {
+ public void givenFailedGSSContextAcceptorInstantiation_continueSPNEGO_shouldReturnAuthenticationException() throws Exception {
final GSSException expected = new GSSException(0);
SPNEGOAuthnController failedGSSController = new SPNEGOAuthnController() {
@Override
@@ -230,155 +220,152 @@ public class SPNEGOAuthnControllerTest {
throw expected;
}
};
- MockHttpServletRequest req = buildKerberosContextHttpServletRequest();
+ final RequestContext req = buildKerberosContextRequestContext();
ModelAndView mv =
- failedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req,
- null);
+ failedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
- Assert.assertSame(((ExternalAuthenticationException) req
+ Assert.assertSame(((Exception) ((ServletRequest) req.getExternalContext().getNativeRequest())
.getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY)).getCause(), expected);
assertAuthenticationExceptionCause(req, mv, GSSException.class);
}
@Test
- public void givenSuccessfulGSSContextAcceptorInstantiation_continueSPNEGO_shouldHaveSetAcceptorInSPNEGOContext()
- throws ExternalAuthenticationException, IOException, Exception {
- GSSContext mockGSSContext = mock(GSSContext.class);
+ public void givenSuccessfulGSSContextAcceptorInstantiation_continueSPNEGO_shouldHaveSetAcceptorInSPNEGOContext() throws Exception {
+ final GSSContext mockGSSContext = mock(GSSContext.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(false);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- MockHttpServletResponse res = new MockHttpServletResponse();
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, res);
-
- StubExternalAuthentication ea =
- (StubExternalAuthentication) req.getSession(true).getAttribute(
- ExternalAuthentication.CONVERSATION_KEY + TEST_CONVERSATION_KEY);
- ProfileRequestContext prc = ea.getProfileRequestContext(req);
- AuthenticationContext authnContext = prc.getSubcontext(AuthenticationContext.class);
- SPNEGOContext spnegoContext = authnContext != null ? authnContext.getSubcontext(SPNEGOContext.class) : null;
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+
+ final AuthenticationContext authnContext =
+ ((BaseContext) req.getConversationScope().get(ProfileRequestContext.BINDING_KEY)).getSubcontext(AuthenticationContext.class);
+ final SPNEGOContext spnegoContext = authnContext != null ? authnContext.getSubcontext(SPNEGOContext.class) : null;
Assert.assertNotNull(spnegoContext);
Assert.assertEquals(spnegoContext.getContextAcceptor(), mockGSSContextAcceptor);
}
@Test
- public void givenHeaderAuthorizationNegotiate_withNTLMdata_continueSPNEGO_shouldReturnAuthenticationError()
- throws ExternalAuthenticationException, IOException {
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NTLMSSP_HEADER_DATA);
- ModelAndView mv =
- controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NTLMSSP_HEADER_DATA, req, null);
+ public void givenHeaderAuthorizationNegotiate_withNTLMdata_continueSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ final RequestContext req = buildSPNEGORequestContext(NTLMSSP_HEADER_DATA);
+ final ModelAndView mv =
+ controller.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NTLMSSP_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertAuthenticationError(req, mv, SPNEGOAuthnController.NTLM_UNSUPPORTED);
}
@Test
- public void whenAcceptSecContextThrowsException_continueSPNEGO_shouldReturnAuthenticationException()
- throws ExternalAuthenticationException, IOException, LoginException, GSSException,
- PrivilegedActionException, Exception {
- RuntimeException e = new RuntimeException();
+ public void whenAcceptSecContextThrowsException_continueSPNEGO_shouldReturnAuthenticationException() throws Exception {
+ final RuntimeException e = new RuntimeException();
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenThrow(e);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- ModelAndView mv =
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req,
- null);
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ final ModelAndView mv =
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
- Assert.assertSame(((ExternalAuthenticationException) req
+ Assert.assertSame(((Exception) ((HttpServletRequest) req.getExternalContext().getNativeRequest())
.getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY)).getCause(), e);
assertAuthenticationExceptionCause(req, mv, RuntimeException.class);
}
@Test
- public void withoutGSSContext_continueSPNEGO_shouldReturnModelAndView() throws LoginException, GSSException,
- PrivilegedActionException, ExternalAuthenticationException, IOException, Exception {
+ public void withoutGSSContext_continueSPNEGO_shouldReturnModelAndView() throws Exception {
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(null);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- ModelAndView modelAndView =
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "", req, new MockHttpServletResponse());
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ final ModelAndView modelAndView =
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "",
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertModelAndView(modelAndView, req);
}
@Test
- public void withoutGSSContext_continueSPNEGO_shouldReplyUnauthorizedNegotiate() throws LoginException,
- GSSException, PrivilegedActionException, ExternalAuthenticationException, IOException, Exception {
+ public void withoutGSSContext_continueSPNEGO_shouldReplyUnauthorizedNegotiate() throws Exception {
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(null);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- MockHttpServletResponse res = new MockHttpServletResponse();
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, res);
- assertResponseUnauthorizedNegotiate(res, Base64Support.encode("tokenBytes".getBytes(), false));
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertResponseUnauthorizedNegotiate(req, Base64Support.encode("tokenBytes".getBytes(), false));
}
@Test
- public void givenGSSContextNotEstablished_continueSPNEGO_shouldReturnModelAndView() throws LoginException,
- GSSException, PrivilegedActionException, ExternalAuthenticationException, IOException, Exception {
- GSSContext mockGSSContext = mock(GSSContext.class);
+ public void givenGSSContextNotEstablished_continueSPNEGO_shouldReturnModelAndView() throws Exception {
+ final GSSContext mockGSSContext = mock(GSSContext.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(false);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- ModelAndView modelAndView =
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "", req, new MockHttpServletResponse());
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ final ModelAndView modelAndView =
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "",
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
assertModelAndView(modelAndView, req);
}
@Test
- public void givenGSSContextNotEstablished_continueSPNEGO_shouldReplyUnauthorizedNegotiate() throws LoginException,
- GSSException, PrivilegedActionException, ExternalAuthenticationException, IOException, Exception {
- GSSContext mockGSSContext = mock(GSSContext.class);
+ public void givenGSSContextNotEstablished_continueSPNEGO_shouldReplyUnauthorizedNegotiate() throws Exception {
+ final GSSContext mockGSSContext = mock(GSSContext.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(false);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- MockHttpServletResponse res = new MockHttpServletResponse();
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, res);
- assertResponseUnauthorizedNegotiate(res, Base64Support.encode("tokenBytes".getBytes(), false));
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+ assertResponseUnauthorizedNegotiate(req, Base64Support.encode("tokenBytes".getBytes(), false));
}
@Test
- public void givenGSSContextEstablished_andGSSException_continueSPNEGO_shouldReturnAuthenticationError()
- throws LoginException, GSSException, PrivilegedActionException, ExternalAuthenticationException,
- IOException, Exception {
- GSSContext mockGSSContext = mock(GSSContext.class);
- GSSException gssException = new GSSException(0);
+ public void givenGSSContextEstablished_andGSSException_continueSPNEGO_shouldReturnAuthenticationError() throws Exception {
+ final GSSContext mockGSSContext = mock(GSSContext.class);
+ final GSSException gssException = new GSSException(0);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(true);
when(mockGSSContext.getSrcName()).thenThrow(gssException);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- ModelAndView mv =
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req,
- null);
- Assert.assertSame(((ExternalAuthenticationException) req
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ final ModelAndView mv =
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+ Assert.assertSame(((Exception) ((HttpServletRequest) req.getExternalContext().getNativeRequest())
.getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY)).getCause(), gssException);
assertAuthenticationExceptionCause(req, mv, GSSException.class);
}
@Test
- public void givenGSSContextEstablished_continueSPNEGO_shouldReturnNull() throws LoginException, GSSException,
- PrivilegedActionException, ExternalAuthenticationException, IOException, Exception {
- GSSContext mockGSSContext = mock(GSSContext.class);
- GSSName mockGssName = mock(GSSName.class);
+ public void givenGSSContextEstablished_continueSPNEGO_shouldReturnNull() throws Exception {
+ final GSSContext mockGSSContext = mock(GSSContext.class);
+ final GSSName mockGssName = mock(GSSName.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(true);
when(mockGSSContext.getSrcName()).thenReturn(mockGssName);
when(mockGssName.toString()).thenReturn("testname at realm");
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- Assert.assertNull(mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate "
- + NEGOTIATE_HEADER_DATA, req, null));
+ final RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ Assert.assertNull(mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse()));
}
@Test
- public void givenGSSContextEstablished_continueSPNEGO_shouldSetAuthenticationSubjectAttribute()
- throws LoginException, GSSException, PrivilegedActionException, ExternalAuthenticationException,
- IOException, Exception {
+ public void givenGSSContextEstablished_continueSPNEGO_shouldSetAuthenticationSubjectAttribute() throws Exception {
GSSContext mockGSSContext = mock(GSSContext.class);
GSSName mockGssName = mock(GSSName.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
@@ -387,47 +374,49 @@ public class SPNEGOAuthnControllerTest {
when(mockGSSContext.isEstablished()).thenReturn(true);
when(mockGSSContext.getSrcName()).thenReturn(mockGssName);
when(mockGssName.toString()).thenReturn("testname at realm");
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, null);
- Subject s = (Subject) req.getAttribute(ExternalAuthentication.SUBJECT_KEY);
+ RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
+ Subject s = (Subject) ((HttpServletRequest) req.getExternalContext().getNativeRequest()).getAttribute(ExternalAuthentication.SUBJECT_KEY);
Assert.assertEquals(s.getClass(), Subject.class);
Assert.assertTrue(s.getPrincipals(KerberosPrincipal.class).contains(new KerberosPrincipal("testname at realm")));
Assert.assertTrue(s.getPrincipals(UsernamePrincipal.class).contains(new UsernamePrincipal("testname at realm")));
}
@Test
- public void givenGSSContextEstablishedButNoGSSNameIsNull_continueSPNEGO_shouldSetAuthenticationSubjectAttribute()
- throws LoginException, GSSException, PrivilegedActionException, ExternalAuthenticationException,
- IOException, Exception {
+ public void givenGSSContextEstablishedButNoGSSNameIsNull_continueSPNEGO_shouldSetAuthenticationSubjectAttribute() throws Exception {
GSSContext mockGSSContext = mock(GSSContext.class);
when(mockGSSContextAcceptor.acceptSecContext(ArgumentMatchers.<byte[]> any(), anyInt(), anyInt())).thenReturn(
"tokenBytes".getBytes());
when(mockGSSContextAcceptor.getContext()).thenReturn(mockGSSContext);
when(mockGSSContext.isEstablished()).thenReturn(true);
when(mockGSSContext.getSrcName()).thenReturn(null);
- MockHttpServletRequest req = buildSPNEGOHttpServletRequest(NEGOTIATE_HEADER_DATA);
- ModelAndView mv = mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA, req, null);
+ RequestContext req = buildSPNEGORequestContext(NEGOTIATE_HEADER_DATA);
+ ModelAndView mv = mockedGSSController.continueSPNEGO(TEST_CONVERSATION_KEY, "Negotiate " + NEGOTIATE_HEADER_DATA,
+ (HttpServletRequest) req.getExternalContext().getNativeRequest(),
+ (HttpServletResponse) req.getExternalContext().getNativeResponse());
Assert.assertNull(mv);
- Assert.assertEquals(((ExternalAuthenticationException) req
- .getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY)).getClass(),ExternalAuthenticationException.class);
+ Assert.assertEquals(
+ ((HttpServletRequest) req.getExternalContext().getNativeRequest()).getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY).getClass(),
+ ExternalAuthenticationException.class);
}
- private MockHttpServletRequest buildSPNEGOHttpServletRequest(String negotiateHeaderData) {
- MockHttpServletRequest req = buildKerberosContextHttpServletRequest();
- req.addHeader(HttpHeaders.AUTHORIZATION, "Negotiate " + negotiateHeaderData);
+ private RequestContext buildSPNEGORequestContext(String negotiateHeaderData) throws ComponentInitializationException {
+ RequestContext req = buildKerberosContextRequestContext();
+ ((MockHttpServletRequest) req.getExternalContext().getNativeRequest()).addHeader(HttpHeaders.AUTHORIZATION, "Negotiate " + negotiateHeaderData);
return req;
}
- private MockHttpServletRequest buildKerberosContextHttpServletRequest() {
- StubExternalAuthentication ea = new StubExternalAuthentication();
- ea.setProfileRequestContext(buildKerberosProfileRequestContext());
- MockHttpServletRequest req = buildConversationHttpServletRequest(TEST_CONVERSATION_KEY, ea);
+ private RequestContext buildKerberosContextRequestContext() throws ComponentInitializationException {
+ RequestContext req = buildConversationRequestContext(TEST_CONVERSATION_KEY);
+ buildKerberosProfileRequestContext(req);
return req;
}
- private ProfileRequestContext buildKerberosProfileRequestContext() {
- ProfileRequestContext prc = new ProfileRequestContext();
- AuthenticationContext ac = new AuthenticationContext();
+ private ProfileRequestContext buildKerberosProfileRequestContext(RequestContext rc) {
+ ProfileRequestContext prc = (ProfileRequestContext) rc.getConversationScope().get(ProfileRequestContext.BINDING_KEY);
+ AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
SPNEGOContext sc = new SPNEGOContext();
KerberosSettings ks = new KerberosSettings();
List<KerberosRealmSettings> realms = new ArrayList<>();
@@ -435,42 +424,55 @@ public class SPNEGOAuthnControllerTest {
ks.setRealms(realms);
sc.setKerberosSettings(ks);
ac.addSubcontext(sc);
- prc.addSubcontext(ac);
return prc;
}
- private MockHttpServletRequest buildConversationHttpServletRequest(String conversationKey,
- ExternalAuthentication externalAuthentication) {
- MockHttpServletRequest req = new MockHttpServletRequest();
- req.addParameter(ExternalAuthentication.CONVERSATION_KEY, conversationKey);
- req.getSession(true).setAttribute(ExternalAuthentication.CONVERSATION_KEY + TEST_CONVERSATION_KEY,
- externalAuthentication);
- return req;
- }
-
- private void assertAuthenticationError(MockHttpServletRequest request, ModelAndView mv, String expectedError) {
+ private RequestContext buildConversationRequestContext(String conversationKey) throws ComponentInitializationException {
+ final RequestContext rc = new RequestContextBuilder().buildRequestContext();
+ if (conversationKey != null) {
+ ((MockHttpServletRequest) rc.getExternalContext().getNativeRequest()).addParameter(
+ ExternalAuthentication.CONVERSATION_KEY, conversationKey);
+ }
+
+ final ProfileRequestContext prc =
+ (ProfileRequestContext) rc.getConversationScope().get(ProfileRequestContext.BINDING_KEY);
+ ((MockServletContext) rc.getExternalContext().getNativeContext()).setAttribute(ExternalAuthentication.SWF_KEY, prc);
+
+ final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class, true);
+ ac.setAttemptedFlow(new AuthenticationFlowDescriptor());
+
+ final ExternalAuthenticationContext eac = (ExternalAuthenticationContext) ac.addSubcontext(
+ new ExternalAuthenticationContext(new ExternalAuthenticationImpl()));
+ eac.setFlowExecutionUrl("foo");
+
+ return rc;
+ }
+
+ private void assertAuthenticationError(RequestContext request, ModelAndView mv, String expectedError) {
Assert.assertNull(mv);
- Assert.assertEquals(request.getAttribute(ExternalAuthentication.AUTHENTICATION_ERROR_KEY).toString(),
+ Assert.assertEquals(
+ ((ServletRequest) request.getExternalContext().getNativeRequest()).getAttribute(ExternalAuthentication.AUTHENTICATION_ERROR_KEY).toString(),
expectedError);
}
- private void assertAuthenticationExceptionCause(MockHttpServletRequest request, ModelAndView mv,
+ private void assertAuthenticationExceptionCause(RequestContext request, ModelAndView mv,
Class<?> exceptedExceptionClass) {
Assert.assertNull(mv);
- Assert.assertEquals(((ExternalAuthenticationException) request
+ Assert.assertEquals(((Exception) ((ServletRequest) request.getExternalContext().getNativeRequest())
.getAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY)).getCause().getClass(),
exceptedExceptionClass);
}
- private void assertModelAndView(ModelAndView modelAndView, MockHttpServletRequest request) {
+ private void assertModelAndView(ModelAndView modelAndView, RequestContext request) {
Assert.assertEquals(modelAndView.getViewName(), "spnego-unavailable");
Map<String, Object> model = modelAndView.getModel();
Assert.assertTrue(model.containsKey("encoder"), "Model doesn't contain \"encoder\"");
Assert.assertEquals(model.get("encoder").getClass(), Class.class);
Assert.assertTrue(model.containsKey("errorUrl"), "Model doesn't contain \"errorUrl\"");
Assert.assertEquals(model.get("errorUrl").getClass(), String.class);
- if (request.getQueryString() != null) {
- Assert.assertTrue(((String) model.get("errorUrl")).endsWith("/error?" + request.getQueryString()));
+ if (((HttpServletRequest) request.getExternalContext().getNativeRequest()).getQueryString() != null) {
+ Assert.assertTrue(((String) model.get("errorUrl")).endsWith(
+ "/error?" + ((HttpServletRequest) request.getExternalContext().getNativeRequest()).getQueryString()));
} else {
Assert.assertTrue(((String) model.get("errorUrl")).endsWith("/error"));
}
@@ -478,38 +480,16 @@ public class SPNEGOAuthnControllerTest {
Assert.assertTrue(model.get("request") instanceof HttpServletRequest);
}
- private void assertResponseUnauthorizedNegotiate(MockHttpServletResponse response) {
+ private void assertResponseUnauthorizedNegotiate(RequestContext request) {
+ final HttpServletResponse response = (HttpServletResponse) request.getExternalContext().getNativeResponse();
Assert.assertEquals(response.getStatus(), 401);
Assert.assertEquals(response.getHeader("WWW-Authenticate"), "Negotiate");
}
- private void assertResponseUnauthorizedNegotiate(MockHttpServletResponse response, String base64token) {
+ private void assertResponseUnauthorizedNegotiate(RequestContext request, String base64token) {
+ final HttpServletResponse response = (HttpServletResponse) request.getExternalContext().getNativeResponse();
Assert.assertEquals(response.getStatus(), 401);
Assert.assertEquals(response.getHeader("WWW-Authenticate"), "Negotiate " + base64token);
}
- private class StubExternalAuthentication extends ExternalAuthentication {
-
- private ProfileRequestContext profileRequestContext;
-
- public void setProfileRequestContext(ProfileRequestContext prc) {
- profileRequestContext = prc;
- }
-
- @Override
- protected void doStart(HttpServletRequest request) throws ExternalAuthenticationException {
- }
-
- @Override
- protected void doFinish(HttpServletRequest request, HttpServletResponse response)
- throws ExternalAuthenticationException, IOException {
- }
-
- @Override
- protected ProfileRequestContext getProfileRequestContext(HttpServletRequest request)
- throws ExternalAuthenticationException {
- return profileRequestContext;
- }
-
- }
-}
+}
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
index 3dc9b50..a0a67dc 100644
--- a/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
@@ -7,8 +7,7 @@
<view-state id="ExternalTransfer" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.External.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
<on-render>
- <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
- <evaluate expression="externalContext.getNativeRequest().getSession().setAttribute('conversation' + flowExecutionContext.getKey().toString(), new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(opensamlProfileRequestContext, calledAsExtendedFlow?:false))" />
+ <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(calledAsExtendedFlow?:false)), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
</on-render>
<transition to="ValidateExternalAuthentication" />
</view-state>
diff --git a/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
index c81ce16..4580a4f 100644
--- a/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
@@ -7,10 +7,10 @@
<view-state id="ExternalTransfer" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.RemoteUser.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
<on-render>
- <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
- <evaluate expression="externalContext.getNativeRequest().getSession().setAttribute('conversation' + flowExecutionContext.getKey().toString(), new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(opensamlProfileRequestContext, calledAsExtendedFlow?:false))" />
+ <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(calledAsExtendedFlow?:false)), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
</on-render>
<transition to="ValidateExternalAuthentication" />
+
</view-state>
<action-state id="ValidateExternalAuthentication">
diff --git a/idp-conf/src/main/resources/system/flows/authn/spnego-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/spnego-authn-flow.xml
index c0d8a4d..bfd5b96 100644
--- a/idp-conf/src/main/resources/system/flows/authn/spnego-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/spnego-authn-flow.xml
@@ -54,8 +54,7 @@
<view-state id="RunSPNEGO" view="externalRedirect:#{flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.SPNEGO.externalAuthnPathStrategy').apply(opensamlProfileRequestContext)}/#{flowExecutionContext.getKey().toString()}?conversation=#{flowExecutionContext.getKey().toString()}">
<on-render>
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.spnego.impl.SPNEGOContext(), true).setKerberosSettings(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.SPNEGO.Krb5.Settings'))" />
- <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
- <evaluate expression="externalContext.getNativeRequest().getSession().setAttribute('conversation' + flowExecutionContext.getKey().toString(), new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(opensamlProfileRequestContext))" />
+ <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl()), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
</on-render>
<transition on="proceed" to="ValidateExternalAuthentication" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/x509-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/x509-authn-flow.xml
index ce1e9df..d00cd30 100644
--- a/idp-conf/src/main/resources/system/flows/authn/x509-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/x509-authn-flow.xml
@@ -10,8 +10,7 @@
<view-state id="ExternalTransfer" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.X509.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
<on-render>
- <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
- <evaluate expression="externalContext.getNativeRequest().getSession().setAttribute('conversation' + flowExecutionContext.getKey().toString(), new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(opensamlProfileRequestContext))" />
+ <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(calledAsExtendedFlow?:false)), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
</on-render>
<transition to="ValidateExternalAuthentication" />
</view-state>
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ExternalInterceptor.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ExternalInterceptor.java
index 385e5f5..d6d4c70 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ExternalInterceptor.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ExternalInterceptor.java
@@ -31,6 +31,7 @@ import org.springframework.webflow.execution.repository.FlowExecutionRepository;
import org.springframework.webflow.execution.repository.FlowExecutionRepositoryException;
import org.springframework.webflow.executor.FlowExecutorImpl;
+import com.google.common.base.Strings;
import com.google.common.net.UrlEscapers;
import net.shibboleth.idp.profile.context.ExternalInterceptorContext;
@@ -45,10 +46,10 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
*/
public abstract class ExternalInterceptor {
- /** Parameter supplied to locate the SWF object needed in the session. */
+ /** Parameter supplied to locate the SWF object needed in the servlet context. */
@Nonnull @NotEmpty public static final String SWF_KEY = "net.shibboleth.idp.flowExecutor";
- /** Parameter supplied to identify the per-conversation structure in the session. */
+ /** Parameter supplied to identify the per-conversation parameter. */
@Nonnull @NotEmpty public static final String CONVERSATION_KEY = "conversation";
/** Request attribute to which an event ID may be bound. */
@@ -94,7 +95,7 @@ public abstract class ExternalInterceptor {
@Nonnull @NotEmpty public static String startExternalInterceptor(@Nonnull final HttpServletRequest request)
throws ExternalInterceptorException {
final String key = request.getParameter(CONVERSATION_KEY);
- if (key == null || key.isEmpty()) {
+ if (Strings.isNullOrEmpty(key)) {
throw new ExternalInterceptorException("No conversation key found in request");
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list