OAuth: Add custom unauthorized message option in configuration (#93717)

* read custom message from config

* Read error key from bootdata

* oopsie

* Remove console.log

* Update docs and sample/default inis

* Add default key value to the config
pull/93903/head
Tobias Skarhed 9 months ago committed by GitHub
parent 08dab3f816
commit f49b4d35f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      conf/defaults.ini
  2. 3
      conf/sample.ini
  3. 4
      docs/sources/setup-grafana/configure-grafana/_index.md
  4. 6
      pkg/api/login_oauth.go
  5. 3
      pkg/setting/setting.go
  6. 12
      public/app/core/components/Login/LoginCtrl.tsx
  7. 3
      public/locales/en-US/grafana.json
  8. 3
      public/locales/pseudo-LOCALE/grafana.json

@ -582,6 +582,9 @@ oauth_auto_login = false
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
oauth_state_cookie_max_age = 600
# Sets a custom oAuth error message. This is useful if you need to point the users to a specific location for support.
oauth_login_error_message = oauth.login.error
# Minimum wait time in milliseconds for the server lock retry mechanism.
# The server lock retry mechanism is used to prevent multiple Grafana instances from
# simultaneously refreshing OAuth tokens. This mechanism waits at least this amount

@ -583,6 +583,9 @@
# Deprecated, use auto_login option for specific provider instead.
;oauth_auto_login = false
# Sets a custom oAuth error message. This is useful if you need to point the users to a specific location for support.
;oauth_login_error_message = oauth.login.error
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
;oauth_state_cookie_max_age = 600

@ -964,6 +964,10 @@ This setting is ignored if multiple OAuth providers are configured. Default is `
How many seconds the OAuth state cookie lives before being deleted. Default is `600` (seconds)
Administrators can increase this if they experience OAuth login state mismatch errors.
### oauth_login_error_message
A custom error message for when users are unauthorized. Default is a key for an internationalized phrase in the frontend, `Login provider denied login request`.
### oauth_refresh_token_server_lock_min_wait_ms
Minimum wait time in milliseconds for the server lock retry mechanism. Default is `1000` (milliseconds). The server lock retry mechanism is used to prevent multiple Grafana instances from simultaneously refreshing OAuth tokens. This mechanism waits at least this amount of time before retrying to acquire the server lock.

@ -1,8 +1,7 @@
package api
import (
"errors"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/services/authn"
@ -21,8 +20,7 @@ func (hs *HTTPServer) OAuthLogin(reqCtx *contextmodel.ReqContext) {
if errorParam := reqCtx.Query("error"); errorParam != "" {
errorDesc := reqCtx.Query("error_description")
hs.log.Error("failed to login ", "error", errorParam, "errorDesc", errorDesc)
hs.redirectWithError(reqCtx, errors.New("login provider denied login request"), "error", errorParam, "errorDesc", errorDesc)
hs.redirectWithError(reqCtx, errutil.Unauthorized("oauth.login", errutil.WithPublicMessage(hs.Cfg.OAuthLoginErrorMessage)).Errorf("Login provider denied login request"))
return
}

@ -263,6 +263,7 @@ type Cfg struct {
// OAuth
OAuthAutoLogin bool
OAuthLoginErrorMessage string
OAuthCookieMaxAge int
OAuthAllowInsecureEmailLookup bool
OAuthRefreshTokenServerLockMinWaitMs int64
@ -1621,6 +1622,8 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
cfg.Logger.Warn("[Deprecated] The oauth_auto_login configuration setting is deprecated. Please use auto_login inside auth provider section instead.")
}
// Default to the translation key used in the frontend
cfg.OAuthLoginErrorMessage = valueAsString(auth, "oauth_login_error_message", "oauth.login.error")
cfg.OAuthCookieMaxAge = auth.Key("oauth_state_cookie_max_age").MustInt(600)
cfg.OAuthRefreshTokenServerLockMinWaitMs = auth.Key("oauth_refresh_token_server_lock_min_wait_ms").MustInt64(1000)
cfg.SignoutRedirectUrl = valueAsString(auth, "signout_redirect_url", "")

@ -51,7 +51,8 @@ export class LoginCtrl extends PureComponent<Props, State> {
isLoggingIn: false,
isChangingPassword: false,
showDefaultPasswordWarning: false,
loginErrorMessage: config.loginError,
// oAuth unauthorized sets the redirect error message in the bootdata, hence we need to check the key here
loginErrorMessage: getBootDataErrMessage(config.loginError),
};
}
@ -178,3 +179,12 @@ function getErrorMessage(err: FetchError<undefined | { messageId?: string; messa
return err.data?.message;
}
}
function getBootDataErrMessage(str?: string) {
switch (str) {
case 'oauth.login.error':
return t('oauth.login.error', 'Login provider denied login request');
default:
return str;
}
}

@ -1845,6 +1845,9 @@
"server-discovery-modal-close": "Close",
"server-discovery-modal-loading": "Loading...",
"server-discovery-modal-submit": "Submit"
},
"login": {
"error": "Login provider denied login request"
}
},
"panel": {

@ -1845,6 +1845,9 @@
"server-discovery-modal-close": "Cľőşę",
"server-discovery-modal-loading": "Ŀőäđįʼnģ...",
"server-discovery-modal-submit": "Ŝūþmįŧ"
},
"login": {
"error": "Ŀőģįʼn přővįđęř đęʼnįęđ ľőģįʼn řęqūęşŧ"
}
},
"panel": {

Loading…
Cancel
Save