When JASPIC is used and HttpServletRequestImpl.authenticate is called, and subsequently the SAM fails to authenticate, the authentication state is left in CHALLENGE_SENT.
If now HttpServletRequestImpl.authenticate is called again, Undertow doesn't attempt to call the SAM once more, but throws an exception right away.
What happens is that during the first call, the following code executes in io.undertow.security.impl.SecurityContextImpl.AuthAttempter.transition():
After this in io.undertow.security.impl.SecurityContextImpl.authTransition() the following executes:
This now sets the state to the mentioned CHALLENGE_SENT and the chain ends. However, sendChallenges() is a bit of a NOOP for the JASPIC mechanism and no challenges are actually send.
Now when HttpServletRequestImpl.authenticate is called once more the state is not reset as was done for UNDERTOW-263:
This will result in the authentication chain being ended in io.undertow.security.impl.SecurityContextImpl.authTransition() and therefor the SAM will not be called. Subsequently, because no authentication took place io.undertow.servlet.spec.HttpServletRequestImpl.authenticate will throw an exception.