Implement rendering of authorization server errors

main
Jan Dittberner 10 months ago
parent 63e3333c4d
commit 79ab816489

@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- implement logout-successful handler
- implement rendering of authorization server errors
### Changed
- recommend `mkcert` to generate certificates for local development
- change default configuration to use files recommended in README.md

@ -101,7 +101,7 @@ func main() {
logoutHandler := handlers.NewLogoutHandler(logger, adminClient.Admin)
logoutSuccessHandler := handlers.NewLogoutSuccessHandler(logger, bundle, catalog)
errorHandler := handlers.NewErrorHandler()
errorHandler := handlers.NewErrorHandler(logger, bundle, catalog)
staticFiles := http.FileServer(http.FS(ui.Static))
router := http.NewServeMux()

@ -18,6 +18,7 @@ limitations under the License.
package handlers
import (
"bytes"
"context"
"fmt"
"html/template"
@ -25,6 +26,7 @@ import (
"net/http"
"code.cacert.org/cacert/oidc-idp/internal/services"
"code.cacert.org/cacert/oidc-idp/ui"
"github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
)
@ -161,15 +163,62 @@ func ErrorHandling(
}
type ErrorHandler struct {
logger *log.Logger
bundle *i18n.Bundle
messageCatalog *services.MessageCatalog
template *template.Template
}
func (e *ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
_, _ = fmt.Fprintf(w, `
didumm %#v
`, r.URL.Query())
func (h *ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
accept := r.Header.Get("Accept-Language")
localizer := i18n.NewLocalizer(h.bundle, accept)
errorName := r.URL.Query().Get("error")
errorDescription := r.URL.Query().Get("error_description")
h.logger.WithFields(log.Fields{
"error_name": errorName,
"error_description": errorDescription,
}).Debug("error from Hydra")
rendered := bytes.NewBuffer(make([]byte, 0))
msg := h.messageCatalog.LookupMessage
msgMarkdown := h.messageCatalog.LookupMarkdownMessage
err := h.template.Lookup("base").Execute(rendered, map[string]interface{}{
"Title": msg("AuthServerErrorTitle", nil, localizer),
"Explanation": template.HTML(msgMarkdown("AuthServerErrorExplanation", nil, localizer)),
"ErrorMessage": errorDescription,
})
if err != nil {
h.logger.WithError(err).Error("template rendering failed")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
w.Header().Add("Pragma", "no-cache")
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
_, _ = w.Write(rendered.Bytes())
}
func NewErrorHandler() *ErrorHandler {
return &ErrorHandler{}
func NewErrorHandler(logger *log.Logger, bundle *i18n.Bundle, messageCatalog *services.MessageCatalog) *ErrorHandler {
return &ErrorHandler{
logger: logger,
bundle: bundle,
messageCatalog: messageCatalog,
template: template.Must(template.ParseFS(
ui.Templates,
"templates/base.gohtml",
"templates/hydra_error.gohtml"),
),
}
}

@ -37,6 +37,15 @@ func AddMessages(catalog *MessageCatalog) error {
ID: "ErrorUnknown",
Other: "Unknown error",
}
messages["AuthServerErrorTitle"] = &i18n.Message{
ID: "AuthServerErrorTitle",
Other: "Authorization server returned an error",
}
messages["AuthServerErrorExplanation"] = &i18n.Message{
ID: "AuthServerErrorExplanation",
Other: "A request that your browser sent to the authorization server caused an error." +
" The authorization server returned details about the error that are printed below.",
}
messages["TitleRequestConsent"] = &i18n.Message{
ID: "TitleRequestConsent",
Other: "Application requests your consent",

@ -1,3 +1,11 @@
[AuthServerErrorExplanation]
hash = "sha1-d0abcb1757c2a0ebf154112e0f768d41e2ad494c"
other = "Eine Anfrage, die dein Browser an den Authorization-Server geschickt hat, hat einen Fehler verursacht. Der Authorization-Server hat die unten ausgegebenen Details zum Fehler zurückgegeben."
[AuthServerErrorTitle]
hash = "sha1-fa3294b49220d6de6f68825d03195e3f33e88378"
other = "Fehlermeldung vom Authorization-Server"
[CertLoginIntroText]
hash = "sha1-e9f7c0522e49ffacc49e3fc35c6ffd31e495baf6"
other = "Die Anwendung <strong>{{ .ClientName }}</strong> fragt nach einer Anmeldung."

@ -1,3 +1,5 @@
AuthServerErrorExplanation = "A request that your browser sent to the authorization server caused an error. The authorization server returned details about the error that are printed below."
AuthServerErrorTitle = "Authorization server returned an error"
CertLoginIntroText = "The application <strong>{{ .ClientName }}</strong> requests a login."
CertLoginRequestText = "Do you want to use the chosen identity from the certificate for authentication?"
ClaimsInformation = "In addition the application wants access to the following information:"

@ -0,0 +1,10 @@
{{ define "content" }}
<div class="container">
<img src="/images/CAcert-logo.svg" width="300" height="68" alt="CAcert" class="mb-4">
<h1>{{ .Title }}</h1>
{{ .Explanation }}
{{ if .ErrorMessage }}
<div class="alert alert-danger">{{ .ErrorMessage }}</div>
{{ end }}
</div>
{{ end }}
Loading…
Cancel
Save