Hi,
we changed our plugin to use the atlassian-connect-spring-boot dependency in version 2.0.1 and expected it to handle the GDPR related changes to authentication transparently.
Our connect plugin app is calling Jira in the ACT_AS_USER scope to retrieve info about an issue. The connect.json specifies the authentication/type as jwt.
I see in the logs the call:
2020-10-13 21:58:08,382 http-nio-8443-exec-10 DEBUG c.x.jira.xstudio.helper.JiraHelper getJiraValue [XQUAL JH ] GET from URL=https://xqual-dev-local.atlassian.net/rest/api/2/issue/PROJ-1?fields=id,summary,priority,issuetype,status,description
2020-10-13 21:58:08,383 http-nio-8443-exec-10 DEBUG c.a.c.s.i.r.o.JwtBearerAccessTokenProvider obtainAccessToken Requesting OAuth 2.0 access token using urn:ietf:params:oauth:grant-type:jwt-bearer
2020-10-13 21:58:08,384 http-nio-8443-exec-10 DEBUG c.a.c.s.i.r.o.OAuth2JwtAssertionGenerator getAssertionString Created OAuth 2.0 JWT assertion: {"sub":"urn:atlassian:connect:userkey:557058:9b03f379-659a-4302-8713-f1843af7397c","aud":"https:\/\/auth.atlassian.io","iss":"urn:atlassian:connect:clientid:eyJob3N0S2V5IjoiN2I5NDUyOGUtMWE1Yy0zYzlkLWI5MTAtOGUwMWE1MWU3
and a little later that:
2020-10-13 21:58:09,186 http-nio-8443-exec-10 DEBUG org.apache.http.wire wire http-outgoing-1 << "{"error":"invalid_grant","error_description":"Subject claim prefix urn:atlassian:connect:userkey: is no longer allowed"}"
2020-10-13 21:58:09,186 http-nio-8443-exec-10 DEBUG org.apache.http.headers onResponseReceived http-outgoing-1 << HTTP/1.1 400 Bad Request
It seems like the atlassian-connect-spring-boot framework adds the userkey property and later on complains about it.
Can anybody please enlighten me what goes wrong here?
Thanks
1 Like
@matthias1, that sounds strange.
Which of the two AtlassianHostRestClients
methods are you calling to obtain a OAuth2RestTemplate
?
If authenticatedAsHostActor()
, how is the security context being set: are you making the Jira API request as part of handling an incoming authenticated request?
Hi @epehrson, thanks for having a look.
I’m using the authenticatedAsHostActor() method in an issue-tab controller to show the logged-in user the content from our application which runs on a different server. For this I need first to request the issue details from Jira to be able to request the other details later on.
The code looks like this:
@RequestMapping(value = "/issuetab", method = RequestMethod.GET)
public String getIssueTabContent(@AuthenticationPrincipal AtlassianHostUser hostUser,
Model model,
String issuekey) {
String hostBaseUrl = hostUser.getHost().getBaseUrl();
...
config = JiraHelper.getProperty(getRestTemplate(), hostBaseUrl, JiraHelper.PROPERTYNAME_ADDONCONFIG, AddonConfig.class);
if (null == config) {
LOG.warn(LOG_PREFIX + "Plugin config could not be read.");
}
LOG.debug(LOG_PREFIX + "Test property value is: {}", config.toString());
String fields = "id,summary,priority,issuetype,status,description";
issue = JiraHelper.getIssue(atlassianHostRestClients.authenticatedAsHostActor(), hostBaseUrl, issuekey, fields);
The getProperty() call (using atlassianHostRestClients.authenticatedAsAddon()) succeeds while the
getIssue() call (using the user-auth) fails.
Hm. If you enable debug logging for com.atlassian.connect.spring
, you should see a Parsed JWT
log line from JwtAuthenticationProvider
. atlassian-connect-spring-boot should only fall back to using the user key if the account ID is not present.
Hi, here’s the log of the ‘Parsed JWT’ part - had to leave the rest of it out, b/o length restrictions. Let me know if you need to see more or where to send the whole request-log to.
2020-10-14 19:32:19,138 http-nio-8443-exec-6 DEBUG o.s.security.web.FilterChainProxy doFilterInternal /issuetab?issuekey=PROJ-1&xdm_e=https%3A%2F%2Fxqual-dev-local.atlassian.net&xdm_c=channel-com.xqual.jira.jira-xstudio-connect-plugin__xstudio-integration-issue-tab&cp=&xdm_deprecated_addon_key_do_not_use=com.xqual.jira.jira-xstudio-connect-plugin&lic=none&cv=1001.0.0-SNAPSHOT&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTcwNTg6OWIwM2YzNzktNjU5YS00MzAyLTg3MTMtZjE4NDNhZjczOTdjIiwicXNoIjoiYWZlMDk4NzVjOWU0YmI2MzU2OGEzY2M1MDAzNDc0ZjhkNTM5Y2JkZjYzM2I4Y2IxNTcyMmFiM2FhODA5NTEwNSIsImlzcyI6IjdiOTQ1MjhlLTFhNWMtM2M5ZC1iOTEwLThlMDFhNTFlNzljNyIsImNvbnRleHQiOnt9LCJleHAiOjE2MDI3MDQ4MzUsImlhdCI6MTYwMjcwMzkzNX0.V8nGSNkzxRjpsMlhbZGC2nwErFfRJiMeVOvhD_IsuN0 has no matching filters
2020-10-14 19:32:19,139 http-nio-8443-exec-6 DEBUG c.a.c.s.i.a.j.JwtAuthenticationFilter createJwtAuthenticationToken Retrieved JWT from request
2020-10-14 19:32:19,139 http-nio-8443-exec-6 DEBUG o.s.s.authentication.ProviderManager authenticate Authentication attempt using com.atlassian.connect.spring.internal.auth.jwt.JwtAuthenticationProvider
2020-10-14 19:32:19,139 http-nio-8443-exec-6 DEBUG c.a.c.s.i.a.j.JwtAuthenticationProvider authenticate Parsed JWT: JWTClaimsSet [iss=7b94528e-1a5c-3c9d-b910-8e01a51e79c7, sub=557058:9b03f379-659a-4302-8713-f1843af7397c, aud=null, exp=Wed Oct 14 19:47:15 UTC 2020, nbf=null, iat=Wed Oct 14 19:32:15 UTC 2020, jti=null, typ=null, customClaims={qsh=afe09875c9e4bb63568a3cc5003474f8d539cbdf633b8cb15722ab3aa8095105, context={}}]
So, the context
claim of the JWT is empty, and you are using atlassian-connect-spring-boot:2.0.1, which will then interpret the JWT sub
as an account ID. The user key of the security context is never set.
I don’t really have any ideas at this point. Can you set this up locally and debug through it to see where the user key is set on the AtlassianHostUser
?
Should the user key be set by atlassian-connect-spring-boot or by Spring? I just saw that we’re using an older version of spring-boot (1.4.7.RELEASE) because we need the Velocity support which was removed in newer versions.
@matthias1 but if you’re using Spring Boot 1, you are surely using atlassian-connect-spring-boot 1. And I have to strongly encourage you to upgrade to Spring Boot 2 and the latest atlassian-connect-spring-boot. Per the CHANGELOG, we have fixed a number of security issues, as well as migrated away from several deprecated APIs, for which the deprecation period has already expired.
1 Like
@epehrson, yes, I already feared that we’d have to do a major upgrade of our plugin. Now switched to Spring Boot 2 and it seems to authenticate Ok now:
2020-10-25 10:27:26,098 http-nio-8080-exec-1 DEBUG c.a.c.s.i.a.j.JwtAuthenticationProvider authenticate Parsed JWT: {"sub":"557058:64c7f919-ee3b-4cf3-8d69-00d92030b2ea","qsh":"75367934b7844d9b02f94359c182095a99c75918894a1856c36d620b812405c6","iss":"a15c2049-7630-3590-9d20-0e1781aa4590","context":{},"exp":1603618920,"iat":1603618020}
2020-10-25 10:27:26,266 http-nio-8080-exec-1 DEBUG c.a.c.s.i.a.j.JwtAuthenticationProvider computeQueryStringHash Canonical request for incoming JWT: [CanonicalHttpServletRequest@756a08c0 method = 'GET', relativePath = '/issuetab', parameterMap = '[issuekey -> (TEST-1),xdm_e -> (https://kuespert-dev-1.atlassian.net),xdm_c -> (channel-com.xqual.jira.jira-xstudio-connect-plugin__xstudio-integration-issue-tab),cp -> (),xdm_deprecated_addon_key_do_not_use -> (com.xqual.jira.jira-xstudio-connect-plugin),lic -> (none),cv -> (1001.0.0-SNAPSHOT),jwt -> (eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTcwNTg6NjRjN2Y5MTktZWUzYi00Y2YzLThkNjktMDBkOTIwMzBiMmVhIiwicXNoIjoiNzUzNjc5MzRiNzg0NGQ5YjAyZjk0MzU5YzE4MjA5NWE5OWM3NTkxODg5NGExODU2YzM2ZDYyMGI4MTI0MDVjNiIsImlzcyI6ImExNWMyMDQ5LTc2MzAtMzU5MC05ZDIwLTBlMTc4MWFhNDU5MCIsImNvbnRleHQiOnt9LCJleHAiOjE2MDM2MTg5MjAsImlhdCI6MTYwMzYxODAyMH0.FUPE9Zuw6UyJlNogUWz8JHncu7mbLOxOX1gsaGYbBLM),]']
2020-10-25 10:27:26,358 http-nio-8080-exec-1 DEBUG c.a.c.s.i.a.j.JwtAuthenticationProvider verifyToken Verified JWT for host https://kuespert-dev-1.atlassian.net (a15c2049-7630-3590-9d20-0e1781aa4590)
Thanks a lot for your support!
1 Like