mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
hybrid IdP (check regular users too); closes #122
previously, when IdP was enabled, the password-based login would be entirely disabled. This was a semi-conscious decision, based on the assumption that you would always want to use IdP after enabling it. it makes more sense to keep password-based login working as usual, conditionally disengaging it for requests which contains a valid IdP username header. This makes it possible to define fallback users, or API-only users, and all similar escape hatches.
This commit is contained in:
parent
db3c0b0907
commit
64501fd7f1
|
@ -1488,7 +1488,9 @@ replace copyparty passwords with oauth and such
|
|||
|
||||
you can disable the built-in password-based login system, and instead replace it with a separate piece of software (an identity provider) which will then handle authenticating / authorizing of users; this makes it possible to login with passkeys / fido2 / webauthn / yubikey / ldap / active directory / oauth / many other single-sign-on contraptions
|
||||
|
||||
a popular choice is [Authelia](https://www.authelia.com/) (config-file based), another one is [authentik](https://goauthentik.io/) (GUI-based, more complex)
|
||||
* the regular config-defined users will be used as a fallback for requests which don't include a valid (trusted) IdP username header
|
||||
|
||||
some popular identity providers are [Authelia](https://www.authelia.com/) (config-file based) and [authentik](https://goauthentik.io/) (GUI-based, more complex)
|
||||
|
||||
there is a [docker-compose example](./docs/examples/docker/idp-authelia-traefik) which is hopefully a good starting point (alternatively see [./docs/idp.md](./docs/idp.md) if you're the DIY type)
|
||||
|
||||
|
|
|
@ -1083,7 +1083,7 @@ def add_cert(ap, cert_path):
|
|||
def add_auth(ap):
|
||||
ses_db = os.path.join(E.cfg, "sessions.db")
|
||||
ap2 = ap.add_argument_group('IdP / identity provider / user authentication options')
|
||||
ap2.add_argument("--idp-h-usr", metavar="HN", type=u, default="", help="bypass the copyparty authentication checks and assume the request-header \033[33mHN\033[0m contains the username of the requesting user (for use with authentik/oauth/...)\n\033[1;31mWARNING:\033[0m if you enable this, make sure clients are unable to specify this header themselves; must be washed away and replaced by a reverse-proxy")
|
||||
ap2.add_argument("--idp-h-usr", metavar="HN", type=u, default="", help="bypass the copyparty authentication checks if the request-header \033[33mHN\033[0m contains a username to associate the request with (for use with authentik/oauth/...)\n\033[1;31mWARNING:\033[0m if you enable this, make sure clients are unable to specify this header themselves; must be washed away and replaced by a reverse-proxy")
|
||||
ap2.add_argument("--idp-h-grp", metavar="HN", type=u, default="", help="assume the request-header \033[33mHN\033[0m contains the groupname of the requesting user; can be referenced in config files for group-based access control")
|
||||
ap2.add_argument("--idp-h-key", metavar="HN", type=u, default="", help="optional but recommended safeguard; your reverse-proxy will insert a secret header named \033[33mHN\033[0m into all requests, and the other IdP headers will be ignored if this header is not present")
|
||||
ap2.add_argument("--idp-gsep", metavar="RE", type=u, default="|:;+,", help="if there are multiple groups in \033[33m--idp-h-grp\033[0m, they are separated by one of the characters in \033[33mRE\033[0m")
|
||||
|
|
|
@ -542,8 +542,14 @@ class HttpCli(object):
|
|||
except:
|
||||
pass
|
||||
|
||||
self.pw = uparam.get("pw") or self.headers.get("pw") or bauth or cookie_pw
|
||||
self.uname = (
|
||||
self.asrv.sesa.get(self.pw)
|
||||
or self.asrv.iacct.get(self.asrv.ah.hash(self.pw))
|
||||
or "*"
|
||||
)
|
||||
|
||||
if self.args.idp_h_usr:
|
||||
self.pw = ""
|
||||
idp_usr = self.headers.get(self.args.idp_h_usr) or ""
|
||||
if idp_usr:
|
||||
idp_grp = (
|
||||
|
@ -588,20 +594,11 @@ class HttpCli(object):
|
|||
idp_grp = ""
|
||||
|
||||
if idp_usr in self.asrv.vfs.aread:
|
||||
self.pw = ""
|
||||
self.uname = idp_usr
|
||||
self.html_head += "<script>var is_idp=1</script>\n"
|
||||
else:
|
||||
self.log("unknown username: [%s]" % (idp_usr), 1)
|
||||
self.uname = "*"
|
||||
else:
|
||||
self.uname = "*"
|
||||
else:
|
||||
self.pw = uparam.get("pw") or self.headers.get("pw") or bauth or cookie_pw
|
||||
self.uname = (
|
||||
self.asrv.sesa.get(self.pw)
|
||||
or self.asrv.iacct.get(self.asrv.ah.hash(self.pw))
|
||||
or "*"
|
||||
)
|
||||
|
||||
if self.args.ipu and self.uname == "*":
|
||||
self.uname = self.conn.ipu_iu[self.conn.ipu_nm.map(self.ip)]
|
||||
|
|
Loading…
Reference in a new issue