mirror of
https://github.com/Luzifer/nginx-sso.git
synced 2024-12-20 12:51:17 +00:00
Allow to configure anonymous access (#48)
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
21aee74144
commit
c0886ce964
4 changed files with 57 additions and 2 deletions
9
acl.go
9
acl.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
35
acl_test.go
35
acl_test.go
|
@ -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",
|
||||||
|
|
7
core.go
7
core.go
|
@ -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())
|
||||||
|
|
8
main.go
8
main.go
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue