2021-09-09 09:00:58 +00:00
|
|
|
package application
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/url"
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
2022-03-03 09:40:07 +00:00
|
|
|
"goauthentik.io/api/v3"
|
2023-02-19 16:35:25 +00:00
|
|
|
"goauthentik.io/internal/config"
|
2021-09-09 09:00:58 +00:00
|
|
|
"golang.org/x/oauth2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type OIDCEndpoint struct {
|
|
|
|
oauth2.Endpoint
|
2023-01-13 15:22:03 +00:00
|
|
|
TokenIntrospection string
|
2021-09-09 09:00:58 +00:00
|
|
|
EndSessionEndpoint string
|
2022-01-21 12:29:51 +00:00
|
|
|
JwksUri string
|
2023-01-19 14:39:30 +00:00
|
|
|
Issuer string
|
2021-09-09 09:00:58 +00:00
|
|
|
}
|
|
|
|
|
2023-01-19 14:39:30 +00:00
|
|
|
func updateURL(rawUrl string, scheme string, host string) string {
|
|
|
|
u, err := url.Parse(rawUrl)
|
|
|
|
if err != nil {
|
|
|
|
return rawUrl
|
|
|
|
}
|
|
|
|
u.Host = host
|
|
|
|
u.Scheme = scheme
|
|
|
|
return u.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string, embedded bool) OIDCEndpoint {
|
2021-09-09 09:00:58 +00:00
|
|
|
authUrl := p.OidcConfiguration.AuthorizationEndpoint
|
|
|
|
endUrl := p.OidcConfiguration.EndSessionEndpoint
|
2023-02-19 16:35:25 +00:00
|
|
|
issuer := p.OidcConfiguration.Issuer
|
2021-09-09 09:00:58 +00:00
|
|
|
ep := OIDCEndpoint{
|
|
|
|
Endpoint: oauth2.Endpoint{
|
|
|
|
AuthURL: authUrl,
|
2023-03-18 17:51:20 +00:00
|
|
|
TokenURL: p.OidcConfiguration.TokenEndpoint,
|
2021-09-09 09:00:58 +00:00
|
|
|
AuthStyle: oauth2.AuthStyleInParams,
|
|
|
|
},
|
|
|
|
EndSessionEndpoint: endUrl,
|
2023-03-18 17:51:20 +00:00
|
|
|
JwksUri: p.OidcConfiguration.JwksUri,
|
2023-01-14 19:54:34 +00:00
|
|
|
TokenIntrospection: p.OidcConfiguration.IntrospectionEndpoint,
|
2023-02-19 16:35:25 +00:00
|
|
|
Issuer: issuer,
|
2021-09-09 09:00:58 +00:00
|
|
|
}
|
2023-03-18 17:51:20 +00:00
|
|
|
// For the embedded outpost, we use the configure `authentik_host` for the browser URLs
|
|
|
|
// and localhost (which is what we've got from the API) for backchannel URLs
|
|
|
|
//
|
|
|
|
// For other outposts, when `AUTHENTIK_HOST_BROWSER` is set, we use that for the browser URLs
|
|
|
|
// and use what we got from the API for backchannel
|
|
|
|
hostBrowser := config.Get().AuthentikHostBrowser
|
|
|
|
if !embedded && hostBrowser == "" {
|
2021-09-09 09:00:58 +00:00
|
|
|
return ep
|
|
|
|
}
|
2023-03-18 17:51:20 +00:00
|
|
|
var newHost *url.URL
|
|
|
|
if embedded {
|
|
|
|
if authentikHost == "" {
|
|
|
|
log.Warning("Outpost has localhost/blank API Connection but no authentik_host is configured.")
|
|
|
|
return ep
|
|
|
|
}
|
|
|
|
aku, err := url.Parse(authentikHost)
|
|
|
|
if err != nil {
|
|
|
|
return ep
|
|
|
|
}
|
|
|
|
newHost = aku
|
|
|
|
} else if hostBrowser != "" {
|
|
|
|
aku, err := url.Parse(hostBrowser)
|
|
|
|
if err != nil {
|
|
|
|
return ep
|
|
|
|
}
|
|
|
|
newHost = aku
|
2021-09-09 09:00:58 +00:00
|
|
|
}
|
2023-03-18 17:51:20 +00:00
|
|
|
// Update all browser-accessed URLs to use the new host and scheme
|
|
|
|
ep.AuthURL = updateURL(authUrl, newHost.Scheme, newHost.Host)
|
|
|
|
ep.EndSessionEndpoint = updateURL(endUrl, newHost.Scheme, newHost.Host)
|
|
|
|
// Update issuer to use the same host and scheme, which would normally break as we don't
|
|
|
|
// change the token URL here, but the token HTTP transport overwrites the Host header
|
|
|
|
//
|
|
|
|
// This is only used in embedded outposts as there we can guarantee that the request
|
|
|
|
// is routed correctly
|
|
|
|
if embedded {
|
|
|
|
ep.Issuer = updateURL(ep.Issuer, newHost.Scheme, newHost.Host)
|
2021-09-09 09:00:58 +00:00
|
|
|
}
|
|
|
|
return ep
|
|
|
|
}
|