In our current SAML callback route, when the server receives a SAML response, it should validate the SAML response, insert that user into the database then issue a JWT wrapped in a cookie that holds the user info.
In the implementation below, its inserting the user, then validate the SAML response, which is not the right way, if there's a middle man that can alter the assertions in the SAML response, it will be still inserted even if the validation fails. I couldn't get it to work using this custom implementation because this line below
securityConfig.security.callback(defaultUrl = securityConfig.idpMetadata.callbackUrl, setCsrfCookie = false)
returns a type Route.
Below is the route implementation:
def callbackRoute(securityConfig: SecurityConfig): server.Route = path("callback") {
formField("SAMLResponse") { samlResponse =>
val userAttributes: UserAttributes = constructUserAttributes(samlResponse)
onComplete(securityConfig.loginService.authenticateUser(userAttributes)) {
case Success(token) =>
setCookie(HttpCookie("Authorization", token, secure = true)) {
//below is the PAC4J callback, that will validate the XML SAML response
securityConfig.security.callback(defaultUrl = callbackUrl)
}
case Failure(exception) => complete((StatusCodes.InternalServerError, s"An error occurred: ${exception.getMessage}"))
}
}
}
Please advise, thanks.
You may have a custom logic on the callback by defining your own CustomCallbackLogic
component at the configuration level: https://www.pac4j.org/docs/config.html#3-advanced