Advice on migrating SPNEGO to MFA-flow

Philip Brusten philip.brusten at kuleuven.be
Thu Dec 15 07:25:44 EST 2016


Hi Scott,

I'll start by explaining what we try to achieve in a bit more detail.

For normal authentication requests (no special requirements from SP or 
custom relying-party config) we want to authenticate our users by:
  - their previous session if available and still active for achieving SSO
  - SPNEGO authentication if the client resides in a subnet so it can 
request a Kerberos ST. Therefore we set an activationCondition based on 
several subnets on the authn/SPNEGO flow. Since not every user-agent is 
automatically able to use SPNEGO we rely on the cookie to "opt-in" and 
to actually run SPNEGO. (from a user's perspective this provides SSO as 
well)
  - password authentication if none of the above succeeded

Our IAM-system allows users to register a 2nd factor. Users can also 
indicate whether they want to use this 2nd factor for every login or 
only when the application requests for it. The former sets the attribute 
eduPersonAssurance to a certain value, for the latter eduPersonAssurance 
is empty.

So if no special requirements are set by the SP, but the user opted in 
for the 2nd factor methods, the IdP must authenticate this 2nd factor 
(or reuse an earlier active result of this method)
If the SP requests for the authnContextClass (or via custom relying 
party configuration, cf defaultAuthenticationMethods) linked to this 2nd 
factor authentication method, the IdP must authenticate the user using 
the 2nd factor (or reuse an earlier active result of this method)

If a SP requests for the authnContextClass 
'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', but 
the user already authenticated using its first and 2nd factor, he must 
not re-authenticate because he already authenticated using a higher 
level of trust.

If a SP requests for the authnContextClass 
'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport' & 
forceAuthn is set, the user must be re-authenticated using his password.


I will answer the other questions/remarks inline

On 14/12/2016 14:17, Cantor, Scott wrote:
> On 12/14/16, 4:50 AM, "users on behalf of Philip Brusten" <users-bounces at shibboleth.net on behalf of philip.brusten at kuleuven.be> wrote:
>
>> and uses SPNEGO or Password as initial authentication. SPNEGO has an
>>     activationCondition based on some subnets and SPNEGO is triggered by the
>>     cookie  '_idp_spnego_autologin'.
> SPNEGO is was designed to fit together with the Password flow and the cookie stuff that SWITCH built, so it really may have to be driven by that more than the MFA logic, it depends on the use case.
I was not using the ExtendedFlows feature of the Password flow to run 
SPNEGO as a subflow. I now configured SPNEGO as an extended flow for 
Password.
In order to use SPNEGO as an extended flow of the Password flow, it had 
to enabled it in the idp.authn.flows property, otherwise the extflows 
won't be enabled. Password on the other hand, must not be enabled via 
this property, it can be called directly from the MFA-flow as a subflow, 
I find this quite confusing.

So I now have set:
idp.authn.flows=SPNEGO|MFA

I also re-ordered the methods in general-authn.xml:
1: authn/Password
2: authn/multifactor
3: authn/MFA
4: authn/SPNEGO

When I now use Password authentication as my first factor, all works as 
expected.

For a SP without any special requirements I can initiate SPNEGO from the 
Password flow using the signaling parameter as set in 
shibboleth.authn.Password.ExtendedFlowParameters 
"_shib_idp_SPNEGO_enable_autologin", SPNEGO runs and succeeds. If I then 
go to a SP which requests the authnContextClass linked to my 2nd factor 
authn, I want to reuse the authentication result from SPNEGO. With my 
currect MFA-transitionmap he goes to authn/Password:

<util:map id="shibboleth.authn.MFA.TransitionMap">
     <entry key="">
         <bean parent="shibboleth.authn.MFA.Transition" 
p:nextFlow="authn/Password" />
     </entry>
     <entry key="authn/Password">
         <bean parent="shibboleth.authn.MFA.Transition" 
p:nextFlowStrategy-ref="checkSecondFactor" />
     </entry>
     <!-- An implicit final rule will return whatever the final flow 
returns. -->
</util:map>

I guess I should use a nextFlowStrategy as the initial step in the 
TransitionMap to determine I can reuse the active result, if not go to 
authn/Password. If so, check if authnContextClass for 2nd factor is 
requested or set in the eduPersonAssurance-attribute (opt-in) and then 
go to authn/multifactor.

