mirror of
https://github.com/Luzifer/nginx-sso.git
synced 2024-12-20 04:41:17 +00:00
Export errors for usage in plugins
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
83fcc4d0fe
commit
e9bff08810
14 changed files with 72 additions and 67 deletions
|
@ -30,7 +30,7 @@ func (a authCrowd) AuthenticatorID() string { return "crowd" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (a *authCrowd) Configure(yamlSource []byte) error {
|
func (a *authCrowd) Configure(yamlSource []byte) error {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
Providers struct {
|
Providers struct {
|
||||||
|
@ -43,7 +43,7 @@ func (a *authCrowd) Configure(yamlSource []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.Providers.Crowd == nil {
|
if envelope.Providers.Crowd == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
a.URL = envelope.Providers.Crowd.URL
|
a.URL = envelope.Providers.Crowd.URL
|
||||||
|
@ -51,7 +51,7 @@ func (a *authCrowd) Configure(yamlSource []byte) error {
|
||||||
a.AppPassword = envelope.Providers.Crowd.AppPassword
|
a.AppPassword = envelope.Providers.Crowd.AppPassword
|
||||||
|
|
||||||
if a.AppName == "" || a.AppPassword == "" {
|
if a.AppName == "" || a.AppPassword == "" {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
@ -62,7 +62,7 @@ func (a *authCrowd) Configure(yamlSource []byte) error {
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the plugins.ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
func (a authCrowd) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
func (a authCrowd) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
||||||
cc, err := a.crowd.GetCookieConfig()
|
cc, err := a.crowd.GetCookieConfig()
|
||||||
|
@ -76,7 +76,7 @@ func (a authCrowd) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
// Fine, we do have a cookie
|
// Fine, we do have a cookie
|
||||||
case http.ErrNoCookie:
|
case http.ErrNoCookie:
|
||||||
// Also fine, there is no cookie
|
// Also fine, there is no cookie
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
default:
|
default:
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ func (a authCrowd) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
sess, err := a.crowd.GetSession(ssoToken)
|
sess, err := a.crowd.GetSession(ssoToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Debug("Getting crowd session failed")
|
log.WithError(err).Debug("Getting crowd session failed")
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
user := sess.User.UserName
|
user := sess.User.UserName
|
||||||
|
@ -106,7 +106,7 @@ func (a authCrowd) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
// to authenticate the user or throw an error. If the user has
|
// to authenticate the user or throw an error. If the user has
|
||||||
// successfully logged in the persistent cookie should be written
|
// successfully logged in the persistent cookie should be written
|
||||||
// in order to use DetectUser for the next login.
|
// in order to use DetectUser for the next login.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the plugins.ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
func (a authCrowd) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func (a authCrowd) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
||||||
|
@ -122,7 +122,7 @@ func (a authCrowd) Login(res http.ResponseWriter, r *http.Request) (string, []pl
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"username": username,
|
"username": username,
|
||||||
}).WithError(err).Debug("Crowd authentication failed")
|
}).WithError(err).Debug("Crowd authentication failed")
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
http.SetCookie(res, &http.Cookie{
|
http.SetCookie(res, &http.Cookie{
|
||||||
|
|
20
auth_ldap.go
20
auth_ldap.go
|
@ -46,7 +46,7 @@ func (a authLDAP) AuthenticatorID() string { return "ldap" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (a *authLDAP) Configure(yamlSource []byte) error {
|
func (a *authLDAP) Configure(yamlSource []byte) error {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
Providers struct {
|
Providers struct {
|
||||||
|
@ -59,7 +59,7 @@ func (a *authLDAP) Configure(yamlSource []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.Providers.LDAP == nil {
|
if envelope.Providers.LDAP == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
a.EnableBasicAuth = envelope.Providers.LDAP.EnableBasicAuth
|
a.EnableBasicAuth = envelope.Providers.LDAP.EnableBasicAuth
|
||||||
|
@ -98,7 +98,7 @@ func (a *authLDAP) Configure(yamlSource []byte) error {
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the plugins.ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
func (a authLDAP) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
func (a authLDAP) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
||||||
var alias, user string
|
var alias, user string
|
||||||
|
@ -118,17 +118,17 @@ func (a authLDAP) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
if user == "" {
|
if user == "" {
|
||||||
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
if user, ok = sess.Values["user"].(string); !ok {
|
if user, ok = sess.Values["user"].(string); !ok {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
if alias, ok = sess.Values["alias"].(string); !ok {
|
if alias, ok = sess.Values["alias"].(string); !ok {
|
||||||
// Most likely an old cookie, force re-login
|
// Most likely an old cookie, force re-login
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// We had a cookie, lets renew it
|
// We had a cookie, lets renew it
|
||||||
|
@ -147,7 +147,7 @@ func (a authLDAP) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
// to authenticate the user or throw an error. If the user has
|
// to authenticate the user or throw an error. If the user has
|
||||||
// successfully logged in the persistent cookie should be written
|
// successfully logged in the persistent cookie should be written
|
||||||
// in order to use DetectUser for the next login.
|
// in order to use DetectUser for the next login.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the plugins.ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
func (a authLDAP) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func (a authLDAP) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
||||||
|
@ -200,7 +200,7 @@ func (a authLDAP) Logout(res http.ResponseWriter, r *http.Request) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkLogin searches for the username using the specified UserSearchFilter
|
// checkLogin searches for the username using the specified UserSearchFilter
|
||||||
// and returns the UserDN and an error (errNoValidUserFound / processing error)
|
// and returns the UserDN and an error (plugins.ErrNoValidUserFound / processing error)
|
||||||
func (a authLDAP) checkLogin(username, password, aliasAttribute string) (string, string, error) {
|
func (a authLDAP) checkLogin(username, password, aliasAttribute string) (string, string, error) {
|
||||||
l, err := a.dial()
|
l, err := a.dial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -224,13 +224,13 @@ func (a authLDAP) checkLogin(username, password, aliasAttribute string) (string,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sres.Entries) != 1 {
|
if len(sres.Entries) != 1 {
|
||||||
return "", "", errNoValidUserFound
|
return "", "", plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
userDN := sres.Entries[0].DN
|
userDN := sres.Entries[0].DN
|
||||||
|
|
||||||
if err := l.Bind(userDN, password); err != nil {
|
if err := l.Bind(userDN, password); err != nil {
|
||||||
return "", "", errNoValidUserFound
|
return "", "", plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
alias := sres.Entries[0].GetAttributeValue(aliasAttribute)
|
alias := sres.Entries[0].GetAttributeValue(aliasAttribute)
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (a authSimple) AuthenticatorID() string { return "simple" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (a *authSimple) Configure(yamlSource []byte) error {
|
func (a *authSimple) Configure(yamlSource []byte) error {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
Providers struct {
|
Providers struct {
|
||||||
|
@ -42,7 +42,7 @@ func (a *authSimple) Configure(yamlSource []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.Providers.Simple == nil {
|
if envelope.Providers.Simple == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
a.EnableBasicAuth = envelope.Providers.Simple.EnableBasicAuth
|
a.EnableBasicAuth = envelope.Providers.Simple.EnableBasicAuth
|
||||||
|
@ -55,7 +55,7 @@ func (a *authSimple) Configure(yamlSource []byte) error {
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the plugins.ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
func (a authSimple) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
func (a authSimple) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
||||||
var user string
|
var user string
|
||||||
|
@ -78,13 +78,13 @@ func (a authSimple) DetectUser(res http.ResponseWriter, r *http.Request) (string
|
||||||
if user == "" {
|
if user == "" {
|
||||||
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
user, ok = sess.Values["user"].(string)
|
user, ok = sess.Values["user"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// We had a cookie, lets renew it
|
// We had a cookie, lets renew it
|
||||||
|
@ -108,7 +108,7 @@ func (a authSimple) DetectUser(res http.ResponseWriter, r *http.Request) (string
|
||||||
// to authenticate the user or throw an error. If the user has
|
// to authenticate the user or throw an error. If the user has
|
||||||
// successfully logged in the persistent cookie should be written
|
// successfully logged in the persistent cookie should be written
|
||||||
// in order to use DetectUser for the next login.
|
// in order to use DetectUser for the next login.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the plugins.ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
func (a authSimple) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func (a authSimple) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
username := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "username"}, "-"))
|
||||||
|
@ -128,7 +128,7 @@ func (a authSimple) Login(res http.ResponseWriter, r *http.Request) (string, []p
|
||||||
return u, a.MFA[u], sess.Save(r, res)
|
return u, a.MFA[u], sess.Save(r, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginFields needs to return the fields required for this login
|
// LoginFields needs to return the fields required for this login
|
||||||
|
|
|
@ -26,7 +26,7 @@ func (a authToken) AuthenticatorID() string { return "token" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (a *authToken) Configure(yamlSource []byte) error {
|
func (a *authToken) Configure(yamlSource []byte) error {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
Providers struct {
|
Providers struct {
|
||||||
|
@ -39,7 +39,7 @@ func (a *authToken) Configure(yamlSource []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.Providers.Token == nil {
|
if envelope.Providers.Token == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Tokens = envelope.Providers.Token.Tokens
|
a.Tokens = envelope.Providers.Token.Tokens
|
||||||
|
@ -50,13 +50,13 @@ func (a *authToken) Configure(yamlSource []byte) error {
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the plugins.ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
func (a authToken) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
func (a authToken) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
||||||
authHeader := r.Header.Get("Authorization")
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
|
||||||
if !strings.HasPrefix(authHeader, "Token ") {
|
if !strings.HasPrefix(authHeader, "Token ") {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := strings.SplitN(authHeader, " ", 2)
|
tmp := strings.SplitN(authHeader, " ", 2)
|
||||||
|
@ -74,7 +74,7 @@ func (a authToken) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !userFound {
|
if !userFound {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
groups := []string{}
|
groups := []string{}
|
||||||
|
@ -91,10 +91,10 @@ func (a authToken) DetectUser(res http.ResponseWriter, r *http.Request) (string,
|
||||||
// to authenticate the user or throw an error. If the user has
|
// to authenticate the user or throw an error. If the user has
|
||||||
// successfully logged in the persistent cookie should be written
|
// successfully logged in the persistent cookie should be written
|
||||||
// in order to use DetectUser for the next login.
|
// in order to use DetectUser for the next login.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the plugins.ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
func (a authToken) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func (a authToken) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginFields needs to return the fields required for this login
|
// LoginFields needs to return the fields required for this login
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (a authYubikey) AuthenticatorID() string { return "yubikey" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (a *authYubikey) Configure(yamlSource []byte) error {
|
func (a *authYubikey) Configure(yamlSource []byte) error {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
Providers struct {
|
Providers struct {
|
||||||
|
@ -42,7 +42,7 @@ func (a *authYubikey) Configure(yamlSource []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.Providers.Yubikey == nil {
|
if envelope.Providers.Yubikey == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
a.ClientID = envelope.Providers.Yubikey.ClientID
|
a.ClientID = envelope.Providers.Yubikey.ClientID
|
||||||
|
@ -55,17 +55,17 @@ func (a *authYubikey) Configure(yamlSource []byte) error {
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the plugins.ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
func (a authYubikey) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
func (a authYubikey) DetectUser(res http.ResponseWriter, r *http.Request) (string, []string, error) {
|
||||||
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
sess, err := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
user, ok := sess.Values["user"].(string)
|
user, ok := sess.Values["user"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// We had a cookie, lets renew it
|
// We had a cookie, lets renew it
|
||||||
|
@ -88,7 +88,7 @@ func (a authYubikey) DetectUser(res http.ResponseWriter, r *http.Request) (strin
|
||||||
// to authenticate the user or throw an error. If the user has
|
// to authenticate the user or throw an error. If the user has
|
||||||
// successfully logged in the persistent cookie should be written
|
// successfully logged in the persistent cookie should be written
|
||||||
// in order to use DetectUser for the next login.
|
// in order to use DetectUser for the next login.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the plugins.ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
func (a authYubikey) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func (a authYubikey) Login(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
keyInput := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "key-input"}, "-"))
|
keyInput := r.FormValue(strings.Join([]string{a.AuthenticatorID(), "key-input"}, "-"))
|
||||||
|
@ -105,13 +105,13 @@ func (a authYubikey) Login(res http.ResponseWriter, r *http.Request) (string, []
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
// Not a valid authentication
|
// Not a valid authentication
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
user, ok := a.Devices[keyInput[:12]]
|
user, ok := a.Devices[keyInput[:12]]
|
||||||
if !ok {
|
if !ok {
|
||||||
// We do not have a definition for that key
|
// We do not have a definition for that key
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
sess, _ := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-")) // #nosec G104 - On error empty session is returned
|
sess, _ := cookieStore.Get(r, strings.Join([]string{mainCfg.Cookie.Prefix, a.AuthenticatorID()}, "-")) // #nosec G104 - On error empty session is returned
|
||||||
|
|
7
main.go
7
main.go
|
@ -17,6 +17,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/Luzifer/nginx-sso/plugins"
|
||||||
"github.com/Luzifer/rconfig"
|
"github.com/Luzifer/rconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -157,7 +158,7 @@ func handleAuthRequest(res http.ResponseWriter, r *http.Request) {
|
||||||
user, groups, err := detectUser(res, r)
|
user, groups, err := detectUser(res, r)
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
mainCfg.AuditLog.Log(auditEventValidate, r, map[string]string{"result": "no valid user found"}) // #nosec G104 - This is only logging
|
mainCfg.AuditLog.Log(auditEventValidate, r, map[string]string{"result": "no valid user found"}) // #nosec G104 - This is only logging
|
||||||
http.Error(res, "No valid user found", http.StatusUnauthorized)
|
http.Error(res, "No valid user found", http.StatusUnauthorized)
|
||||||
|
|
||||||
|
@ -194,7 +195,7 @@ func handleLoginRequest(res http.ResponseWriter, r *http.Request) {
|
||||||
// Simple authentication
|
// Simple authentication
|
||||||
user, mfaCfgs, err := loginUser(res, r)
|
user, mfaCfgs, err := loginUser(res, r)
|
||||||
switch err {
|
switch err {
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
auditFields["reason"] = "invalid credentials"
|
auditFields["reason"] = "invalid credentials"
|
||||||
mainCfg.AuditLog.Log(auditEventLoginFailure, r, auditFields) // #nosec G104 - This is only logging
|
mainCfg.AuditLog.Log(auditEventLoginFailure, r, auditFields) // #nosec G104 - This is only logging
|
||||||
http.Redirect(res, r, "/login?go="+url.QueryEscape(r.FormValue("go")), http.StatusFound)
|
http.Redirect(res, r, "/login?go="+url.QueryEscape(r.FormValue("go")), http.StatusFound)
|
||||||
|
@ -213,7 +214,7 @@ func handleLoginRequest(res http.ResponseWriter, r *http.Request) {
|
||||||
// MFA validation against configs from login
|
// MFA validation against configs from login
|
||||||
err = validateMFA(res, r, user, mfaCfgs)
|
err = validateMFA(res, r, user, mfaCfgs)
|
||||||
switch err {
|
switch err {
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
auditFields["reason"] = "invalid credentials"
|
auditFields["reason"] = "invalid credentials"
|
||||||
mainCfg.AuditLog.Log(auditEventLoginFailure, r, auditFields) // #nosec G104 - This is only logging
|
mainCfg.AuditLog.Log(auditEventLoginFailure, r, auditFields) // #nosec G104 - This is only logging
|
||||||
res.Header().Del("Set-Cookie") // Remove login cookie
|
res.Header().Del("Set-Cookie") // Remove login cookie
|
||||||
|
|
6
mfa.go
6
mfa.go
|
@ -44,7 +44,7 @@ func initializeMFAProviders(yamlSource []byte) error {
|
||||||
case nil:
|
case nil:
|
||||||
activeMFAProviders = append(activeMFAProviders, m)
|
activeMFAProviders = append(activeMFAProviders, m)
|
||||||
log.WithFields(log.Fields{"mfa_provider": m.ProviderID()}).Debug("Activated MFA provider")
|
log.WithFields(log.Fields{"mfa_provider": m.ProviderID()}).Debug("Activated MFA provider")
|
||||||
case errProviderUnconfigured:
|
case plugins.ErrProviderUnconfigured:
|
||||||
log.WithFields(log.Fields{"mfa_provider": m.ProviderID()}).Debug("MFA provider unconfigured")
|
log.WithFields(log.Fields{"mfa_provider": m.ProviderID()}).Debug("MFA provider unconfigured")
|
||||||
// This is okay.
|
// This is okay.
|
||||||
default:
|
default:
|
||||||
|
@ -70,7 +70,7 @@ func validateMFA(res http.ResponseWriter, r *http.Request, user string, mfaCfgs
|
||||||
case nil:
|
case nil:
|
||||||
// Validated successfully
|
// Validated successfully
|
||||||
return nil
|
return nil
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
// This is fine for now
|
// This is fine for now
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
|
@ -78,5 +78,5 @@ func validateMFA(res http.ResponseWriter, r *http.Request, user string, mfaCfgs
|
||||||
}
|
}
|
||||||
|
|
||||||
// No method could verify the user
|
// No method could verify the user
|
||||||
return errNoValidUserFound
|
return plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func (m mfaDuo) ProviderID() (id string) { return "duo" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (m *mfaDuo) Configure(yamlSource []byte) (err error) {
|
func (m *mfaDuo) Configure(yamlSource []byte) (err error) {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
MFA struct {
|
MFA struct {
|
||||||
|
@ -52,7 +52,7 @@ func (m *mfaDuo) Configure(yamlSource []byte) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.MFA.Duo == nil {
|
if envelope.MFA.Duo == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
m.IKey = envelope.MFA.Duo.IKey
|
m.IKey = envelope.MFA.Duo.IKey
|
||||||
|
@ -105,7 +105,7 @@ func (m mfaDuo) ValidateMFA(res http.ResponseWriter, r *http.Request, user strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report this provider was not able to verify the MFA request
|
// Report this provider was not able to verify the MFA request
|
||||||
return errNoValidUserFound
|
return plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mfaDuo) findIP(r *http.Request) (string, error) {
|
func (m mfaDuo) findIP(r *http.Request) (string, error) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (m mfaTOTP) ProviderID() (id string) {
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (m mfaTOTP) Configure(yamlSource []byte) (err error) { return nil }
|
func (m mfaTOTP) Configure(yamlSource []byte) (err error) { return nil }
|
||||||
|
|
||||||
// ValidateMFA takes the user from the login cookie and performs a
|
// ValidateMFA takes the user from the login cookie and performs a
|
||||||
|
@ -53,7 +53,7 @@ func (m mfaTOTP) ValidateMFA(res http.ResponseWriter, r *http.Request, user stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report this provider was not able to verify the MFA request
|
// Report this provider was not able to verify the MFA request
|
||||||
return errNoValidUserFound
|
return plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mfaTOTP) exec(c plugins.MFAConfig) (string, error) {
|
func (m mfaTOTP) exec(c plugins.MFAConfig) (string, error) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (m mfaYubikey) ProviderID() (id string) { return "yubikey" }
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the plugins.ErrProviderUnconfigured
|
||||||
func (m *mfaYubikey) Configure(yamlSource []byte) (err error) {
|
func (m *mfaYubikey) Configure(yamlSource []byte) (err error) {
|
||||||
envelope := struct {
|
envelope := struct {
|
||||||
MFA struct {
|
MFA struct {
|
||||||
|
@ -40,7 +40,7 @@ func (m *mfaYubikey) Configure(yamlSource []byte) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelope.MFA.Yubikey == nil {
|
if envelope.MFA.Yubikey == nil {
|
||||||
return errProviderUnconfigured
|
return plugins.ErrProviderUnconfigured
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ClientID = envelope.MFA.Yubikey.ClientID
|
m.ClientID = envelope.MFA.Yubikey.ClientID
|
||||||
|
@ -85,5 +85,5 @@ func (m mfaYubikey) ValidateMFA(res http.ResponseWriter, r *http.Request, user s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not a valid authentication
|
// Not a valid authentication
|
||||||
return errNoValidUserFound
|
return plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ type Authenticator interface {
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the ErrProviderUnconfigured
|
||||||
Configure(yamlSource []byte) (err error)
|
Configure(yamlSource []byte) (err error)
|
||||||
|
|
||||||
// DetectUser is used to detect a user without a login form from
|
// DetectUser is used to detect a user without a login form from
|
||||||
// a cookie, header or other methods
|
// a cookie, header or other methods
|
||||||
// If no user was detected the errNoValidUserFound needs to be
|
// If no user was detected the ErrNoValidUserFound needs to be
|
||||||
// returned
|
// returned
|
||||||
DetectUser(res http.ResponseWriter, r *http.Request) (user string, groups []string, err error)
|
DetectUser(res http.ResponseWriter, r *http.Request) (user string, groups []string, err error)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ type Authenticator interface {
|
||||||
// With the login result an array of mfaConfig must be returned. In
|
// With the login result an array of mfaConfig must be returned. In
|
||||||
// case there is no MFA config or the provider does not support MFA
|
// case there is no MFA config or the provider does not support MFA
|
||||||
// return nil.
|
// return nil.
|
||||||
// If the user did not login correctly the errNoValidUserFound
|
// If the user did not login correctly the ErrNoValidUserFound
|
||||||
// needs to be returned
|
// needs to be returned
|
||||||
Login(res http.ResponseWriter, r *http.Request) (user string, mfaConfigs []MFAConfig, err error)
|
Login(res http.ResponseWriter, r *http.Request) (user string, mfaConfigs []MFAConfig, err error)
|
||||||
|
|
||||||
|
|
8
plugins/errors.go
Normal file
8
plugins/errors.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrProviderUnconfigured = errors.New("No valid configuration found for this provider")
|
||||||
|
ErrNoValidUserFound = errors.New("No valid users found")
|
||||||
|
)
|
|
@ -10,7 +10,7 @@ type MFAProvider interface {
|
||||||
// Configure loads the configuration for the Authenticator from the
|
// Configure loads the configuration for the Authenticator from the
|
||||||
// global config.yaml file which is passed as a byte-slice.
|
// global config.yaml file which is passed as a byte-slice.
|
||||||
// If no configuration for the Authenticator is supplied the function
|
// If no configuration for the Authenticator is supplied the function
|
||||||
// needs to return the errProviderUnconfigured
|
// needs to return the ErrProviderUnconfigured
|
||||||
Configure(yamlSource []byte) (err error)
|
Configure(yamlSource []byte) (err error)
|
||||||
|
|
||||||
// ValidateMFA takes the user from the login cookie and performs a
|
// ValidateMFA takes the user from the login cookie and performs a
|
||||||
|
|
14
registry.go
14
registry.go
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -12,9 +11,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errProviderUnconfigured = errors.New("No valid configuration found for this provider")
|
|
||||||
errNoValidUserFound = errors.New("No valid users found")
|
|
||||||
|
|
||||||
authenticatorRegistry = []plugins.Authenticator{}
|
authenticatorRegistry = []plugins.Authenticator{}
|
||||||
authenticatorRegistryMutex sync.RWMutex
|
authenticatorRegistryMutex sync.RWMutex
|
||||||
|
|
||||||
|
@ -40,7 +36,7 @@ func initializeAuthenticators(yamlSource []byte) error {
|
||||||
case nil:
|
case nil:
|
||||||
tmp = append(tmp, a)
|
tmp = append(tmp, a)
|
||||||
log.WithFields(log.Fields{"authenticator": a.AuthenticatorID()}).Debug("Activated authenticator")
|
log.WithFields(log.Fields{"authenticator": a.AuthenticatorID()}).Debug("Activated authenticator")
|
||||||
case errProviderUnconfigured:
|
case plugins.ErrProviderUnconfigured:
|
||||||
log.WithFields(log.Fields{"authenticator": a.AuthenticatorID()}).Debug("Authenticator unconfigured")
|
log.WithFields(log.Fields{"authenticator": a.AuthenticatorID()}).Debug("Authenticator unconfigured")
|
||||||
// This is okay.
|
// This is okay.
|
||||||
default:
|
default:
|
||||||
|
@ -66,14 +62,14 @@ func detectUser(res http.ResponseWriter, r *http.Request) (string, []string, err
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
return user, groups, err
|
return user, groups, err
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
// This is okay.
|
// This is okay.
|
||||||
default:
|
default:
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginUser(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
func loginUser(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAConfig, error) {
|
||||||
|
@ -85,14 +81,14 @@ func loginUser(res http.ResponseWriter, r *http.Request) (string, []plugins.MFAC
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
return user, mfaCfgs, nil
|
return user, mfaCfgs, nil
|
||||||
case errNoValidUserFound:
|
case plugins.ErrNoValidUserFound:
|
||||||
// This is okay.
|
// This is okay.
|
||||||
default:
|
default:
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil, errNoValidUserFound
|
return "", nil, plugins.ErrNoValidUserFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func logoutUser(res http.ResponseWriter, r *http.Request) error {
|
func logoutUser(res http.ResponseWriter, r *http.Request) error {
|
||||||
|
|
Loading…
Reference in a new issue