RelyParty redirect URL
Christopher Bongaarts
cab at umn.edu
Thu Jun 18 20:05:32 UTC 2020
On 6/18/2020 12:52 PM, Joseph Fischetti wrote:
> For some reason, error.vm doesn't appear to have the flowExecutionUrl available (and I'm not sure what it's supposed to be part of since I don't see where it's set during login.vm).
>
> That said, this should more or less achieve exactly what I'm trying to do. I'm using attribute-resolver to figure out whether to send the user to SP-B or not, and if the user goes to SP-B and does that they should do, the attribute will be set appropriately. As long as the attribute-resolver is executed after hitting the flowExecutionUrl (assuming SSO takes over, as you said), it should work fine.
You end up needing to reinvoke the resolver to pick up the changed
value. I'll throw our our expired password flow here to give you an
idea of how we put it together. Note the new view state we defined, and
that we push the flowExecutionUrl into it. There is probably some extra
noise that could be cleaned up. Enable it by adding it to an appropriate
relying party definition with e.g. p:postAuthenticationFlows="expiredpw".
<decision-state id="CheckPasswordExpired">
<on-entry>
<evaluate expression="ResolveAttributes" />
<evaluate
expression="isPasswordExpired.apply(opensamlProfileRequestContext)"
result="flowScope.ispwexpired" />
<evaluate
expression="isPasswordChangeSP.apply(opensamlProfileRequestContext)"
result="flowScope.ispwchangesp" />
</on-entry>
<if test="ispwexpired && !ispwchangesp"
then="PasswordExpired" else="CleanUpContexts" />
</decision-state>
<view-state id="PasswordExpired" view="expired-password">
<on-render>
<evaluate expression="environment"
result="viewScope.environment" />
<evaluate expression="opensamlProfileRequestContext"
result="viewScope.profileRequestContext" />
<evaluate
expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext))"
result="viewScope.authenticationContext" />
<evaluate
expression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationErrorContext))"
result="viewScope.authenticationErrorContext" />
<evaluate
expression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationWarningContext))"
result="viewScope.authenticationWarningContext" />
<evaluate
expression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.LDAPResponseContext))"
result="viewScope.ldapResponseContext" />
<evaluate
expression="T(net.shibboleth.utilities.java.support.codec.HTMLEncoder)"
result="viewScope.encoder" />
</on-render>
<transition on="proceed" to="RetryExpiredCheck" />
</view-state>
<action-state id="RetryExpiredCheck">
<evaluate
expression="opensamlProfileRequestContext.removeSubcontext(T(net.shibboleth.idp.attribute.context.AttributeContext))"/>
<evaluate
expression="opensamlProfileRequestContext.removeSubcontext(T(net.shibboleth.idp.attribute.resolution.context.AttributeResolutionContext))"/>
<transition to="CheckPasswordExpired"/>
</action-state>
<action-state id="CleanUpContexts">
<evaluate
expression="opensamlProfileRequestContext.removeSubcontext(T(net.shibboleth.idp.attribute.context.AttributeContext))"/>
<evaluate
expression="opensamlProfileRequestContext.removeSubcontext(T(net.shibboleth.idp.attribute.resolution.context.AttributeResolutionContext))"/>
<transition to="proceed"/>
</action-state>
And a snippet of the beans file:
<bean id="isPasswordChangeSP"
parent="shibboleth.Conditions.RelyingPartyId">
<constructor-arg>
<list>
<value>https://sp-b-test...</value>
<value>https://sp-b-prod...</value>
</list>
</constructor-arg>
</bean>
<bean id="isPasswordExpired"
class="edu.umn.oit.idm.shib.RegexAttributePredicate" <!-- there is a
built-in predicate or condition for this now -->
p:pat="^[Xs].*" p:attributeId="umnPasswordStatus"
p:attributeContextLookupStrategy-ref="shibboleth.ChildLookupOrCreate.AttributeContext"/>
<bean id="ResolveAttributes"
class="net.shibboleth.idp.profile.impl.ResolveAttributes"
scope="prototype" <!-- WARNING: this instances an "impl" bean which is
not guaranteed to work across idp releases -->
c:resolverService-ref="shibboleth.AttributeResolverService"
p:maskFailures="true" p:attributesToResolve="umnPasswordStatus"
p:attributeContextCreationStrategy-ref="shibboleth.ChildLookupOrCreate.AttributeContext"/>
<!-- this tells it to put these attributes in a separate context -->
And the corresponding expired-password view:
#parse("header.vm")
<h1 class="text-center">Password has expired</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-xs-12">
<p class="idp3_confirmation-message">Your password has expired
and must be changed before
you can proceed to the application.</p>
<p>#springMessageText("idp.login.changePassword", "To create a new
password now, go to")
<strong><a href="https://example.edu/change-password"
target="_blank">https://example.edu/change-password</a></strong>.</p>
<p>After you change your password, click <a
href="$flowExecutionUrl&_eventId_proceed=1">Continue</a>.</p>
</div>
</div>
#parse("footer.vm")
--
%% Christopher A. Bongaarts %% cab at umn.edu %%
%% OIT - Identity Management %% http://umn.edu/~cab %%
%% University of Minnesota %% +1 (612) 625-1809 %%
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/users/attachments/20200618/ce32ef1b/attachment.htm>
More information about the users
mailing list