提交 eb1698c6 编写于 作者: D Daniel Beck 提交者: Oleg Nenashev

[JENKINS-59859] Make resource root URL tokens work with user names containing : (#4307)

* Make resource root URL tokens work with user names containing :

* Fix null handling
上级 6670fd1b
......@@ -195,7 +195,7 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
private final String authenticationName;
private final String browserUrl;
InternalResourceRequest(@Nonnull String browserUrl, String authenticationName) {
InternalResourceRequest(@Nonnull String browserUrl, @Nonnull String authenticationName) {
this.browserUrl = browserUrl;
this.authenticationName = authenticationName;
}
......@@ -208,7 +208,7 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
LOGGER.fine(() -> "Performing a request as authentication: " + authenticationName + " and restOfUrl: " + requestUrlSuffix + " and restOfPath: " + restOfPath);
Authentication auth = Jenkins.ANONYMOUS;
if (authenticationName != null) {
if (Util.fixEmpty(authenticationName) != null) {
User user = User.getById(authenticationName, false);
if (user != null) {
try {
......@@ -268,14 +268,14 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
private Instant timestamp;
@VisibleForTesting
Token (String path, @Nullable String username, Instant timestamp) {
Token (@Nonnull String path, @Nullable String username, @Nonnull Instant timestamp) {
this.path = path;
this.username = Util.fixNull(username);
this.timestamp = timestamp;
}
private String encode() {
String value = username + ":" + timestamp.toEpochMilli() + ":" + path;
String value = timestamp.toEpochMilli() + ":" + username.length() + ":" + username + ":" + path;
byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
byte[] byteValue = ArrayUtils.addAll(KEY.mac(valueBytes), valueBytes);
return Base64.getUrlEncoder().encodeToString(byteValue);
......@@ -291,10 +291,12 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
throw new IllegalArgumentException("Failed mac check for " + rest);
}
String[] splits = rest.split(":", 3);
String authenticationName = Util.fixEmpty(splits[0]);
String epoch = splits[1];
String browserUrl = splits[2];
String[] splits = rest.split("[:]", 3);
String epoch = splits[0];
int authenticationNameLength = Integer.parseInt(splits[1]);
String authenticationNameAndBrowserUrl = splits[2];
String authenticationName = authenticationNameAndBrowserUrl.substring(0, authenticationNameLength);
String browserUrl = authenticationNameAndBrowserUrl.substring(authenticationNameLength + 1);
return new Token(browserUrl, authenticationName, ofEpochMilli(Long.parseLong(epoch)));
} catch (Exception ex) {
// Choose log level that hides people messing with the URLs
......
......@@ -286,6 +286,25 @@ public class ResourceDomainTest {
Assert.assertFalse(monitor.isActivated());
}
@Test
public void testColonUserName() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
MockAuthorizationStrategy a = new MockAuthorizationStrategy();
a.grant(Jenkins.READ).everywhere().toEveryone();
j.jenkins.setAuthorizationStrategy(a);
JenkinsRule.WebClient webClient = j.createWebClient();
webClient.setRedirectEnabled(true);
webClient.login("foo:bar");
Page page = webClient.goTo("userContent/readme.txt", "text/plain");
String resourceResponseUrl = page.getUrl().toString();
Assert.assertEquals("resource response success", 200, page.getWebResponse().getStatusCode());
Assert.assertNull("no CSP headers", page.getWebResponse().getResponseHeaderValue("Content-Security-Policy"));
Assert.assertTrue("Served from resource domain", resourceResponseUrl.contains(RESOURCE_DOMAIN));
Assert.assertTrue("Served from resource action", resourceResponseUrl.contains("static-files"));
}
@Test
public void testRedirectUrls() throws Exception {
ResourceDomainRootAction rootAction = ResourceDomainRootAction.get();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册