Add support for extending Response Modes
Closed this issue · 3 comments
Is your feature request related to a problem? Please describe.
Hi, for our OpenID implicit flow, we have clients with user agents that do not support redirects and fragments, but a custom agreed response for the id_token
and redirect information.
RFC 6749 Section 4.2.2 leaves open the option to provide other kind of responses:
Developers should note that some user-agents do not support the
inclusion of a fragment component in the HTTP "Location" response
header field. Such clients will require using other methods for
redirecting the client than a 3xx redirection response -- for
example, returning an HTML page that includes a 'continue' button
with an action linked to the redirection URI.
OpenID oauth v2 multiple response types governs how response_mode
param must behave and provides a real life example of how they can be extended:
See OAuth 2.0 Form Post Response Mode OAuth.Post for an example of a specification that defines an additional Response Mode. Note that it is expected that additional Response Modes may be defined by other specifications in the future...
Currently fosite
supports the standard oauth2 and openid response modes query, fragment, form_post
but it does not have a way to provide additional ones.
Describe the solution you'd like
In short, I would like that fosite
provides an extension point to set additional response modes.
The following are the proposed implementation changes to achieve it:
fosite.go
: Add an attribute tofosite.Fosite
to set aResponseModeHandler
which handles custom response modes
type Fosite struct {
...
ResponseModeHandler ResponseModeHandler
}
response_mode_handler.go
type ResponseModeHandler interface {
// Set of response modes supported by this handler. Being an array
// allows for composition without adding complexity to `Fosite`
ResponseModes() []string
// Writes Authorize Response errors
WriteAuthorizeError(...)
// Writes successful Authorize Response
WriteAuthorizeResponse(...)
}
-
authorize_error.go:63
: Check if response_mode is infosite.Fosite.ResponseModeHandler.ResponseModes()
and if so write error using itsWriteAuthorizeError
. It will behave similar toResponseModeFormPost
. -
authorize_write.go:41
: Add a extra case forfosite.Fosite.ResponseModeHandler.ResponseModes()
. It behaves similar toResponseModeFormPost
case -
authorize_request_handler.go
: AdjustParseResponseMode
to include handlerResponseModes()
in the validation
Describe alternatives you've considered
- custom fork
- change clients: currently not possible, clients are not in our control, and they are thousands
Additional context
The change is 100% backwards compatible, if no handler is register fosite provides its standard functionality, if registered fosite will include it on authorization validations, write error and write success.
Already supported response_mode
methods won't be modified to use the new interface, they can remain explicit and hardcoded since they are standard.
What do you think?
Would you be open for this contribution?
Please take a look to the draft PR #592. Your comments are welcome!
Btw. I created this issue with other username, but it is me :)
I am curious, why is form_post
not working for your clients? What is the mode you are hoping to implement? Would it make sense to contribute this extra mode to fosite?
Hi @mitar, basically we do not use general purpose but tailored user-agents. Those are closed-source user-agents with workflows/endpoints and redirections hard-coded, they neither understand HTTP redirects nor are capable to extract values from #fragments
, they expect a json
response similar to the Access Token Successful/Error Reponse (rfc6749). Those thousand clients are already in the market using this custom authorize response, and updating them is not an option due to technical and also project coordination overhead.
example response
{
"id_token": "..."
}
Because it is a response tailored to our needs I do not think it will be useful in fosite, but if needed or there are others interested in this solution I could also include it. For now I think it will be more useful to include an example similar to what I have implemented for our case, in the docs/how-to
folder, explaining how this extension can be used.