June 3-5, 2014 | Berlin, Germany
Patrick Streule, Architect, Atlassian
Build a Connect Add-on
with Your Own Stack
• Atlassian Connect Express: node.js/express
• Atlassian Connect Play: Java/Play
• ACE and AC-Play provide:
• Authenticati...
• You have an existing service that will host the add-on
• Development in your company happens on a different
stack
• Conne...
Overview
Product
Overview
WEBHOOKS
REST
API
REST API
HTTP
Add-On
Serve descriptor and add-on UI

☑ Web server / web framework

☑ SSL certificate
Handle add-on installation

☑ Persistent st...
The Minimum Viable
Add-On
• Description of the Add-On
• Where does it show up?
• Where are the add-on
endpoints?
• General Metadata
The Descriptor
{...
The Content
<!DOCTYPE html>!
<html>!
<head>!
<title>Atlas Camp</title>!
<script src=“https://someinstance.jira.com/atlassi...
The Result
• HTTPS in production, HTTP for development only
• Include all.js from the host:
The Important Bits
var hostBaseUrl = getU...
Adding Authentication:
Installation Event
• Authentication type: JWT
• Installed Lifecycle hook is
required.
• Will be called during
installation
• Other hooks:
• U...
Installation event
• clientKey

Identifies the tenant
• sharedSecret

The key for signing
and verifying JWT
tokens
• baseUr...
Adding Authentication:
JWT
• Authenticity
• Parties are who they claim to be
• Integrity
• The request was not tampered with
• Authorization (special...
JWT: Anatomy of a token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO
jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE
wMTQ...
JWT: Anatomy of a token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO
jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE
wMTQ...
JWT: Anatomy of a token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO
jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE
wMTQ...
JWT Verification: Step 1
base64url(sign(‘eyJhbGciOiJIUzI1NiIsInR5cCI6Ik
pXVCJ9.eyJleHAiOjE0MDEwODEwMzgsInN1YiI6ImZmODA
4MT...
JWT Verification: Step 2
a=5,7&lic=none&page.id=19809&user_id=pstreule
{!
"baseUrl": “https://addon.example.com/base”,…!
}...
• Characters in the unreserved character set MUST NOT
be encoded: (ALPHA, DIGIT, "-", ".", "_", "~")
• All other character...
• JWT tokens used on incoming and outgoing requests
• URL Parameter: jwt=eY…
• HTTP header: Authorization: JWT eY…
• Find ...
Adding Authentication:
Add-On to Add-On
• Do not use session cookies
• Cookies set by the iframe are third-party cookies
• Many browsers don’t accept them by defa...
• How to handle authentication for intra-add-on Ajax calls
and links.
Your own requests
• Create a JWT token for the tenant and user
• QSH is optional, depending on the parameter data
Reuse JWT
{!
"exp": 140108...
Dev Speed
Quick descriptor deployment
curl -i -X HEAD -u admin:admin 

http://localhost:2990/jira/rest/plugins/1.0/
HTTP/1.1 200 OK!...
We’re here to help

http://go.atlassian.com/ac-dev
Upcoming SlideShare
Loading in …5
×

AtlasCamp 2014: Building a Connect Add-on With Your Own Stack

1,281 views

Published on

Atlassian provides two easy-to-use frameworks for getting a Connect add-on up and running quickly – atlassian-connect-express and ac-play. But what if these frameworks don't quite fit your bill? What does it mean to build a Connect add-on with your own stack? What components do you need to write? And how does it all fit together? Attending this talk will give you enough background information to implement an add-on in the language and technology stack of your choice.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,281
On SlideShare
0
From Embeds
0
Number of Embeds
132
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

AtlasCamp 2014: Building a Connect Add-on With Your Own Stack

  1. 1. June 3-5, 2014 | Berlin, Germany
  2. 2. Patrick Streule, Architect, Atlassian Build a Connect Add-on with Your Own Stack
  3. 3. • Atlassian Connect Express: node.js/express • Atlassian Connect Play: Java/Play • ACE and AC-Play provide: • Authentication handling (both directions) • Lifecycle handling • Persistence ACE/AC-Play vs Your Own
  4. 4. • You have an existing service that will host the add-on • Development in your company happens on a different stack • Connect does not prescribe a stack at all ACE/AC-Play vs Your Own
  5. 5. Overview
  6. 6. Product Overview WEBHOOKS REST API REST API HTTP Add-On
  7. 7. Serve descriptor and add-on UI
 ☑ Web server / web framework
 ☑ SSL certificate Handle add-on installation
 ☑ Persistent store Handle add-on requests
 ☑ JWT token handler
 ☑ Crypto library
 ☑ JSON and HttpClient libs Checklist
  8. 8. The Minimum Viable Add-On
  9. 9. • Description of the Add-On • Where does it show up? • Where are the add-on endpoints? • General Metadata The Descriptor {! "key": "atlas-camp",! "name": "AtlasCamp",! "baseUrl": “https://addon.example.com”,! "authentication": {! "type": "none"! },! "modules": {! "generalPages": [! {! "url": "/intro.html",! "key": "intro-page",! "name": {! "value": "Atlas Camp"! }! }! ]! }! }
  10. 10. The Content <!DOCTYPE html>! <html>! <head>! <title>Atlas Camp</title>! <script src=“https://someinstance.jira.com/atlassian-connect/all.js”></script>! ! <style>body { text-align: center; padding-top: 50px; }</style>! </head>! <body>! <div class=“ac-content”>! <a href=“https://www.atlassian.com/atlascamp/2014">! ! <img src=“img/atlas-camp.png"/>! </a>! </div>! </body>! </html>
  11. 11. The Result
  12. 12. • HTTPS in production, HTTP for development only • Include all.js from the host: The Important Bits var hostBaseUrl = getUrlParameter("xdm_e");! var contextPath = getUrlParameter("cp");! loadScript(hostBaseUrl + contextPath + "/atlassian-connect/all.js");
  13. 13. Adding Authentication: Installation Event
  14. 14. • Authentication type: JWT • Installed Lifecycle hook is required. • Will be called during installation • Other hooks: • Uninstalled, Enabled, Disabled ! Setting it up {! "key": "atlas-camp",! "name": "AtlasCamp",! "baseUrl": “https://addon.example.com”,! "authentication": {! "type": "jwt"! },! "lifecycle": {! "installed": "/installed",! "uninstalled": "/uninstalled"! }! }
  15. 15. Installation event • clientKey
 Identifies the tenant • sharedSecret
 The key for signing and verifying JWT tokens • baseUrl
 The host and context path of the product
  16. 16. Adding Authentication: JWT
  17. 17. • Authenticity • Parties are who they claim to be • Integrity • The request was not tampered with • Authorization (special case in Connect) • User has access to the pages and issues referenced by URL parameters JWT
  18. 18. JWT: Anatomy of a token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE wMTQwY2Q0NWE5MWQwMDBkIiwiaXNzIjoiQ29uZmx1ZW5jZ TowNzA3MjM3MjM2IiwicXNoIjoiMjU5YzZkNjU1NjEwYzg yNzE3MDMxNWEwMTM1ZGI0OTAwODYxZjkxYzA5NDdlM2I2N jY2NjgyZTkzMDU1NWFiNCIsImlhdCI6MTQwMTA4MDg1OH0 .iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E
  19. 19. JWT: Anatomy of a token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE wMTQwY2Q0NWE5MWQwMDBkIiwiaXNzIjoiQ29uZmx1ZW5jZ TowNzA3MjM3MjM2IiwicXNoIjoiMjU5YzZkNjU1NjEwYzg yNzE3MDMxNWEwMTM1ZGI0OTAwODYxZjkxYzA5NDdlM2I2N jY2NjgyZTkzMDU1NWFiNCIsImlhdCI6MTQwMTA4MDg1OH0 .iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E Header Payload, Claims Signature
  20. 20. JWT: Anatomy of a token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE wMTQwY2Q0NWE5MWQwMDBkIiwiaXNzIjoiQ29uZmx1ZW5jZ TowNzA3MjM3MjM2IiwicXNoIjoiMjU5YzZkNjU1NjEwYzg yNzE3MDMxNWEwMTM1ZGI0OTAwODYxZjkxYzA5NDdlM2I2N jY2NjgyZTkzMDU1NWFiNCIsImlhdCI6MTQwMTA4MDg1OH0 .iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E {"alg":"HS256","typ":"JWT"} {! "exp": 1401081038,! "sub": “ff808…d000d”,! "iss": "Confluence:070789",! "qsh": “259c6…55ab4”,! "iat": 1401080858! } HMAC using SHA-256 Expires at Subject Issuer Query String Hash Issued at BTW: Never rely on this prefix!
  21. 21. JWT Verification: Step 1 base64url(sign(‘eyJhbGciOiJIUzI1NiIsInR5cCI6Ik pXVCJ9.eyJleHAiOjE0MDEwODEwMzgsInN1YiI6ImZmODA 4MTgxNDBjMDcyOWEwMTQwY2Q0NWE5MWQwMDBkIiwiaXNzI joiQ29uZmx1ZW5jZTowNzA3MjM3MjM2IiwicXNoIjoiMjU 5YzZkNjU1NjEwYzgyNzE3MDMxNWEwMTM1ZGI0OTAwODYxZ jkxYzA5NDdlM2I2NjY2NjgyZTkzMDU1NWFiNCIsImlhdCI 6MTQwMTA4MDg1OH0’, 
 header.alg, tenants[claims.iss].sharedSecret))! ! == iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E ?
  22. 22. JWT Verification: Step 2 a=5,7&lic=none&page.id=19809&user_id=pstreule {! "baseUrl": “https://addon.example.com/base”,…! } GET /base/render?page.id=19809&a=7&a=5&user_id=pstreule&lic=none&jwt=eY… "qsh": “259c6…55ab4” hex(sha256(‘GET&…’)) remove context path remove ‘jwt’, order keys and values, apply OAuth1 encoding rulesuppercase /renderGET &&
  23. 23. • Characters in the unreserved character set MUST NOT be encoded: (ALPHA, DIGIT, "-", ".", "_", "~") • All other characters MUST be encoded • The two hexadecimal characters 
 used to represent encoded characters 
 MUST be uppercase. Pitfalls Raw Encoded SPACE %20 * %2A ! %21 ' %27 ( %28 ) %29
  24. 24. • JWT tokens used on incoming and outgoing requests • URL Parameter: jwt=eY… • HTTP header: Authorization: JWT eY… • Find more information • http://go.atlassian.com/ac-docs • http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html JWT Summary
  25. 25. Adding Authentication: Add-On to Add-On
  26. 26. • Do not use session cookies • Cookies set by the iframe are third-party cookies • Many browsers don’t accept them by default Pitfalls
  27. 27. • How to handle authentication for intra-add-on Ajax calls and links. Your own requests
  28. 28. • Create a JWT token for the tenant and user • QSH is optional, depending on the parameter data Reuse JWT {! "exp": 1401081038,! "sub": “ff808…d000d”,! "iss": "Confluence:070789",! "iat": 1401080858! }
  29. 29. Dev Speed
  30. 30. Quick descriptor deployment curl -i -X HEAD -u admin:admin 
 http://localhost:2990/jira/rest/plugins/1.0/ HTTP/1.1 200 OK! upm-token: 7864481825707347853 curl -i -X POST -u admin:admin ! -H "Content-type: application/vnd.atl.plugins.remote.install+json" 
 -d '{"pluginUri":"http://localhost:3000/atlassian-connect.json"}'! http://localhost:2990/jira/rest/plugins/1.0/?token=7864481825707347853
  31. 31. We’re here to help
 http://go.atlassian.com/ac-dev

×