Provide method to avoid Nimbus message parsing restrictions
Description
Environment
blocks
is related to
Activity
Henri MikkonenSeptember 6, 2024 at 9:20 AM
Switched the hardcoded bean IDs to use properties instead.
idp.oidc.requestParser.IntrospectionRequest
idp.oidc.requestParser.PushedAuthorizationRequest
idp.oidc.requestParser.RevocationRequest
idp.oidc.requestParser.AuthenticationRequest
idp.oidc.requestParser.AuthorizationRequest
idp.oidc.requestParser.EndSessionRequest
idp.oidc.requestParser.RegisterRequest
idp.oidc.requestParser.TokenRequest
idp.oidc.requestParser.UserInfoRequest
They’re documented at https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3785326593/OPMessageHandling .
Henri MikkonenMay 13, 2024 at 3:03 PM
Just pushed a first version that provides what I described in the earlier comment.
The custom parsers may be wired via message-specific beans:
IntrospectionRequestParser
PushedAuthorizationRequestParser
RevocationRequestParser
AuthenticationRequestParser
AuthorizationRequestParser
EndSessionRequestParser
RegisterRequestParser
TokenRequestParser
UserInfoRequestParser
Henri MikkonenMay 13, 2024 at 3:03 PM
Having said that, if you have to do it, there is a way, by going top-down from the servlet request and tracking through the binding key we attach the PRC with. And we do it where we have to.
It’s a good hint for the custom parser developers that the PRC may be found via servlet request.
Scott CantorMay 13, 2024 at 2:48 PM
Yes, the design kind of meets in a “non-ideal” way because a lot of the code operates around PRCs but the mesaging APIs act in isolation and actually produce the MessageContext, so it’s not hooked up yet and you can’t just walk up the tree to get access to more stuff.
Having said that, if you have to do it, there is a way, by going top-down from the servlet request and tracking through the binding key we attach the PRC with. And we do it where we have to.
Henri MikkonenMay 13, 2024 at 2:40 PM
Another option could perhaps be to provide configurable hook for bean transforming
HttpServletRequest
into the endpoint specific message. Currently our message decoders first parseHTTPRequest
from the servlet request and then hand it to the Nimbus parser. If we refactored the parsing logic to be taken fromBiFunction<ProfileRequestContext,HttpServletRequest,?>
“parsing strategy” (where ? refers to the expected Nimbus message object), then the building of Nimbus objects could be fully customised.
I forgot that the decoders are implementing MessageDecoder
. The SWF action org.opensaml.profile.action.impl.DecodeMessage
calls decoders with decode()
method, so there’s no access to ProfileRequestContext
.
Now it feels that the best way to provide custom parsing support with the current codebase is the following:
Base decoder (
BaseOAuth2RequestDecoder<T extends Request>
) could containCustomNimbusRequestParser<T> customRequestParser
-variableIt’s null by default but if it’s set, it’ll be used instead of the
abstract T parseMessage()
-method, which is implemented by all the implementing decodersThis way we don’t need to modify the inheriting classes, just the parent one
It makes sense to add
interface CustomNimbusRequestParser<T extends Request>
instead of usingFunction
, as we probably want extensions to be able to useMessageDecodingException
T parse(@Nonnull final HttpServletRequest httpServletRequest) throws MessageDecodingException;
One example of such message parsing restriction was solved within https://shibboleth.atlassian.net/browse/JOIDC-155 by renaming the
resource
parameter into a custom one before handing the NimbusHTTPRequest
object to the message parser. This way we allowed spec-violating values to be used with the parameter.@Pasquale Barbaro noticed that similar restriction exists for client authentication parsing: Nimbus currently supports only
client_secret_jwt
andprivate_key_jwt
methods forclient_assertion
-parameter parsing. Probably due to that they have hardcoded the parsing to check that only single JWT value may exist inclient_assertion
, not depending onclient_assertion_type
. In some cases (such as https://shibboleth.atlassian.net/browse/JOIDC-204) there might be a chain of JWTs. This parsing restriction denies wiring of such extensions.If we provided a generic manipulation hook for the
HTTPRequest
object before it's passed to the Nimbus parser, the deployers could apply custom manipulation logic to avoid parsing restrictions.