1
0
Fork 0
mirror of https://github.com/Luzifer/nginx-sso.git synced 2024-10-18 07:34:22 +00:00

Allow to configure anonymous access (#48)

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2019-12-28 13:12:18 +00:00 committed by GitHub
parent 21aee74144
commit c0886ce964
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 2 deletions

9
acl.go
View file

@ -9,6 +9,8 @@ import (
"github.com/Luzifer/go_helpers/v2/str" "github.com/Luzifer/go_helpers/v2/str"
) )
const groupAnonymous = "@_anonymous"
type aclRule struct { type aclRule struct {
Field string `yaml:"field"` Field string `yaml:"field"`
Invert bool `yaml:"invert"` Invert bool `yaml:"invert"`
@ -148,7 +150,12 @@ func (a aclRuleSet) HasAccess(user string, groups []string, r *http.Request) acl
} }
} }
if str.StringInSlice("@_authenticated", a.Allow) && user != "" { // Allow special group @_authenticated if any non-anonymous user is set
if str.StringInSlice("@_authenticated", a.Allow) && !str.StringInSlice(user, []string{"", "\x00"}) {
return accessAllow
}
if str.StringInSlice(groupAnonymous, a.Allow) {
return accessAllow return accessAllow
} }

View file

@ -77,12 +77,47 @@ func TestGroupAuthenticated(t *testing.T) {
t.Error("Access was denied") t.Error("Access was denied")
} }
if r.HasAccess("\x00", nil, aclTestRequest(fields)) == accessAllow {
t.Error("Access was allowed to unauth-user")
}
if r.HasAccess("", nil, aclTestRequest(fields)) == accessAllow {
t.Error("Access was allowed to empty user")
}
r.Allow = []string{"testgroup"} r.Allow = []string{"testgroup"}
if r.HasAccess(aclTestUser, aclTestGroups, aclTestRequest(fields)) == accessAllow { if r.HasAccess(aclTestUser, aclTestGroups, aclTestRequest(fields)) == accessAllow {
t.Error("Access was allowed") t.Error("Access was allowed")
} }
} }
func TestAnonymousAccess(t *testing.T) {
r := aclRuleSet{
Rules: []aclRule{
{
Field: "field_a",
MatchString: aclTestString("expected"),
},
},
Allow: []string{groupAnonymous},
}
fields := map[string]string{
"field_a": "expected",
}
if r.HasAccess(aclTestUser, aclTestGroups, aclTestRequest(fields)) != accessAllow {
t.Error("Access was denied")
}
if r.HasAccess("", nil, aclTestRequest(fields)) != accessAllow {
t.Error("Access without user was denied")
}
if r.HasAccess("\x00", nil, aclTestRequest(fields)) != accessAllow {
t.Error("Access with special unauth-user was denied")
}
}
func TestInvertedRegexMatcher(t *testing.T) { func TestInvertedRegexMatcher(t *testing.T) {
fields := map[string]string{ fields := map[string]string{
"field_a": "expected", "field_a": "expected",

View file

@ -14,12 +14,17 @@ import (
) )
func registerModules() { func registerModules() {
// Start with very simple, local auth providers as they are cheap
// in their execution and therefore if they are used nginx-sso
// can process far more requests than through the other providers
registerAuthenticator(simple.New(cookieStore)) registerAuthenticator(simple.New(cookieStore))
registerAuthenticator(token.New())
// Afterwards utilize the more expensive remove providers
registerAuthenticator(crowd.New()) registerAuthenticator(crowd.New())
registerAuthenticator(ldap.New(cookieStore)) registerAuthenticator(ldap.New(cookieStore))
registerAuthenticator(google.New(cookieStore)) registerAuthenticator(google.New(cookieStore))
registerAuthenticator(oidc.New(cookieStore)) registerAuthenticator(oidc.New(cookieStore))
registerAuthenticator(token.New())
registerAuthenticator(auth_yubikey.New(cookieStore)) registerAuthenticator(auth_yubikey.New(cookieStore))
registerMFAProvider(duo.New()) registerMFAProvider(duo.New())

View file

@ -153,6 +153,14 @@ func handleAuthRequest(res http.ResponseWriter, r *http.Request) {
switch err { switch err {
case plugins.ErrNoValidUserFound: case plugins.ErrNoValidUserFound:
// No valid user found, check whether special anonymous "user" has access
// Username is set to 0x0 character to prevent accidential whitelist-match
if mainCfg.ACL.HasAccess(string(0x0), nil, r) {
mainCfg.AuditLog.Log(auditEventValidate, r, map[string]string{"result": "anonymous access granted"}) // #nosec G104 - This is only logging
res.WriteHeader(http.StatusOK)
return
}
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)