-
Bug
-
Resolution: Done
-
Major
-
1.2.8.Final
-
None
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():
case NOT_AUTHENTICATED: // A mechanism attempted to authenticate but could not complete, this now means that // authentication is required and challenges need to be sent. setAuthenticationRequired(); return AuthenticationState.ATTEMPTED;
After this in io.undertow.security.impl.SecurityContextImpl.authTransition() the following executes:
case ATTEMPTED:
authenticationState = sendChallenges();
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:
public boolean authenticate() { if(authenticationState == AuthenticationState.ATTEMPTED) { //we are re-attempted, so we just reset the state //see UNDERTOW-263 authenticationState = AuthenticationState.NOT_ATTEMPTED; } return !authTransition(); }
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.