-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support HTTP BasicAuth for authentication if $AUTH_USER is set #7143
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is neat, thank you! I know we are not generally adding auth methods, but this seems simple enough to maintain.
@@ -0,0 +1,45 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Docker image seems unrelated to the auth changes, could we remove it from this PR? Happy to read about it in another PR/issue, but at first glance I am not sure it is something we should be maintaining here.
@@ -0,0 +1,15 @@ | |||
github.copilot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we omit this file? Seems unrelated to code-server itself.
@@ -0,0 +1,12 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also seems unrelated to this particular PR.
@@ -0,0 +1,44 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
@@ -86,6 +86,7 @@ | |||
"safe-buffer": "^5.2.1", | |||
"safe-compare": "^1.1.4", | |||
"semver": "^7.5.4", | |||
"tslib": "^2.8.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was this added for? We have no direct dependency on tslib, do we?
} else if (args.auth === AuthType.HttpBasic) { | ||
logger.info(" - HTTP basic authentication is enabled") | ||
logger.info(" - Using user from $AUTH_USER") | ||
logger.info(" - Using password from $PASSWORD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The password might be from the config, so we would need to check args.usingEnvPassword
(just like the block above). We can maybe combine these blocks. Something like:
if (args.auth === AuthType.Password || args.auth === AuthType.HttpBasic) {
logger.info(" - Authentication is enabled")
if (args.usingEnvPassword) {
logger.info(" - Using password from $PASSWORD")
} else if (args.usingEnvHashedPassword) {
logger.info(" - Using password from $HASHED_PASSWORD")
} else {
logger.info(` - Using password from ${args.config}`)
}
if (args.auth === AuthType.HttpBasic) {
logger.info(" - With user ${args["auth-user"]}") // or add an args.usingEnvAuthUser and switch on it as appropriate
}
} else {
logger.info(" - Authentication is disabled")
}
@@ -118,6 +119,11 @@ router.get("/", ensureVSCodeLoaded, async (req, res, next) => { | |||
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew | |||
|
|||
if (!isAuthenticated) { | |||
// If auth is HttpBasic, return a 401. | |||
if (req.args.auth === AuthType.HttpBasic) { | |||
res.setHeader('WWW-Authenticate', 'Basic realm="Access to the site"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to set this header on the other places where we throw unauthorized for basic auth? And in the ensureAuthenticated
middleware as well.
Also, could be cool to put the name in the realm, maybe:
`Basic realm=${req.args["app-name"] || "code-server"}`
@@ -0,0 +1,27 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to the PR?
@@ -132,6 +151,9 @@ export const authenticated = async (req: express.Request): Promise<boolean> => { | |||
|
|||
return await isCookieValid(isCookieValidArgs) | |||
} | |||
case AuthType.HttpBasic: { | |||
return validateBasicAuth(req.headers.authorization, req.args["auth-user"], req.args.password); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if someone sets HASHED_PASSWORD but not PASSWORD and then sets auth=basic-auth
? I think it would use the config password instead (a default one is always generated), which might be unexpected. We could use handlePasswordValidation
to support both HASHED_PASSWORD and PASSWORD, or we could error when HASHED_PASSWORD is set and say it can only be used with PASSWORD.
const base64Credentials = authHeader.split(' ')[1]; | ||
const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8'); | ||
const [username, password] = credentials.split(':'); | ||
return username === authUser && password === authPassword; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use safeCompare
instead of ===
probably.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, did not mean to approve quite yet. 😄
Fixes #7142