canvas-lms/config/initializers/inst_access.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

28 lines
964 B
Ruby
Raw Normal View History

InstID tokens, part 1: generation fixes INTEROP-6913, INTEROP-6892, INTEROP-6893, INTEROP-6920 flag = none This commit introduces the InstID token, a signed and encrypted JWT (aka JWE) that will soon be usable for Canvas API access (that's "part 2"). If the InstID class is configured with a private signing key and public encryption key, it will be able to produce encrypted JWTs and validate and deserialize decrypted JWTs. If it is configured with only a public signing key, it cannot produce tokens but it can still validate and deserialize decrypted ones. Therefore this class can be used by the identity provider (currently Canvas) to produce tokens, but also by any services that want to use InstID tokens for authentication. test plan: 1) generate two RSA keypairs. one way to generate a keypair is from a rails console: > keypair = Canvas::Security::RSAKeyPair.new > puts keypair.private_key.to_s > puts keypair.public_key.to_s 2) choose which one is for signing and which is for encryption, then add the private signing key and the public encryption key to your rails credentials: - run `bin/rails credentials:edit` - add an entry like the following, and then save and close your editor: ``` inst_id: encryption_key: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvY1EMlGm1daM87ejGuFX <...snip...> /wIDAQAB -----END PUBLIC KEY----- signing_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAnDwED/QOB0f0H6TOZqLmjaPqA7m8c40NDXkAa6u5cK8zCbk3 <...snip...> QhjPgifBwTrzj21484CfiPfy5oe756Exerj8PIlRrE/hxWRSDwBIOg== -----END RSA PRIVATE KEY----- ``` 3) open a rails console and do: > id = InstID.for_user('user-uuid') > id.to_token # make sure this doesn't blow up > token = id.to_unencrypted_token > decoded_id = InstID.from_token(token) > id.jwt_payload == decoded_id.jwt_payload # => true TODO in followup commits: - make canvas accept InstID tokens for auth Change-Id: Ie550c17507c26f9944bd62a747a6a63161e8e770 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/268872 Reviewed-by: Ethan Vizitei <evizitei@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Michael Ziwisky <mziwisky@instructure.com> Product-Review: Michael Ziwisky <mziwisky@instructure.com>
2021-07-13 11:46:17 +08:00
# frozen_string_literal: true
#
# Copyright (C) 2021 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
require "inst_access"
require_relative "inst_access_support"
InstID tokens, part 1: generation fixes INTEROP-6913, INTEROP-6892, INTEROP-6893, INTEROP-6920 flag = none This commit introduces the InstID token, a signed and encrypted JWT (aka JWE) that will soon be usable for Canvas API access (that's "part 2"). If the InstID class is configured with a private signing key and public encryption key, it will be able to produce encrypted JWTs and validate and deserialize decrypted JWTs. If it is configured with only a public signing key, it cannot produce tokens but it can still validate and deserialize decrypted ones. Therefore this class can be used by the identity provider (currently Canvas) to produce tokens, but also by any services that want to use InstID tokens for authentication. test plan: 1) generate two RSA keypairs. one way to generate a keypair is from a rails console: > keypair = Canvas::Security::RSAKeyPair.new > puts keypair.private_key.to_s > puts keypair.public_key.to_s 2) choose which one is for signing and which is for encryption, then add the private signing key and the public encryption key to your rails credentials: - run `bin/rails credentials:edit` - add an entry like the following, and then save and close your editor: ``` inst_id: encryption_key: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvY1EMlGm1daM87ejGuFX <...snip...> /wIDAQAB -----END PUBLIC KEY----- signing_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAnDwED/QOB0f0H6TOZqLmjaPqA7m8c40NDXkAa6u5cK8zCbk3 <...snip...> QhjPgifBwTrzj21484CfiPfy5oe756Exerj8PIlRrE/hxWRSDwBIOg== -----END RSA PRIVATE KEY----- ``` 3) open a rails console and do: > id = InstID.for_user('user-uuid') > id.to_token # make sure this doesn't blow up > token = id.to_unencrypted_token > decoded_id = InstID.from_token(token) > id.jwt_payload == decoded_id.jwt_payload # => true TODO in followup commits: - make canvas accept InstID tokens for auth Change-Id: Ie550c17507c26f9944bd62a747a6a63161e8e770 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/268872 Reviewed-by: Ethan Vizitei <evizitei@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Michael Ziwisky <mziwisky@instructure.com> Product-Review: Michael Ziwisky <mziwisky@instructure.com>
2021-07-13 11:46:17 +08:00
configure_inst_access = proc do
InstAccessSupport.configure_inst_access!
InstID tokens, part 1: generation fixes INTEROP-6913, INTEROP-6892, INTEROP-6893, INTEROP-6920 flag = none This commit introduces the InstID token, a signed and encrypted JWT (aka JWE) that will soon be usable for Canvas API access (that's "part 2"). If the InstID class is configured with a private signing key and public encryption key, it will be able to produce encrypted JWTs and validate and deserialize decrypted JWTs. If it is configured with only a public signing key, it cannot produce tokens but it can still validate and deserialize decrypted ones. Therefore this class can be used by the identity provider (currently Canvas) to produce tokens, but also by any services that want to use InstID tokens for authentication. test plan: 1) generate two RSA keypairs. one way to generate a keypair is from a rails console: > keypair = Canvas::Security::RSAKeyPair.new > puts keypair.private_key.to_s > puts keypair.public_key.to_s 2) choose which one is for signing and which is for encryption, then add the private signing key and the public encryption key to your rails credentials: - run `bin/rails credentials:edit` - add an entry like the following, and then save and close your editor: ``` inst_id: encryption_key: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvY1EMlGm1daM87ejGuFX <...snip...> /wIDAQAB -----END PUBLIC KEY----- signing_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAnDwED/QOB0f0H6TOZqLmjaPqA7m8c40NDXkAa6u5cK8zCbk3 <...snip...> QhjPgifBwTrzj21484CfiPfy5oe756Exerj8PIlRrE/hxWRSDwBIOg== -----END RSA PRIVATE KEY----- ``` 3) open a rails console and do: > id = InstID.for_user('user-uuid') > id.to_token # make sure this doesn't blow up > token = id.to_unencrypted_token > decoded_id = InstID.from_token(token) > id.jwt_payload == decoded_id.jwt_payload # => true TODO in followup commits: - make canvas accept InstID tokens for auth Change-Id: Ie550c17507c26f9944bd62a747a6a63161e8e770 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/268872 Reviewed-by: Ethan Vizitei <evizitei@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Michael Ziwisky <mziwisky@instructure.com> Product-Review: Michael Ziwisky <mziwisky@instructure.com>
2021-07-13 11:46:17 +08:00
end
Rails.configuration.after_initialize(&configure_inst_access)
Canvas::Reloader.on_reload(&configure_inst_access)