Repository navigation
fix(server): decode Basic auth as UTF-8 and split on the first colon #3290
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
base: master
Are you sure you want to change the base?
Changes from all commits
1fd9a21
56a4e06
5e5be9c
577f4c3
7e048d1
cd10ba8
c9339f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| import static org.apache.hugegraph.config.ServerOptions.WHITE_IP_STATUS; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.security.Principal; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
|
|
@@ -39,7 +40,6 @@ | |
| import org.apache.hugegraph.util.Log; | ||
| import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException; | ||
| import org.glassfish.grizzly.http.server.Request; | ||
| import org.glassfish.grizzly.utils.Charsets; | ||
| import org.gridkit.jvmtool.cmd.AntPathMatcher; | ||
| import org.slf4j.Logger; | ||
|
|
||
|
|
@@ -184,19 +184,16 @@ protected User authenticate(ContainerRequestContext context) { | |
|
|
||
| if (auth.startsWith(BASIC_AUTH_PREFIX)) { | ||
| auth = auth.substring(BASIC_AUTH_PREFIX.length()); | ||
| // TODO: decode the Basic credential as UTF-8 and split it on the first colon only. | ||
| // Decoding as ASCII and splitting on every colon makes a non-ASCII password answer | ||
| // 401 and a password containing ':' answer 400, although both were accepted at | ||
| // account creation. The Helm chart (helm/hugegraph) refuses such admin passwords in | ||
| // its schema and Server wrapper; drop that guard once this is fixed. | ||
| auth = new String(DatatypeConverter.parseBase64Binary(auth), Charsets.ASCII_CHARSET); | ||
| String[] values = auth.split(":"); | ||
| if (values.length != 2) { | ||
| // RFC 7617 section 2.1 allows only UTF-8 as the declared charset, and it bars a | ||
| // colon from the user-id alone, so split on the first one and keep the rest | ||
| auth = new String(DatatypeConverter.parseBase64Binary(auth), StandardCharsets.UTF_8); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the suggestion. I agree that advertising the expected charset is the signal RFC 7617 section 2.1 defines, and I would like to confirm the intended scope before implementing it. At present the 401 responses do not carry a Basic challenge. The Browsers respond to a Basic challenge by showing their native login dialog, so this would also change what browser-based clients such as Hubble display when credentials are missing or a session has expired. Would you prefer this change in this PR, or in a separate PR together with the client-side encoding work for Jersey and OkHttp? I can implement it in either place, with a response-level regression for both entry points and a note on the remaining client limitations. If it belongs here, please also let me know which realm value you would like to use. |
||
| int colon = auth.indexOf(':'); | ||
| if (colon < 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: the 400 paths in this block and the two behaviour changes listed under Compatibility have no automated test. Every API test authenticates through Jersey's Requested change: next to
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you. c9339f0 adds |
||
| throw new BadRequestException("Invalid syntax for username and password"); | ||
| } | ||
|
|
||
| final String username = values[0]; | ||
| final String password = values[1]; | ||
| final String username = auth.substring(0, colon); | ||
| final String password = auth.substring(colon + 1); | ||
|
|
||
| if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { | ||
| throw new BadRequestException("Invalid syntax for username and password"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.