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