Skip to content

Commit

Permalink
refactor: deprecate domain aliases
Browse files Browse the repository at this point in the history
BREAKING CHANGES: This patch removes the ability to use domain aliases, an obscure feature rarely used that had several issues and inconsistencies.
  • Loading branch information
aeneasr committed Jan 5, 2022
1 parent 2c97439 commit 894a2cc
Show file tree
Hide file tree
Showing 56 changed files with 96 additions and 477 deletions.
2 changes: 1 addition & 1 deletion cmd/courier/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func ServeMetrics(ctx cx.Context, r driver.Registry) {
router := x.NewRouterAdmin()

r.MetricsHandler().SetRoutes(router.Router)
n.Use(reqlog.NewMiddlewareFromLogger(l, "admin#"+c.SelfPublicURL(nil).String()))
n.Use(reqlog.NewMiddlewareFromLogger(l, "admin#"+c.SelfPublicURL().String()))
n.Use(r.PrometheusManager())

if tracer := r.Tracer(ctx); tracer.IsLoaded() {
Expand Down
4 changes: 2 additions & 2 deletions cmd/daemon/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func ServePublic(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
}
publicLogger := reqlog.NewMiddlewareFromLogger(
l,
"public#"+c.SelfPublicURL(nil).String(),
"public#"+c.SelfPublicURL().String(),
)
if r.Config(ctx).DisablePublicHealthRequestLog() {
publicLogger.ExcludePaths(healthx.AliveCheckPath, healthx.ReadyCheckPath)
Expand Down Expand Up @@ -156,7 +156,7 @@ func ServeAdmin(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
}
adminLogger := reqlog.NewMiddlewareFromLogger(
l,
"admin#"+c.SelfPublicURL(nil).String(),
"admin#"+c.SelfPublicURL().String(),
)
if r.Config(ctx).DisableAdminHealthRequestLog() {
adminLogger.ExcludePaths(healthx.AliveCheckPath, healthx.ReadyCheckPath)
Expand Down
55 changes: 1 addition & 54 deletions docs/docs/guides/multi-domain-cookies.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,7 @@ other scenarios.
## Base URL

The public base URL (`serve.public.base_url`) is used to compute redirect URLs,
form action URLs, and more. If you host Ory Kratos on more than one domain you
might want to enable the domain aliasing feature. This allows to register
additional base URLs. On incoming HTTP Requests, Ory Kratos checks the HTTP
`Host` Header and compares that to the list of domain aliases.

```yaml title="path/to/kratos/config.yml
serve:
public:
base_url: https://this-is-the-default/base-url
domain_aliases:
- match_domain: www.another-domain.com
base_path: /kratos
scheme: https
- match_domain: that-domain.com
base_path: /
scheme: http
```
If a match is found, the value `serve.public.base_url` will be ignored and
instead the base URL is computed:

```
<config.protocol>://<request.host + request.port><config.base_path>
```

Values `<request.host>`, `<request.port>` are set by the incoming HTTP request
and `<config.base_path>`, `<config.protocol>`, by the config:

- Incoming request is to `https://www.another-domain.com:123/kratos/identities/`
so the result is `https://www.another-domain.com:123/kratos`
- Incoming request is to `http://www.another-domain.com/kratos/sessions/` so the
result is `http://www.another-domain.com/kratos`
- Incoming request is to `https://that-domain.com/identities/` so the result is
`https://that-domain.com/identities`
form action URLs, and more.

## Cookies

Expand Down Expand Up @@ -77,26 +44,6 @@ session:

# Overrides cookies.samesite for session cookies
same_site: Strict
serve:
public:
domain_aliases:
# When a request is coming from www.another-domain.com or that-domain.com, these these override:
#
# - session.cookie.domain and session.cookie.path for sessions
# - cookies.domain and cookies.path for anti-CSRF cookies
- match_domain: www.another-domain.com
base_path: /kratos
# The scheme has NO effect on the cookie `secure` flag!
# scheme: https

- match_domain: that-domain.com
base_path: /

# The scheme has NO effect on the cookie `secure` flag!
# scheme: http
```
What **is not** currently possible is to set up Ory Kratos in a way where you
Expand Down
56 changes: 3 additions & 53 deletions driver/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -68,7 +67,6 @@ const (
ViperKeySecretsCipher = "secrets.cipher"
ViperKeyDisablePublicHealthRequestLog = "serve.public.request_log.disable_for_health"
ViperKeyPublicBaseURL = "serve.public.base_url"
ViperKeyPublicDomainAliases = "serve.public.domain_aliases"
ViperKeyPublicPort = "serve.public.port"
ViperKeyPublicHost = "serve.public.host"
ViperKeyPublicSocketOwner = "serve.public.socket.owner"
Expand Down Expand Up @@ -435,7 +433,7 @@ func (p *Config) DefaultIdentityTraitsSchemaURL() *url.URL {
}

func (p *Config) TOTPIssuer() string {
return p.Source().StringF(ViperKeyTOTPIssuer, p.SelfPublicURL(nil).Hostname())
return p.Source().StringF(ViperKeyTOTPIssuer, p.SelfPublicURL().Hostname())
}

func (p *Config) IdentityTraitsSchemas() Schemas {
Expand Down Expand Up @@ -710,56 +708,8 @@ func (p *Config) DisablePublicHealthRequestLog() bool {
return p.p.Bool(ViperKeyDisablePublicHealthRequestLog)
}

type DomainAlias struct {
BasePath string `json:"base_path"`
Scheme string `json:"scheme"`
MatchDomain string `json:"match_domain"`
}

func (p *Config) SelfPublicURL(r *http.Request) *url.URL {
primary := p.baseURL(ViperKeyPublicBaseURL, ViperKeyPublicHost, ViperKeyPublicPort, 4433)
if r == nil {
return primary
}

out, err := p.p.Marshal(kjson.Parser())
if err != nil {
p.l.WithError(err).Errorf("Unable to marshal configuration.")
return primary
}

raw := gjson.GetBytes(out, ViperKeyPublicDomainAliases).String()
if len(raw) == 0 {
return primary
}

var aliases []DomainAlias
if err := json.NewDecoder(bytes.NewBufferString(raw)).Decode(&aliases); err != nil {
p.l.WithError(err).WithField("config", raw).Warnf("Unable to unmarshal domain alias configuration, falling back to primary domain.")
return primary
}

host := r.URL.Query().Get("alias")
if len(host) == 0 {
host = r.Host
}

hostname, _, _ := net.SplitHostPort(host)
if hostname == "" {
hostname = host
}
for _, a := range aliases {
if strings.EqualFold(a.MatchDomain, hostname) || strings.EqualFold(a.MatchDomain, host) {
parsed := &url.URL{
Scheme: a.Scheme,
Host: host,
Path: a.BasePath,
}
return parsed
}
}

return primary
func (p *Config) SelfPublicURL() *url.URL {
return p.baseURL(ViperKeyPublicBaseURL, ViperKeyPublicHost, ViperKeyPublicPort, 4433)
}

func (p *Config) DisableAdminHealthRequestLog() bool {
Expand Down
60 changes: 5 additions & 55 deletions driver/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestViperProvider(t *testing.T) {
assert.Equal(t, "http://test.kratos.ory.sh/error", p.SelfServiceFlowErrorURL().String())

assert.Equal(t, "http://admin.kratos.ory.sh", p.SelfAdminURL().String())
assert.Equal(t, "http://public.kratos.ory.sh", p.SelfPublicURL(nil).String())
assert.Equal(t, "http://public.kratos.ory.sh", p.SelfPublicURL().String())

var ds []string
for _, v := range p.SelfServiceBrowserWhitelistedReturnToDomains() {
Expand Down Expand Up @@ -404,73 +404,23 @@ func TestProviderBaseURLs(t *testing.T) {
}

p := config.MustNew(t, logrusx.New("", ""), os.Stderr, configx.SkipValidation())
assert.Equal(t, "https://"+machineHostname+":4433/", p.SelfPublicURL(nil).String())
assert.Equal(t, "https://"+machineHostname+":4433/", p.SelfPublicURL().String())
assert.Equal(t, "https://"+machineHostname+":4434/", p.SelfAdminURL().String())

p.MustSet(config.ViperKeyPublicPort, 4444)
p.MustSet(config.ViperKeyAdminPort, 4445)
assert.Equal(t, "https://"+machineHostname+":4444/", p.SelfPublicURL(nil).String())
assert.Equal(t, "https://"+machineHostname+":4444/", p.SelfPublicURL().String())
assert.Equal(t, "https://"+machineHostname+":4445/", p.SelfAdminURL().String())

p.MustSet(config.ViperKeyPublicHost, "public.ory.sh")
p.MustSet(config.ViperKeyAdminHost, "admin.ory.sh")
assert.Equal(t, "https://public.ory.sh:4444/", p.SelfPublicURL(nil).String())
assert.Equal(t, "https://public.ory.sh:4444/", p.SelfPublicURL().String())
assert.Equal(t, "https://admin.ory.sh:4445/", p.SelfAdminURL().String())

// Set to dev mode
p.MustSet("dev", true)
assert.Equal(t, "http://public.ory.sh:4444/", p.SelfPublicURL(nil).String())
assert.Equal(t, "http://public.ory.sh:4444/", p.SelfPublicURL().String())
assert.Equal(t, "http://admin.ory.sh:4445/", p.SelfAdminURL().String())

// Check domain aliases
p.MustSet(config.ViperKeyPublicDomainAliases, []config.DomainAlias{
{
MatchDomain: "www.google.com",
BasePath: "/.ory/",
Scheme: "https",
},
{
MatchDomain: "www.amazon.com",
BasePath: "/",
Scheme: "http",
},
{
MatchDomain: "ory.sh:1234",
BasePath: "/",
Scheme: "https",
},
})
assert.Equal(t, "http://public.ory.sh:4444/", p.SelfPublicURL(nil).String())
assert.Equal(t, "http://public.ory.sh:4444/", p.SelfPublicURL(&http.Request{
URL: new(url.URL),
Host: "www.not-google.com",
}).String())
assert.Equal(t, "https://www.GooGle.com:312/.ory/", p.SelfPublicURL(&http.Request{
URL: new(url.URL),
Host: "www.GooGle.com:312",
}).String())
assert.Equal(t, "http://www.amazon.com/", p.SelfPublicURL(&http.Request{
URL: new(url.URL),
Host: "www.amazon.com",
}).String())

// Check domain aliases with alias query param
assert.Equal(t, "http://www.amazon.com/", p.SelfPublicURL(&http.Request{
URL: &url.URL{RawQuery: url.Values{"alias": {"www.amazon.com"}}.Encode()},
Host: "www.GooGle.com:312",
}).String())
assert.Equal(t, "https://ory.sh:1234/", p.SelfPublicURL(&http.Request{
URL: &url.URL{RawQuery: url.Values{"alias": {"ory.sh:1234"}}.Encode()},
Host: "www.amazon.com",
}).String())
assert.Equal(t, "http://www.amazon.com:8181/", p.SelfPublicURL(&http.Request{
URL: new(url.URL),
Host: "www.amazon.com:8181",
}).String())
assert.Equal(t, "http://www.amazon.com:8181/", p.SelfPublicURL(&http.Request{
URL: &url.URL{RawQuery: url.Values{"alias": {"www.amazon.com:8181"}}.Encode()},
Host: "www.GooGle.com:312",
}).String())
}

func TestViperProvider_Secrets(t *testing.T) {
Expand Down
69 changes: 14 additions & 55 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1534,55 +1534,6 @@
"base_url": {
"$ref": "#/definitions/baseUrl"
},
"domain_aliases": {
"title": "Domain Aliases",
"description": "Adds an alias domain. If a request with the hostname (FQDN) matching the hostname in the alias is found, that URL is used as the base URL.",
"type": "array",
"items": [
{
"additionalProperties": false,
"type": "object",
"required": [
"match_domain",
"base_path",
"scheme"
],
"properties": {
"match_domain": {
"minLength": 1,
"title": "Matching Domain",
"description": "Sets the matching domain. If the domain matches with this entry, the accompanying base_url will be used.",
"type": "string",
"examples": [
"localhost",
"my-domain.com"
]
},
"scheme": {
"title": "Scheme",
"description": "Sets the scheme, for example https or http.",
"type": "string",
"enum": [
"http",
"https"
]
},
"base_path": {
"minLength": 1,
"title": "Base Path",
"description": "Sets the base path for the matched domain.",
"type": "string",
"default": "/",
"pattern": "^/.*$",
"examples": [
"/",
"/.ory/kratos"
]
}
}
}
]
},
"host": {
"title": "Public Host",
"description": "The host (interface) kratos' public endpoint listens on.",
Expand Down Expand Up @@ -1999,7 +1950,7 @@
},
"additionalProperties": false
},
"ciphers" : {
"ciphers": {
"title": "Cipher Algorithm Configuration",
"type": "object",
"properties": {
Expand Down Expand Up @@ -2220,7 +2171,7 @@
{
"if": {
"properties": {
"ciphers" : {
"ciphers": {
"properties": {
"algorithm": {
"oneOf": [
Expand All @@ -2233,16 +2184,24 @@
]
}
},
"required": ["algorithm"]
"required": [
"algorithm"
]
}
},
"required": ["ciphers"]
"required": [
"ciphers"
]
},
"then": {
"required": ["secrets"],
"required": [
"secrets"
],
"properties": {
"secrets": {
"required": ["cipher"]
"required": [
"cipher"
]
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion persistence/sql/persister_identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,6 @@ func (p *Persister) injectTraitsSchemaURL(ctx context.Context, i *identity.Ident
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf(
`The JSON Schema "%s" for this identity's traits could not be found.`, i.SchemaID))
}
i.SchemaURL = s.SchemaURL(p.r.Config(ctx).SelfPublicURL(nil)).String()
i.SchemaURL = s.SchemaURL(p.r.Config(ctx).SelfPublicURL()).String()
return nil
}
2 changes: 1 addition & 1 deletion schema/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (h *Handler) getAll(w http.ResponseWriter, r *http.Request, ps httprouter.P
})
}

x.PaginationHeader(w, urlx.AppendPaths(h.r.Config(r.Context()).SelfPublicURL(r), fmt.Sprintf("/%s", SchemasPath)), int64(total), page, itemsPerPage)
x.PaginationHeader(w, urlx.AppendPaths(h.r.Config(r.Context()).SelfPublicURL(), fmt.Sprintf("/%s", SchemasPath)), int64(total), page, itemsPerPage)
h.r.Writer().Write(w, r, ss)
}

Expand Down
Loading

0 comments on commit 894a2cc

Please sign in to comment.