3
0

Resolve SAML initialization issues

* invalid certificates
* invalid URL
* enabled/disabled
This commit is contained in:
Tomaž Jerman
2021-09-22 10:53:15 +02:00
parent 1b3a811cfd
commit 48a8705053
5 changed files with 49 additions and 10 deletions

View File

@@ -258,7 +258,14 @@ func (svc *service) LoadSamlService(ctx context.Context, s *settings.Settings) (
// idp metadata needs to be loaded before
// the internal samlsp package
md, err := saml.FetchIDPMetadata(ctx, *idpUrl)
if err != nil {
return
}
ru, err := url.Parse(svc.opt.BaseURL)
if err != nil {
return
}
rootURL := &url.URL{
Scheme: ru.Scheme,
@@ -266,11 +273,9 @@ func (svc *service) LoadSamlService(ctx context.Context, s *settings.Settings) (
Host: ru.Host,
}
if err != nil {
return
}
srvc, err = saml.NewSamlSPService(saml.SamlSPArgs{
Enabled: s.Saml.Enabled,
AcsURL: links.SamlCallback,
MetaURL: links.SamlMetadata,
SloURL: links.SamlLogout,

View File

@@ -9,7 +9,19 @@ import (
func (h AuthHandlers) samlInit(w http.ResponseWriter, r *http.Request) {
r = copyProviderToContext(r)
h.Log.Info("starting saml authentication flow")
h.Log.Info("starting SAML authentication flow")
if h.SamlSPService.Handler() == nil {
h.Log.Error("SAML service not initialized")
w.WriteHeader(http.StatusServiceUnavailable)
return
}
if !h.SamlSPService.Enabled {
h.Log.Warn("failed to start SAML authentication flow: disabled")
w.WriteHeader(http.StatusServiceUnavailable)
return
}
ex := external.NewSamlExternalHandler(h.SamlSPService)
beginUserAuth(w, r, ex)

View File

@@ -100,10 +100,21 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
r.Post(tbp(l.OAuth2DefaultClient), h.handle(h.oauth2authorizeDefaultClientProc))
})
// Wrapping SAML structs so we assure that fresh ones are always used in case
// of settings changes.
//
// @todo refactor this with a wrapping struct to handle serve HTTPS and pass
// calls to internal SAML service.
r.Group(func(r chi.Router) {
r.Handle(tbp(l.SamlMetadata), h.SamlSPService)
r.Handle(tbp(l.SamlCallback), h.SamlSPService)
r.HandleFunc(tbp(l.SamlInit), h.samlInit)
r.HandleFunc(tbp(l.SamlMetadata), func(rw http.ResponseWriter, r *http.Request) {
h.SamlSPService.ServeHTTP(rw, r)
})
r.HandleFunc(tbp(l.SamlCallback), func(rw http.ResponseWriter, r *http.Request) {
h.SamlSPService.ServeHTTP(rw, r)
})
r.HandleFunc(tbp(l.SamlInit), func(rw http.ResponseWriter, r *http.Request) {
h.samlInit(rw, r)
})
})
r.Route(tbp(l.External)+"/{provider}", func(r chi.Router) {

View File

@@ -17,6 +17,8 @@ const defaultNameIdentifier = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAd
type (
SamlSPService struct {
Enabled bool
IdpURL url.URL
Host url.URL
IDPUserMeta *IdpIdentityPayload
@@ -27,6 +29,8 @@ type (
}
SamlSPArgs struct {
Enabled bool
AcsURL string
MetaURL string
SloURL string
@@ -49,7 +53,6 @@ func NewSamlSPService(args SamlSPArgs) (s *SamlSPService, err error) {
)
keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0])
if err != nil {
return
}
@@ -77,7 +80,6 @@ func NewSamlSPService(args SamlSPArgs) (s *SamlSPService, err error) {
// internal samlsp service
handler, err := samlsp.New(opts)
if err != nil {
err = errors.Wrap(err, "could not init SAML SP handler")
return
@@ -87,6 +89,8 @@ func NewSamlSPService(args SamlSPArgs) (s *SamlSPService, err error) {
handler.ServiceProvider = sp
s = &SamlSPService{
Enabled: args.Enabled,
sp: sp,
handler: handler,
@@ -130,5 +134,10 @@ func (ssp *SamlSPService) Handler() *samlsp.Middleware {
// ServeHTTP enables us to use the service directly
// in the router
func (ssp SamlSPService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if ssp.handler == nil || !ssp.Enabled {
w.WriteHeader(http.StatusServiceUnavailable)
return
}
ssp.handler.ServeHTTP(w, r)
}