fix(oidc): handle authorization post requests (#4270)

This fixes an issue where the authorization endpoint was not handling post requests as per the specification. It also fixes the missing CORS middleware on the authorization endpoint.
pull/4260/head
James Elliott 2022-10-26 19:14:43 +11:00 committed by GitHub
parent 89166adf54
commit a283fda6d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 18 deletions

View File

@ -13,10 +13,10 @@ import (
"github.com/authelia/authelia/v4/internal/oidc" "github.com/authelia/authelia/v4/internal/oidc"
) )
// OpenIDConnectAuthorizationGET handles GET requests to the OpenID Connect 1.0 Authorization endpoint. // OpenIDConnectAuthorization handles GET/POST requests to the OpenID Connect 1.0 Authorization endpoint.
// //
// https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint // https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
func OpenIDConnectAuthorizationGET(ctx *middlewares.AutheliaCtx, rw http.ResponseWriter, r *http.Request) { func OpenIDConnectAuthorization(ctx *middlewares.AutheliaCtx, rw http.ResponseWriter, r *http.Request) {
var ( var (
requester fosite.AuthorizeRequester requester fosite.AuthorizeRequester
responder fosite.AuthorizeResponder responder fosite.AuthorizeResponder

View File

@ -197,19 +197,19 @@ type CORSPolicy struct {
// HandleOPTIONS is an OPTIONS handler that just adds CORS headers, the Allow header, and sets the status code to 204 // HandleOPTIONS is an OPTIONS handler that just adds CORS headers, the Allow header, and sets the status code to 204
// without a body. This handler should generally not be used without using WithAllowedMethods. // without a body. This handler should generally not be used without using WithAllowedMethods.
func (p CORSPolicy) HandleOPTIONS(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) HandleOPTIONS(ctx *fasthttp.RequestCtx) {
p.handleOPTIONS(ctx) p.handleOPTIONS(ctx)
p.handle(ctx) p.handle(ctx)
} }
// HandleOnlyOPTIONS is an OPTIONS handler that just handles the Allow header, and sets the status code to 204 // HandleOnlyOPTIONS is an OPTIONS handler that just handles the Allow header, and sets the status code to 204
// without a body. This handler should generally not be used without using WithAllowedMethods. // without a body. This handler should generally not be used without using WithAllowedMethods.
func (p CORSPolicy) HandleOnlyOPTIONS(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) HandleOnlyOPTIONS(ctx *fasthttp.RequestCtx) {
p.handleOPTIONS(ctx) p.handleOPTIONS(ctx)
} }
// Middleware provides a middleware that adds the appropriate CORS headers for this CORSPolicyBuilder. // Middleware provides a middleware that adds the appropriate CORS headers for this CORSPolicyBuilder.
func (p CORSPolicy) Middleware(next fasthttp.RequestHandler) (handler fasthttp.RequestHandler) { func (p *CORSPolicy) Middleware(next fasthttp.RequestHandler) (handler fasthttp.RequestHandler) {
return func(ctx *fasthttp.RequestCtx) { return func(ctx *fasthttp.RequestCtx) {
p.handle(ctx) p.handle(ctx)
@ -217,7 +217,7 @@ func (p CORSPolicy) Middleware(next fasthttp.RequestHandler) (handler fasthttp.R
} }
} }
func (p CORSPolicy) handle(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handle(ctx *fasthttp.RequestCtx) {
if !p.enabled { if !p.enabled {
return return
} }
@ -229,7 +229,7 @@ func (p CORSPolicy) handle(ctx *fasthttp.RequestCtx) {
} }
} }
func (p CORSPolicy) handleOPTIONS(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handleOPTIONS(ctx *fasthttp.RequestCtx) {
ctx.Response.ResetBody() ctx.Response.ResetBody()
/* The OPTIONS method should not return a 204 as per the following specifications when read together: /* The OPTIONS method should not return a 204 as per the following specifications when read together:
@ -250,13 +250,13 @@ func (p CORSPolicy) handleOPTIONS(ctx *fasthttp.RequestCtx) {
} }
} }
func (p CORSPolicy) handleVary(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handleVary(ctx *fasthttp.RequestCtx) {
if len(p.vary) != 0 { if len(p.vary) != 0 {
ctx.Response.Header.SetBytesKV(headerVary, p.vary) ctx.Response.Header.SetBytesKV(headerVary, p.vary)
} }
} }
func (p CORSPolicy) handleCORS(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handleCORS(ctx *fasthttp.RequestCtx) {
var ( var (
originURL *url.URL originURL *url.URL
err error err error
@ -302,7 +302,7 @@ func (p CORSPolicy) handleCORS(ctx *fasthttp.RequestCtx) {
p.handleAllowedMethods(ctx) p.handleAllowedMethods(ctx)
} }
func (p CORSPolicy) handleAllowedMethods(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handleAllowedMethods(ctx *fasthttp.RequestCtx) {
switch len(p.methods) { switch len(p.methods) {
case 0: case 0:
// TODO: It may be beneficial to be able to control this automatic behaviour. // TODO: It may be beneficial to be able to control this automatic behaviour.
@ -314,7 +314,7 @@ func (p CORSPolicy) handleAllowedMethods(ctx *fasthttp.RequestCtx) {
} }
} }
func (p CORSPolicy) handleAllowedHeaders(ctx *fasthttp.RequestCtx) { func (p *CORSPolicy) handleAllowedHeaders(ctx *fasthttp.RequestCtx) {
switch len(p.headers) { switch len(p.headers) {
case 0: case 0:
// TODO: It may be beneficial to be able to control this automatic behaviour. // TODO: It may be beneficial to be able to control this automatic behaviour.

View File

@ -261,21 +261,23 @@ func handleRouter(config schema.Configuration, providers middlewares.Providers)
r.GET("/api/oidc/jwks", policyCORSPublicGET.Middleware(middlewareOIDC(handlers.JSONWebKeySetGET))) r.GET("/api/oidc/jwks", policyCORSPublicGET.Middleware(middlewareOIDC(handlers.JSONWebKeySetGET)))
policyCORSAuthorization := middlewares.NewCORSPolicyBuilder(). policyCORSAuthorization := middlewares.NewCORSPolicyBuilder().
WithAllowedMethods("OPTIONS", "GET"). WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodGet, fasthttp.MethodPost).
WithAllowedOrigins(allowedOrigins...). WithAllowedOrigins(allowedOrigins...).
WithEnabled(utils.IsStringInSlice(oidc.EndpointAuthorization, config.IdentityProviders.OIDC.CORS.Endpoints)). WithEnabled(utils.IsStringInSlice(oidc.EndpointAuthorization, config.IdentityProviders.OIDC.CORS.Endpoints)).
Build() Build()
r.OPTIONS(oidc.EndpointPathAuthorization, policyCORSAuthorization.HandleOnlyOPTIONS) r.OPTIONS(oidc.EndpointPathAuthorization, policyCORSAuthorization.HandleOnlyOPTIONS)
r.GET(oidc.EndpointPathAuthorization, middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET))) r.GET(oidc.EndpointPathAuthorization, policyCORSAuthorization.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorization))))
r.POST(oidc.EndpointPathAuthorization, policyCORSAuthorization.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorization))))
// TODO (james-d-elliott): Remove in GA. This is a legacy endpoint. // TODO (james-d-elliott): Remove in GA. This is a legacy endpoint.
r.OPTIONS("/api/oidc/authorize", policyCORSAuthorization.HandleOnlyOPTIONS) r.OPTIONS("/api/oidc/authorize", policyCORSAuthorization.HandleOnlyOPTIONS)
r.GET("/api/oidc/authorize", middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET))) r.GET("/api/oidc/authorize", policyCORSAuthorization.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorization))))
r.POST("/api/oidc/authorize", policyCORSAuthorization.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorization))))
policyCORSToken := middlewares.NewCORSPolicyBuilder(). policyCORSToken := middlewares.NewCORSPolicyBuilder().
WithAllowCredentials(true). WithAllowCredentials(true).
WithAllowedMethods("OPTIONS", "POST"). WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodPost).
WithAllowedOrigins(allowedOrigins...). WithAllowedOrigins(allowedOrigins...).
WithEnabled(utils.IsStringInSlice(oidc.EndpointToken, config.IdentityProviders.OIDC.CORS.Endpoints)). WithEnabled(utils.IsStringInSlice(oidc.EndpointToken, config.IdentityProviders.OIDC.CORS.Endpoints)).
Build() Build()
@ -285,7 +287,7 @@ func handleRouter(config schema.Configuration, providers middlewares.Providers)
policyCORSUserinfo := middlewares.NewCORSPolicyBuilder(). policyCORSUserinfo := middlewares.NewCORSPolicyBuilder().
WithAllowCredentials(true). WithAllowCredentials(true).
WithAllowedMethods("OPTIONS", "GET", "POST"). WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodGet, fasthttp.MethodPost).
WithAllowedOrigins(allowedOrigins...). WithAllowedOrigins(allowedOrigins...).
WithEnabled(utils.IsStringInSlice(oidc.EndpointUserinfo, config.IdentityProviders.OIDC.CORS.Endpoints)). WithEnabled(utils.IsStringInSlice(oidc.EndpointUserinfo, config.IdentityProviders.OIDC.CORS.Endpoints)).
Build() Build()
@ -296,7 +298,7 @@ func handleRouter(config schema.Configuration, providers middlewares.Providers)
policyCORSIntrospection := middlewares.NewCORSPolicyBuilder(). policyCORSIntrospection := middlewares.NewCORSPolicyBuilder().
WithAllowCredentials(true). WithAllowCredentials(true).
WithAllowedMethods("OPTIONS", "POST"). WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodPost).
WithAllowedOrigins(allowedOrigins...). WithAllowedOrigins(allowedOrigins...).
WithEnabled(utils.IsStringInSlice(oidc.EndpointIntrospection, config.IdentityProviders.OIDC.CORS.Endpoints)). WithEnabled(utils.IsStringInSlice(oidc.EndpointIntrospection, config.IdentityProviders.OIDC.CORS.Endpoints)).
Build() Build()
@ -310,7 +312,7 @@ func handleRouter(config schema.Configuration, providers middlewares.Providers)
policyCORSRevocation := middlewares.NewCORSPolicyBuilder(). policyCORSRevocation := middlewares.NewCORSPolicyBuilder().
WithAllowCredentials(true). WithAllowCredentials(true).
WithAllowedMethods("OPTIONS", "POST"). WithAllowedMethods(fasthttp.MethodOptions, fasthttp.MethodPost).
WithAllowedOrigins(allowedOrigins...). WithAllowedOrigins(allowedOrigins...).
WithEnabled(utils.IsStringInSlice(oidc.EndpointRevocation, config.IdentityProviders.OIDC.CORS.Endpoints)). WithEnabled(utils.IsStringInSlice(oidc.EndpointRevocation, config.IdentityProviders.OIDC.CORS.Endpoints)).
Build() Build()