I have an application running behind an Nginx proxy load balancer, utilizing multiple Java instances where requests are distributed in a round-robin manner. In this setup, Server 1 may handle the initiation of the authentication request, while Server 2 receives the response assertion to verify.
Due to the stateless nature of the application, I cannot use cookies sessions. In my analysis of the code, I observed that the initial check is performed on Saml2AuthenticationToken in the session. If this check fails, the system falls back to tokenByEntityId, which then attempts to locate the registration by entity ID. However, during this process, the AbstractSaml2AuthenticationRequest is set to null in OpenSamlAuthenticationTokenConverter convert method.
This leads to the following error when validating the InResponseTo attribute:
Unauthorized error: The response contained an InResponseTo attribute [ARQa81ff07-49ea-4ad4-a409-f174afb594e9] but no saved authentication request was found
In below code tokenByEntityId sets AuthenticationRequest to null then how InResponseTo will be validated if it does not get ? Whats the alternative for stateless application , do I need to store the authentication request in DB , is there any alternative as I do not want to store in DB?
@Override
public Saml2AuthenticationToken convert(HttpServletRequest request) {
String serialized = request.getParameter(Saml2ParameterNames.SAML_RESPONSE);
if (serialized == null) {
return null;
}
RequestMatcher.MatchResult result = this.requestMatcher.matcher(request);
if (!result.isMatch()) {
return null;
}
Saml2AuthenticationToken token = tokenByAuthenticationRequest(request);
if (token == null) {
token = tokenByRegistrationId(request, result);
}
if (token == null) {
token = tokenByEntityId(request);
}
return token;
}
private Saml2AuthenticationToken tokenByEntityId(HttpServletRequest request) {
String serialized = request.getParameter(Saml2ParameterNames.SAML_RESPONSE);
String decoded = new String(samlDecode(serialized), StandardCharsets.UTF_8);
Response response = parse(decoded);
String issuer = response.getIssuer().getValue();
RelyingPartyRegistration registration = this.registrations.findUniqueByAssertingPartyEntityId(issuer);
return tokenByRegistration(request, registration, null);
}
Comment From: sumeetpri
@marcusdacoregio @jzheaux - I am looking for your expert input .
Comment From: sumeetpri
Is there any way to turn off the InResponseTo validation if AuthenticationRequest is not set or found in application ? @marcusdacoregio @jzheaux
Comment From: sumeetpri
Is there any simple way to disable InResponseTo validation even it exists in response assertion ?
Comment From: marcusdacoregio
Hi, @sumeetpri. Please read the documentation about SAML 2.0 Response Validation. You can easily set a custom response validator by using the setters available in OpenSaml4AuthenticationProvider.
Comment From: marcusdacoregio
It feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements.