add middleware to rewrite the /.well-known/openid-configuration endpoint for external idps

This commit is contained in:
Willy Kloucek
2022-08-05 13:48:22 +02:00
parent 4699fba073
commit 94646c8060
4 changed files with 70 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
Enhancement: Fix behavior for foobar (in present tense)
We've added the configuration option `PROXY_OIDC_REWRITE_WELLKNOWN` to rewrite the `/.well-known/openid-configuration` endpoint.
If active, it serves the `/.well-known/openid-configuration` response of the original IDP configured in `OCIS_OIDC_ISSUER` / `PROXY_OIDC_ISSUER`. This is needed so that the Desktop Client, Android Client and iOS Client can discover the OIDC identity provider.
Previously this rewrite needed to be performed with an external proxy as NGINX or Traefik if an external IDP was used.
https://github.com/owncloud/ocis/pull/4346
https://github.com/owncloud/ocis/issues/2819
https://github.com/owncloud/ocis/issues/3280

View File

@@ -173,6 +173,11 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
chimiddleware.RequestID,
middleware.AccessLog(logger),
middleware.HTTPSRedirect,
middleware.OIDCWellKnownRewrite(
logger, cfg.OIDC.Issuer,
cfg.OIDC.RewriteWellKnown,
oidcHTTPClient,
),
// now that we established the basics, on with authentication middleware
middleware.Authentication(

View File

@@ -95,6 +95,7 @@ type OIDC struct {
AccessTokenVerifyMethod string `yaml:"access_token_verify_method" env:"PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD" desc:"Sets how OIDC access tokens should be verified. Possible values are 'none' and 'jwt'. When using 'none', no special validation apart from using it for accessing the IPD's userinfo endpoint will be done. When using 'jwt', it tries to parse the access token as a jwt token and verifies the signature using the keys published on the IDP's 'jwks_uri'."`
UserinfoCache UserinfoCache `yaml:"user_info_cache"`
JWKS JWKS `yaml:"jwks"`
RewriteWellKnown bool `yaml:"rewrite_well_known" env:"PROXY_OIDC_REWRITE_WELLKNOWN" desc:"Enables rewriting the /.well-known/openid-configuration to the configured OIDC issuer. Needed by the Desktop Client, Android Client and iOS Client to discover the OIDC provider."`
}
type JWKS struct {

View File

@@ -0,0 +1,54 @@
package middleware
import (
"io"
"net/http"
"net/url"
"path"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
var (
wellKnownPath = "/.well-known/openid-configuration"
)
// OIDCWellKnownRewrite is a middleware that rewrites the /.well-known/openid-configuration endpoint for external IDPs.
func OIDCWellKnownRewrite(logger log.Logger, oidcISS string, rewrite bool, oidcClient *http.Client) func(http.Handler) http.Handler {
oidcURL, _ := url.Parse(oidcISS)
oidcURL.Path = path.Join(oidcURL.Path, wellKnownPath)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if rewrite && path.Clean(r.URL.Path) == wellKnownPath {
wellKnownRes, err := oidcClient.Get(oidcURL.String())
if err != nil {
logger.Error().
Err(err).
Str("middleware", "oidc wellknown rewrite").
Str("url", oidcURL.String()).
Msg("get information from url failed")
w.WriteHeader(http.StatusInternalServerError)
}
defer wellKnownRes.Body.Close()
copyHeader(w.Header(), wellKnownRes.Header)
w.WriteHeader(wellKnownRes.StatusCode)
io.Copy(w, wellKnownRes.Body)
return
}
next.ServeHTTP(w, r)
})
}
}
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}