Response modes
New in 0.130.0, Duende 8.0.1's, measured. The code flow answers the way the client asks with response_mode:
response_mode |
The answer |
|---|---|
query, or none |
a redirect with the parameters in the redirect URI's query string |
form_post |
a page that posts the parameters to the redirect URI as a form (OAuth 2.0 Form Post Response Mode) |
fragment |
a redirect with the parameters in the redirect URI's fragment |
Errors go back in the same mode as success. The form_post page is Duende's: it posts itself on load, with a button for
a browser that runs no script; its Content-Security-Policy allows only that script, named by its hash ('unsafe-inline'
is added at CspLevel.One, which has no hash sources); it is sent no-store, because it carries a code, and with
Referrer-Policy: no-referrer.
ASP.NET Core's OpenID Connect handler asks for form_post by default, so its clients get what they asked for rather than
a code in the query string. Written out, as a web application signing in against this server would have it — from
samples/Server.Hosting:
/// <summary>
/// Signs users in with the authorization code flow and PKCE, asking for the code by form post — the handler's
/// default, written out here — so it never appears in a URL.
/// </summary>
public static IServiceCollection AddServerSignIn(this IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "web";
options.ClientSecret = "web-secret";
options.ResponseType = OpenIdConnectResponseType.Code;
options.ResponseMode = OpenIdConnectResponseMode.FormPost;
options.UsePkce = true;
options.SaveTokens = true;
options.Scope.Add("api");
options.Scope.Add("offline_access");
});
return services;
}
Client libraries shows the same handler in a back end for a front end that calls APIs as its user.
Any other value — query.jwt (JARM, which Duende does not have either), or Form_Post, since the match is exact — is
refused with unsupported_response_type and "Invalid response_mode", on the error page rather than at the client, there
being no knowing how a client that asked for a mode this server lacks would read its answer. Until 0.130.0
response_mode was not read at all: every answer went in the query, whatever was asked.
Discovery lists response_modes_supported as form_post, query, fragment, in Duende's order, under
DiscoveryOptions.ShowResponseModes (on by default); until 0.130.0 it said query only, and went with
ShowResponseTypes. ValidatedAuthorizeRequest.ResponseMode, deleted in 0.26.0, is back with the value.
The authorization code flow is recorded end to end.