Hi team,
I’m having some problems when creating the token for JIRA attachments when the attachment URL has encoded characters.
For example, the issue’s attachment has encoded characters:
The suggested way to create a JWT token in the documentation doesn’t work. The URL returns 401 Forbidden,
@Test
public void createUriWithJwt()
throws UnsupportedEncodingException, NoSuchAlgorithmException {
long issuedAt = System.currentTimeMillis() / 1000L;
long expiresAt = issuedAt + 180L;
String key = "<hidden>"; //the key from the add-on descriptor
String sharedSecret = "<hidden>";
//during the add-on installation handshake
String method = "GET";
String baseUrl = "https://<hidden>.atlassian.net";
String contextPath = "/";
String apiPath = "/secure/attachment/12600/Some+Image+%28dev%29+-+JIRA+-+Google+Chrome_121+%288%29.png";
JwtJsonBuilder jwtBuilder = new JsonSmartJwtJsonBuilder()
.issuedAt(issuedAt)
.expirationTime(expiresAt)
.issuer(key);
CanonicalHttpUriRequest canonical = new CanonicalHttpUriRequest(method,
apiPath, contextPath, new HashMap());
JwtClaimsBuilder.appendHttpRequestClaims(jwtBuilder, canonical);
JwtWriterFactory jwtWriterFactory = new NimbusJwtWriterFactory();
String jwtbuilt = jwtBuilder.build();
String jwtToken = jwtWriterFactory.macSigningWriter(SigningAlgorithm.HS256,
sharedSecret).jsonToJwt(jwtbuilt);
String apiUrl = baseUrl + apiPath + "?jwt=" + jwtToken;
System.out.print(apiUrl);
}
If I change the the path to
String apiPath ="/rest/api/latest/serverInfo";
or
String apiPath = "/secure/attachment/12600/fakeName.png";
The generated URL works and I can get the server info and download the attachment.
What would be the CanonicalHttpUriRequest’s expected encoding for the apiPath parameter?
UPDATE:
I have also tried atlassian connect spring boot library with the same result, encoded filenames are unnauthorized. This is my test:
import com.atlassian.connect.spring.AtlassianHost;
import com.atlassian.connect.spring.AtlassianHostRepository;
import com.atlassian.connect.spring.internal.AtlassianConnectProperties;
import com.atlassian.connect.spring.internal.descriptor.AddonDescriptor;
import com.atlassian.connect.spring.internal.descriptor.AddonDescriptorLoader;
import com.atlassian.connect.spring.internal.request.AtlassianHostUriResolver;
import com.atlassian.connect.spring.internal.request.jwt.JwtGenerator;
import com.atlassian.connect.spring.internal.request.jwt.JwtQueryHashGenerator;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.http.HttpMethod;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;
public class JWTTest {
@Test
public void downloadFileURL() throws URISyntaxException {
AtlassianHostRepository repository = Mockito.mock(AtlassianHostRepository.class);
AtlassianHost host = new AtlassianHost();
host.setBaseUrl("https://<hidden>.atlassian.net");
String addonKey = "<hidden>";
host.setSharedSecret("<hidden>");
Mockito.when(repository.findFirstByBaseUrl(Mockito.anyString())).thenReturn(Optional.of(host));
AtlassianHostUriResolver atlassianHostUriResolver = new AtlassianHostUriResolver(repository);
AddonDescriptorLoader loader = Mockito.mock(AddonDescriptorLoader.class);
AddonDescriptor addonDescriptor = Mockito.mock(AddonDescriptor.class);
Mockito.when(addonDescriptor.getKey()).thenReturn(addonKey);
Mockito.when(loader.getDescriptor()).thenReturn(addonDescriptor);
JwtGenerator jwtGenerator = new JwtGenerator(atlassianHostUriResolver, loader, new AtlassianConnectProperties(), new JwtQueryHashGenerator());
String apiPath = "/secure/attachment/12600/Some+Image+%28dev%29+-+JIRA+-+Google+Chrome_121+%288%29.png";
String url = host.getBaseUrl() + apiPath;
String jwt = jwtGenerator.createJwtToken(HttpMethod.GET, new URI(url), host);
System.out.println(url + "?jwt=" + jwt);
}
}
If I change the name to something without encoded characters (like /fakenme.png) I can download the file. I don’t want to patch URLs in my production code.
Any help will be highly appreciated!
Cheers
Fernando