I have to figure out how to do this in using your API. Any pointers 
would be appreciated since I am not that familiar with the API.

Some extracts from the log after I already authenticated using SPNEGO 
and then went to that 2nd SP requiring the 2nd factor authnContextClass:

Loading AuthenticationResult for flow authn/MFA in session 
7dc58cd6ca340f35091dd6259b604d3c6921319333c77fe3139fbccf519add1a
Profile Action ExtractActiveAuthenticationResults: Authentication result 
authn/MFA is active, copying from session
Profile Action ResolveAttributes: Activation condition for action 
returned false
Profile Action FilterFlowsByAttribute: Activation condition for action 
returned false
Profile Action InitializeRequestedPrincipalContext: Leaving existing 
RequestedPrincipalContext in place
Profile Action FilterFlowsByForcedAuthn: Request does not have forced 
authentication requirement, nothing to do
Profile Action FilterFlowsByNonBrowserSupport: Request does not have 
non-browser requirement, nothing to do
Profile Action SelectAuthenticationFlow: Specific principals requested 
with 'exact' operator: 
[AuthnContextClassRefPrincipal{authnContextClassRef=https://example.com/auth/multifactor}]
{} Giving priority to active results that meet request requirements
Profile Action SelectAuthenticationFlow: Checking for an active result 
compatible with operator 'exact' and principal 
'https://example.com/auth/multifactor'
Registry located predicate factory of type 
'net.shibboleth.idp.authn.principal.impl.ExactPrincipalEvalPredicateFactory' 
for principal type 'class 
net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal' 
and operator 'exact'
Profile Action SelectAuthenticationFlow: Checking for an inactive flow 
compatible with operator 'exact' and principal 
'https://example.com/auth/multifactor'
Registry located predicate factory of type 
'net.shibboleth.idp.authn.principal.impl.ExactPrincipalEvalPredicateFactory' 
for principal type 'class 
net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal' 
and operator 'exact'
Profile Action SelectAuthenticationFlow: Selecting inactive 
authentication flow authn/MFA
Profile Action PopulateMultiFactorAuthenticationContext: 1 active 
result(s) extracted for possible reuse
Profile Action TransitionMultiFactorAuthentication: Applying MFA 
transition rule to determine initial state
Profile Action TransitionMultiFactorAuthentication: MFA flow transition 
after 'proceed' event to 'authn/Password' flow


>
> Also, any use of initial-authn is broken. It will not be included in 4.0 barring me totally changing my mind about it. If you need to control the order of flows, use the MFA flow for that.
That's why I started this thread :)
It's better to explicitly deprecate those properties at 
https://wiki.shibboleth.net/confluence/display/IDP30/AuthenticationConfiguration 
in favour of the MFA-flow.
>
>>     But SPNEGO returns a ReselectFlow event, which cannot be catched by the
>>     MFA-flow, so the MFA-flow exits. Since SPNEGO is a system flow, changing
>>     it's default behaviour doesn't seem like an option.
> I don't believe it cannot be caught. You didn't supply a transition rule for ReslectFlow so it fell through as the final result of the MFA flow. If you want to handle it, you need to handle it, and provide a rule for that event. If the docs aren't clear on how to do that, let me know.
>
> I could be wrong, it's possible ReselectFlow is being handled in a way that prevents that, but I don't think so, and your rules don't mention it.
Since I now use SPNEGO as an ExtendedFlow of the Password flow this 
question has become irrelevant.

But anyway before I did the transition to SPNEGO as an ExtendedFlow of 
Password, I tried adding an entry in the TransitionMap for ReselectFlow, 
but control was given back to SelectAuthenticationFlow, log:

Profile Action TransitionMultiFactorAuthentication: MFA flow completing 
with event 'ReselectFlow'
Profile Action SelectAuthenticationFlow: Moving incomplete flow 
authn/MFA to intermediate set

> So:
>
> - stop using initial-authn
> - you should not be looking at the SubjectCanonicalizationContext, certainly not as a means of determining anything about how authentication happens
In my authn/multifactor lib, I use the CanonicalUsernameLookupStrategy 
to retrieve the username. But I understand that I must not use it for 
determining the authentication flow.

Kind regards,
Philip



More information about the users mailing list