refs FOO-2410
test plan:
- in dynamic_settings.yml, add the following block:
```
store:
canvas:
services-jwt:
# these are all the same JWK but with different kid
# to generate a new key, run the following in a Canvas console:
#
# key = OpenSSL::PKey::RSA.generate(2048)
# key.public_key.to_jwk(kid: Time.now.utc.iso8601).to_json
jwk-past.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-05-18T22:33:20Z_a\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
jwk-present.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-06-18T22:33:20Z_b\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
jwk-future.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-07-18T22:33:20Z_c\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
```
- Ensure /internal/services/jwks loads correctly
- In console, ensure `CanvasSecurity::ServicesJwt.decrypt(Base64.decode64(CanvasSecurity::ServicesJwt.for_user('localhost', User.first)))`
and `CanvasSecurity::ServicesJwt.decrypt(Base64.decode64(CanvasSecurity::ServicesJwt.for_user('localhost', User.first, symmetric: true)))`
both work and produce sensible looking output
Change-Id: I13c6c35cc92ed12d03bf97e89e590614e11c6d47
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275160
QA-Review: August Thornton <august@instructure.com>
Product-Review: August Thornton <august@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
This also makes tool domain matching work with ports
for working with localhost.
fixes INTEROP-6849
flag=none
Test plan
- Set up the LTI 1.3 test tool in the RCE
- Create a deep link for an iFrame
(which seems to require some json in the
iFrame section)
- Use an API key to generate a sessionless
launch with a URL pointing to the deep link
like canvas/api/v1/courses/:id/external_tools/
sessionless_launch?url=deep_link
- The return URL you receive can be placed in a
browser and then in the POST to /login, in the
request data you should be able to see the
target_link_uri that you gave
- If you fiddle with the deep link URL and make
it something that doesn't match the domain
of the tool, it should NOT send that URL
as the target_link_uri
Change-Id: I5487b221d24faeb3267eec84ff038d1c789ad55b
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/271777
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Evan Battaglia <ebattaglia@instructure.com>
Product-Review: Mysti Lilla <mysti@instructure.com>
refs SAS-1540
* adds an audience setting to developer keys, so a key can be set to
target external audiences with its credentials grants
* when a key with an external audience grants credentials, the token is
signed with an asymmetric key instead of the internal symmetric key
* external audiences can retrieve the corresponding public keys from
/login/oauth2/jwks
* credentials issued by developer keys with an account id include the
account's guid in a custom claim
includes a refactor of key storage and rotation in consul, which had
already been done for LTI. but it wasn't really a feature of lti, just
something used by LTI, and we needed the same for key management for
this. moved it to be part of Canvas::Security
Change-Id: Ie5c0fcee6fc21687f31c109389a3bcc1ed349c5d
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/243606
QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
Reviewed-by: Jonathan Featherstone <jfeatherstone@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
Closes PLAT-4428
Test Plan:
- Create an LTI key in the SA account that is
'allowed'. Turn the key on in the root accounts
of shard 1 and shard 2
- Install the tool in shard 1 and shard 2 root
accounts and courses
- Make a change to the tool configuration from
the SA account (for example: remove a placement)
- Run jobs
- Verify all installs of the tool have been
updated
- Verify the same thing for a root account level
developer key. Changes to the root acocunt
tool configuration should only update tools
in that root account
Change-Id: Icdd71c074fd76c49209b5130f83d1a6f7a976bf5
Reviewed-on: https://gerrit.instructure.com/194445
Tested-by: Jenkins
Reviewed-by: Drake Harper <dharper@instructure.com>
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Product-Review: Jesse Poulos <jpoulos@instructure.com>
Validate that a tool config matches the schema for
a tool.
closes PLAT-4258
Test Plan:
- Attempt to create an lti tool with an old config, should
fail with schema errors
- Create an lti tool with a new tool config, should succeed
- Create a tool from the config, should work
- Test that the launches still work for launch basic and
Deeplinking
Change-Id: Iaeea45f14dd10f464ab06f4bd1bb24696e91b38f
Reviewed-on: https://gerrit.instructure.com/184182
Tested-by: Jenkins
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Product-Review: Marc Phillips <mphillips@instructure.com>
Fix the confusing name of oidc_login_uri in the
tool configuration settings.
refs PLAT-4258
Test Plan:
n/a
Change-Id: I7e5bf518c884cf6a324d671bdf67c5ba09110765
Reviewed-on: https://gerrit.instructure.com/184159
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Tested-by: Jenkins
Product-Review: Marc Phillips <mphillips@instructure.com>
LTI 1.3 configurations had confusing names for the
target_link_uri. Make them consistent.
refs PLAT-4258
Test Plan:
n/a
Change-Id: Ia3ac7f896bdf5959cdf30fc6264ef85cd6774a76
Reviewed-on: https://gerrit.instructure.com/184158
Tested-by: Jenkins
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Product-Review: Marc Phillips <mphillips@instructure.com>
Closes PLAT-4141
Test Plan:
1. Create an LTI developer key and set the oidc_login_uri.
The tool should have the following placements:
- user_navigation
- course_navigation
- editor_button
Each placement should have a different 'url' property
(you can just add query params if you want)
2. Launch the tool from each of the placements and verify
the following:
- The OIDC login message is sent to the oidc_login_uri
- the target_link_uri sent in the OIDC login message
is equal to the 'url' property of the placement setting
3. Create ane LTI assignment with the tool and do a launch
4. Verify that:
- The OIDC login message is sent to the oidc_login_uri
- The target_link_uri is the 'url' of the ContextExternalTool
5. Install an LTI 1 tool in the same placements
6. Launch the LTI 1 tool at each placement and verify the launch
works as before
Change-Id: Ib7508daad9a954e7eabcb0374dbd54520280a172
Reviewed-on: https://gerrit.instructure.com/177627
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
Reviewed-by: Marc Phillips <mphillips@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Fixes PLAT-3924
Test Plan:
- Create a new LTI key
- Without refreshing the page verify the following:
* toggling the "on/off" switch works
* the global id of the key is displayed
* the key's secret is available
Change-Id: I1cde9db31ecf8315a7814633d398364acea0a45f
Reviewed-on: https://gerrit.instructure.com/170184
Tested-by: Jenkins
QA-Review: Marc Phillips <mphillips@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Marc Phillips <mphillips@instructure.com>
Closes PLAT-3633, PLAT-3634
Test Plan:
- Do an LTI 1.3 launch in Canvas and verify the id token is
signed with the current canvas secret key.
- Verify the following claims are included and correct:
* exp
* iat
* iss
* nonce
* sub
Change-Id: I57699ac42bbe98a9fa03f82f3f9b9a16c6923011
Reviewed-on: https://gerrit.instructure.com/159855
Tested-by: Jenkins
Reviewed-by: Marc Alan Phillips <mphillips@instructure.com>
QA-Review: Marc Alan Phillips <mphillips@instructure.com>
Product-Review: Marc Alan Phillips <mphillips@instructure.com>