canvas-lms
canvas-lms copied to clipboard
Third-Party Identity Providers Won't Map to Manually Enrolled Users
Summary:
When setting up a third-party authentication provider like GitHub or an OpenID Connect service, accounts can only log in when "Just-in-time provisioning" is enabled, and even then, will create duplicate records if that same email exists in the database already.
Steps to reproduce:
- Manually create a user with email "[email protected]" (or any other email)
- Setup any third-party identity provider under the Authentication settings (I confirmed with Github and OpenID Connect)
- Attempt to login with SSO
Expected behavior:
I would expect that if I manually create a user with the email "[email protected]" that it will map to that account whenever the user authenticates with a third-party identity provider
Actual behavior:
User is redirected to error page that says "Canvas does not have an account for user: [email protected]"
I’m assuming you’re creating the user with a login matching their email address, not just a communication channel. And that you’ve so figured your authentication provider to use the email address as the login attribute, and not sub
or some other id attribute. And finally, that you’re doing so via the web UI, and not the API or SIS Import. When pre-creating logins for a user, they must be specifically attached to the proper authentication provider, which cannot currently be done via the web UI.
Tl;dr: I’ve made a lot of assumptions about what you’re doing, and that you may have missed one of several small details for it to work correctly.
Most of your assumptions were correct, namely what fixes my issue is specifically attaching the proper authentication provider to the user record. Thank you! Is there a community-based resource that describes all of these details? I’d be happy to update documentation to reflect these steps.
The reason is here https://github.com/instructure/canvas-lms/blob/master/app/models/pseudonym.rb#L191
def self.for_auth_configuration(unique_id, aac, include_suspended: false)
auth_id = aac.try(:auth_provider_filter)
scope = include_suspended ? active : active_only
scope.by_unique_id(unique_id).where(authentication_provider_id: auth_id)
.order("authentication_provider_id NULLS LAST").take
end
When account was created manually, authenticate_provider_id
is NULL
, not attach to any authentication provider from Root or Sub-Account. So it's won't map or create new duplicated one.
I try remove the where
out and then it works on that case. But not sure if is there any problems around this...
There is no plan to remove that clause. If you want to pre create users for use with OIDC or GitHub, you need to specify the auth provider when they are created