idp auth module plugin

Paul Henson henson at signet.id
Wed Aug 3 02:50:16 UTC 2022


On 8/2/2022 8:07 AM, Cantor, Scott via dev wrote:

> That's part of the CredentialValidator interface, which is used for
> scenarios where you plug into the Password login flow. It's not used
> much of anywhere else.

As you mention later in the email, the source is pretty much the 
documentation; and I'm using your existing TOTP module as my primary 
reference point :).

It has two classes derived from AbstractAuthenticationAction that 
basically do administrative stuff leading up to the authentication:

	ExtractTOTPFromFormRequest
	ExtractTOTPFromHeader

and then one class derived from AbstractCredentialValidator that 
actually performs the authentication and calls populateSubject on success:

	TOTPCredentialValidator

This one uses the call errorHandler if not null otherwise throw 
exception paradigm for errors.

What I perhaps inaccurately derived from this example is that the 
classes in my module that interact with the API and do things leading up 
to successful authentication should be derived from 
AbstractAuthenticationAction and the final one when authentication 
succeeds and needs to be returned would be derived from 
AbstractCredentialValidator.

Looking at other "authentication" things that aren't username and 
password, such as ValidateRemoteUser, ValidateUserAgentAddress, 
ValidateX509Certificate, and ValidateExternalAuthentication, they seem 
to be based on AbstractValidationAction? Would that be a better choice 
for my module?

They seem to use a mix of ActionSupport.buildEvent and handleError for 
failure conditions.

>> recordFailure(profileRequestContext);
> 
> That's for metrics, it counts failed transactions. Nobody uses any of
> that but it's there.

It's on my long-term to do list to integrate the metrics into our 
monitoring framework and graph them :). Sadly, it's already been on my 
to do list for quite a long term 8-/.

>> authenticationContext.getSubcontext(AuthenticationErrorContext.class,
 > true).getClassifiedErrors().add(AuthnEventIds.INVALID_CREDENTIALS);
> 
> That's not going to be very common, I'd have to know what's doing it
> to know why.

That example is again taken from the TOTP module, in 
AbstractTOTPExtractionAction:

log.warn("{} Exception converting code string to an integer", 
getLogPrefix(), e);
authenticationContext.getSubcontext(AuthenticationErrorContext.class,
true).getClassifiedErrors().add(AuthnEventIds.INVALID_CREDENTIALS);
ActionSupport.buildEvent(profileRequestContext, 
AuthnEventIds.INVALID_CREDENTIALS);

and it seems to result in special handling for display in totp-error.vm:

#if ($authenticationErrorContext && 
$authenticationErrorContext.getClassifiedErrors().size() > 0)
     ## This handles errors that are classified by the message maps in 
the authentication config.
     #set ($eventId = 
$authenticationErrorContext.getClassifiedErrors().iterator().next())
     #if ($eventId == "InvalidCredentials")
         #set ($message = 
$springMacroRequestContext.getMessage("bad-tokencode.message", "The 
supplied token code was invalid."))

> Long story, it's not really worth going into, it had to do with how
> SWF handles empty return values from actions. If we had made the
> actions all return "proceed" or some other success string, every
> action would have had to be inside its own action-state instead of
> chained together. That's very verbose, and would be slower.

Ok, then for my purposes I should just generate events on error 
conditions in the Java code and hard code a proceed at the end of the 
evaluate list that will be used if nothing else generated anything?

>> My plugin is going to have a number of classes derived from 
>> AbstractAuthenticationAction
> 
> That more or less mostly just handles guaranteeing the AC exists and
> gets it passed into the overridden methods.

Is there any child class of it that would be more appropriate for 
wrapping the API calls to the rapid identity server?

> Very unclear that's what you'd want to do, this isn't a password use
> case.

I'm doing it because you did it :), and the bundled TOTP module seemed 
like a good basis for this one. I'm definitely open to better options, 
whether it is AbstractValidationAction or something else.

> We don't want errors that are hugely specific unless they're
> actionable by the user in some way. If it fails, it fails,
> AuthenticationException is probably good enough.

Cool. I will log a specific error message so the administrator knows 
what broke, but then just generate a generic failure event. That will 
make things simpler.

> know how to deal with it, so adding completely new events is more or
> less not possible from a login flow. The list it handles is in

By this you mean end state error events that bubble up, right? Not 
random internal events that control transitions within the flow like if 
I make up ones such as RapidTOTPAuth or RapidAuthSelection to move 
between my web flow states within the flow?

> This is not a documented system, that takes extraordinary amounts of
> time and money, so like most open source, the code is the
> documentation. In this case, you have to know SWF very well to
> understand the code, and even then there are a lot of "-isms"
> particular to how it was used.

And I'm sure there probably aren't too many people outside of the main 
development team that fiddle with it. I definitely don't know SFW very 
well, but hopefully I'm picking it up reasonably quickly, and certainly 
appreciate your help.

> And on top of that, error handling is by far the hardest part of any
> design and usually the worst. In this cases, it's pretty awful.

Just build things that never fail and then you don't need error 
handling, right ;)?



-- 
Signet - The Art of Access
https://www.signet.id/


More information about the dev mailing list