Spring Boot and Salesforce Canvas
The challenge
Salesforce canvas offers a capable integration point between Salesforce and external applications to surface them inside the Salesforce UI. One of the aspects is establishing identity. There are two options: OAuth and a signed request. I’m looking at the later. A signed request posts (as in HTTP POST) a digitally signed JSON request to the external application.
When all you need is a single page, validating the request and returning the result is all that needs to be done. It becomes trickier when you want to navigate in the application and when that application runs in the cloud with multiple load balanced instances, so you might end up on a different instance mid-flight.
Most of the sample code available uses the sophisticated Canvas JavaScript SDK, so I decided to focus on backend code here.
The project
All the code can be found on Github including sources. Feel free to open issues. To try it out you can deploy it to Heroku (button in the Readme on Github) and configure a Canvas app in Salesforce. Use https://yourappname.herokuapp.com/sfdcauth/hw
as Canvas URL
The approach
Build a Spring Boot application that provides an authentication endpoint suitable for a Canvas POST and other endpoints that only allow authenticated access. The security will be provided by Json Web Tokens a.k.a JWT or RFC 7519.
As added challenge: The application will require standard link and form based navigation, so we can't rely on AJAX to provide additional "stuff" into the requests from/to the server. And yes - needs to be able to run on Heroku on multiple instances (Dynos in Heroku language) without the sticky session feature switched on.
Lessons learned
- Spring Boot performs magic. Sometimes a little too much magic
- Base64 isn't Base64. The Java8 decoder works different from the Apache Commons, so the signed checksums don't tally. Pain in the "proverbial" to get the validation code from the SDK running
- Spring security is well thought through. I like the approach: the very moment you add it to a project, all is closed until you specifically open it
- You can't stuff the entire JSON coming from Salesforce back into a cookie
- JSON in Java is still a pain (Bearable with JsonNode)
- The information around custom error pages in Spring is confusing. It seems to have evolved over time and conflicting information is presented
- Json Web Tokens (JWT) rock
- Cookies behave different in Salesforce canvas than in regular iFrames. In an iFrame http cookies are considered "native" to their environment, in canvas they seem to run as third-party cookies (unless I miss something). Stole a few hours tracking the issue down
- Avonni Creator is a nice tool to play with Lightning Design System layouts
As usual YMMV
Posted by Stephan H Wissel on 20 February 2018 | Comments (1) | categories: Heroku Identity Management Java JWT Salesforce