Your SlideShare is downloading. ×
AtlasCamp 2014: Building a Connect Add-on With Your Own Stack
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

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

335
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 …

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
335
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. June 3-5, 2014 | Berlin, Germany
  • 2. Patrick Streule, Architect, Atlassian Build a Connect Add-on with Your Own Stack
  • 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. • 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. Overview
  • 6. Product Overview WEBHOOKS REST API REST API HTTP Add-On
  • 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. The Minimum Viable Add-On
  • 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. 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. The Result
  • 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. Adding Authentication: Installation Event
  • 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. 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. Adding Authentication: JWT
  • 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. JWT: Anatomy of a token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE wMTQwY2Q0NWE5MWQwMDBkIiwiaXNzIjoiQ29uZmx1ZW5jZ TowNzA3MjM3MjM2IiwicXNoIjoiMjU5YzZkNjU1NjEwYzg yNzE3MDMxNWEwMTM1ZGI0OTAwODYxZjkxYzA5NDdlM2I2N jY2NjgyZTkzMDU1NWFiNCIsImlhdCI6MTQwMTA4MDg1OH0 .iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E
  • 19. JWT: Anatomy of a token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiO jE0MDEwODEwMzgsInN1YiI6ImZmODA4MTgxNDBjMDcyOWE wMTQwY2Q0NWE5MWQwMDBkIiwiaXNzIjoiQ29uZmx1ZW5jZ TowNzA3MjM3MjM2IiwicXNoIjoiMjU5YzZkNjU1NjEwYzg yNzE3MDMxNWEwMTM1ZGI0OTAwODYxZjkxYzA5NDdlM2I2N jY2NjgyZTkzMDU1NWFiNCIsImlhdCI6MTQwMTA4MDg1OH0 .iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E Header Payload, Claims Signature
  • 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. JWT Verification: Step 1 base64url(sign(‘eyJhbGciOiJIUzI1NiIsInR5cCI6Ik pXVCJ9.eyJleHAiOjE0MDEwODEwMzgsInN1YiI6ImZmODA 4MTgxNDBjMDcyOWEwMTQwY2Q0NWE5MWQwMDBkIiwiaXNzI joiQ29uZmx1ZW5jZTowNzA3MjM3MjM2IiwicXNoIjoiMjU 5YzZkNjU1NjEwYzgyNzE3MDMxNWEwMTM1ZGI0OTAwODYxZ jkxYzA5NDdlM2I2NjY2NjgyZTkzMDU1NWFiNCIsImlhdCI 6MTQwMTA4MDg1OH0’, 
 header.alg, tenants[claims.iss].sharedSecret))! ! == iSmtl3ukm8EohrCwO94MF7sXeEFtIRQ-aBggghjlE0E ?
  • 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. • 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. • 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. Adding Authentication: Add-On to Add-On
  • 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. • How to handle authentication for intra-add-on Ajax calls and links. Your own requests
  • 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. Dev Speed
  • 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. We’re here to help
 http://go.atlassian.com/ac-dev