Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvenkatr/7f98126d97bec0d70d219c8ba9f5c19a to your computer and use it in GitHub Desktop.
Save bvenkatr/7f98126d97bec0d70d219c8ba9f5c19a to your computer and use it in GitHub Desktop.
Open edX - SSO Doc - Draft

Third Party Authentication Features in Open edX: Technical Knowledge Transfer

Part 1: Background / Notes

  • Open edX has full, integrated support for three different types of third party auth provider:

    1. OAuth based providers (OAuth2 and the older OAuth v1). Google, Facebook, LinkedIn, and Azure Active Directory are available by default. Any other OAuth backends supported by python-social-auth v0.2.12 can be enabled by changing a configuration setting. Contributed by Google (John Cox).
    2. SAML / Shibboleth. SAML is an SSO standard mostly used by universities and corporations. Shibboleth is the name of a particular implementation of SAML, commonly used by higher ed. institutions.
    3. LTI. Users can use Learning Tools Interoperability® (LTI®) to authenticate. Support for this was contributed by UBC.
  • The Open edX platform also includes limited support for the following SSO providers.

    1. OpenID
    2. Apache-hosted Shibboleth (used by Stanford)
    3. SSL client certificates (currently hard-coded to work for MIT-only)
    4. CAS (Central Authentication Service).

    ^ These providers are part of the external_auth app, tend to be older and less robustly tested (each one was more or less put together for the use of one specific institution), and have a much more limited feature set. I would not recommend their use, and they don't necessarily need to be documented, beyond this sort of brief mention.

  • "SSO" and "Third Party Auth" are largely interchangeable terms for the purposes of this doc.

    • Sometimes in the world of edX, people use "SSO" to refer to SAML/Shibboleth sign in, and "third party auth" to refer to Google/Facebook integration.
  • The rest of this technical write-up will focus only on the OAuth2, SAML, and LTI providers.

Part 2: Common behavior

These topics cover behavior that applies to all three types of provider (OAuth, SAML, and LTI).

New User Registration

  • When a user logs in with SSO for the first time, their account is not [normally] created automatically. Instead, the user information sent by the provider is used to pre-fill the registration form. The user can then edit any of the information before finalizing the creation of their account. The user could also cancel the registration process at this point, and no account would be created for them.
  • The user information that is passed from the external authentication provider (e.g. Google) to Open edX varies depending on the provider (Google vs Facebook vs MIT SAML vs UBC SAML). Some providers may pass the user's full name, first name, last name, username, email address, external user ID, and more. Other providers (e.g. UBC) may pass only an opaque "user token" that can be used to permanently and consistently identify that user, but which is not considered personal information and does not correspond with any other public identifier.
  • Once the user does submit the registration form, their user account is created and is automatically "linked" to the external provider. (See "Linking Accounts" below.)
  • When creating an account with SSO, the password field on the registration form is hidden. User accounts created via SSO will have a random, highly secure password set. The user will not know (or need to know) this password. However, the user can always use the "reset password" feature to change their password, if they would also like to be able to use a traditional password-based login.
  • Important: No matter which type of login is used, a full and independent Open edX account is always created for the new user, with a copy of the user's information. As a result, if the user's information (name, email, etc.) is updated by the external provider, that information will not be automatically updated in the user's Open edX account. In other words, the use of the external account as a reference that provides user details is a one-time event, not an ongoing connection.

Linking Accounts

  • To be able to login with an external provider (e.g. Google), the user's Open edX account must be "linked" to that provider. e.g. if a user's account is linked to Google, then the uesr can click the "Login with Google" button, and will be automatically sign in to their Open edX account.
  • User accounts can be linked to zero, one, or many external providers.
  • Any provider can be linked or unlinked from an account at any time.
  • If an external provider is used to register a new account, then the newly created account will automatically be linked to that provider.
  • If a user tries to login with an external provider that is not yet linked to any Open edX account, the user will be given the option to either: A. Login to an existing account (using a password), which will then link the new provider to that existing account; or B. Create a new account

Part 3: OAuth2 Provider Setup

Login with Google

Here are the instructions for configuring Google as a third party authentication provider, so that users can use their Google account (which includes Google Apps accounts) to login. These are based on [the official Google

  1. First, you need to get credentials to access the Google API. Follow the official instructions to go to the Google Developers Console, create a new project, and Enable the Google+ API service.

  2. Still in the Google Developers Console, select API Manager > OAuth Consent Screen, and enter the name of your Open edX instance as the "Product name shown to users" (e.g. "Example Academy Online"). Then Save.

  3. Select the "Credentials" tab, and click "Create credentials" > "OAuth client ID".

    • For "Application type", select "Web application".
    • "Authorized JavaScript origins" should be left blank.
    • For "Authorized redirect URIs", enter (Open edX instance domain)/auth/complete/google-oauth2/. e.g. for a devstack, enter http://localhost:8000/auth/complete/google-oauth2/
    • Then press Create to finish creating the credentials.
  4. Note the Client ID and Client secret.

  5. In lms.env.json:

    • Ensure that FEATURES > ENABLE_THIRD_PARTY_AUTH is true (it is false by default)
    • If you have customized the THIRD_PARTY_AUTH_BACKENDS list, you must add "social.backends.google.GoogleOAuth2" to that list. If that setting does not appear in lms.env.json (it won't by default), no change is necessary since the Google Backend is enabled by default.
  6. Add the client secret to lms.auth.json. Create a new key called SOCIAL_AUTH_OAUTH_SECRETS if it doesn't already exist, and then add "google-oauth2" to that key as follows:

    "SOCIAL_AUTH_OAUTH_SECRETS": {
        "google-oauth2": "abcdef123456789101112131"
    }

    (If configuring via ansible, the variable to set is called EDXAPP_SOCIAL_AUTH_OAUTH_SECRETS.)

  7. Restart the LMS server so that it will use the new settings.

  8. Go to /admin/third_party_auth/oauth2providerconfig/ (e.g. http://localhost:8000/admin/third_party_auth/oauth2providerconfig/ on devstack)

  9. Click "Add Provider Configuration (OAuth)"

    • Ensure "Enabled" is checked
    • For "Icon Class", enter fa-google-plus
    • For "Name", enter "Google"
    • For "Backend Name", select "google-oauth2". (If it does not appear in the list, then either the ENABLE_THIRD_PARTY_AUTH setting or the THIRD_PARTY_AUTH_BACKENDS setting is not configured correctly.)
    • For "Client ID", enter the client ID from the Google console.
    • Leave "Client Secret" blank (we set the secret via lms.auth.json instead, which is more secure).
    • Press Save

Google+ login is now available for users.

Troubleshooting:

  • If you see the error 'unicode' object has no attribute 'get', the SOCIAL_AUTH_OAUTH_SECRETS setting is not correct. Check that it does not appear multiple times in lms.auth.json.

Login with Facebook

  1. Create the app in the Facebook Developer Console:

    • Login to Facebook, then go to https://developers.facebook.com/apps/?action=create
    • Click "Add a New App" > "Website"
    • Enter a name for the app and click "Create New Facebook App ID"
    • Complete the rest of the fields in the app creation process.
    • When you get to the "Quick Start for Website", click "Skip Quick Start"
    • You should now be at the developer console page for the new Facebook app.
    • Click "Settings" and note the App ID and App Secret.
    • Still on the "Settings" page, click "Add Platform" > "Website". For the "Site URL", put the URL of your Open edX instance (e.g. http://localhost:8000/ for devstack). Also add the domain name from this URL (e.g. localhost) to the "App Domains" field near the top of the Settings page. Then click "Save Changes".
  2. In lms.env.json:

    • Ensure that FEATURES > ENABLE_THIRD_PARTY_AUTH is true (it is false by default)
    • If you have customized the THIRD_PARTY_AUTH_BACKENDS list, you must add "social.backends.facebook.FacebookOAuth2" to that list. If that setting does not appear in lms.env.json (it won't by default), no change is necessary since the Facebook Backend is enabled by default.
  3. Add the App Secret to lms.auth.json. Create a new key called SOCIAL_AUTH_OAUTH_SECRETS if it doesn't already exist, and then add "facebook" to that key as follows:

    "SOCIAL_AUTH_OAUTH_SECRETS": {
        "facebook": "98765432181bbe3a2596efa8ba7abcde"
    }

    (If configuring via ansible, the variable to set is called EDXAPP_SOCIAL_AUTH_OAUTH_SECRETS.)

  4. Restart the LMS server so that it will use the new settings.

  5. Go to /admin/third_party_auth/oauth2providerconfig/ (e.g. http://localhost:8000/admin/third_party_auth/oauth2providerconfig/ on devstack)

  6. Click "Add Provider Configuration (OAuth)"

    • Ensure "Enabled" is checked

    • For "Icon Class", enter fa-facebook

    • For "Name", enter "Facebook"

    • For "Backend Name", select "facebook". (If it does not appear in the list, then either the ENABLE_THIRD_PARTY_AUTH setting or the THIRD_PARTY_AUTH_BACKENDS setting is not configured correctly.)

    • For "Client ID", enter the client ID from the Facebook console (e.g. 1222222244412345).

    • Leave "Client Secret" blank (we set the secret via lms.auth.json instead, which is more secure).

    • Optional: If you want Facebook to provide the user's email address during registration, then enter the following into "Other settings":

      {
          "SCOPE": ["email"], 
          "PROFILE_EXTRA_PARAMS": {
              "fields": "id, name, email"
          }
      }
    • Press Save

Facebook login is now available for users.

Login with LinkedIn

  1. Create an app in the LinkedIn Developer portal:

    • Go to https://www.linkedin.com/secure/developer
    • Click "Create Application" and fill out the fields as appropriate. Submit the form.
    • On the new page with information about the App, note the Client ID and Client Secret.
    • In the "OAuth 2.0" section, add a new Authorized Redirect URL: (Open edX instance domain)/auth/complete/linkedin-oauth2/ (e.g. http://localhost:8000/auth/complete/linkedin-oauth2/ for devstack), and press "Update" to save.
  2. In lms.env.json:

    • Ensure that FEATURES > ENABLE_THIRD_PARTY_AUTH is true (it is false by default)
    • If you have customized the THIRD_PARTY_AUTH_BACKENDS list, you must add "social.backends.linkedin.LinkedinOAuth2" to that list. If that setting does not appear in lms.env.json (it won't by default), no change is necessary since the LinkedIn Backend is enabled by default.
  3. Add the client secret to lms.auth.json. Create a new key called SOCIAL_AUTH_OAUTH_SECRETS if it doesn't already exist, and then add "linkedin-oauth2" to that key as follows:

    "SOCIAL_AUTH_OAUTH_SECRETS": {
        "linkedin-oauth2": "4D3Cb2aB1C0dEFGH"
    }

    (If configuring via ansible, the variable to set is called EDXAPP_SOCIAL_AUTH_OAUTH_SECRETS.)

  4. Restart the LMS server so that it will use the new settings.

  5. Go to /admin/third_party_auth/oauth2providerconfig/ (e.g. http://localhost:8000/admin/third_party_auth/oauth2providerconfig/ on devstack)

  6. Click "Add Provider Configuration (OAuth)"

    • Ensure "Enabled" is checked

    • For "Icon Class", enter fa-linkedin

    • For "Name", enter "LinkedIn"

    • For "Backend Name", select "linkedin-oauth2". (If it does not appear in the list, then either the ENABLE_THIRD_PARTY_AUTH setting or the THIRD_PARTY_AUTH_BACKENDS setting is not configured correctly.)

    • For "Client ID", enter the client ID noted earlier.

    • Leave "Client Secret" blank (we set the secret via lms.auth.json instead, which is more secure).

    • Optional: If you want LinkedIn to provide the user's email address during registration, then enter the following into "Other settings":

      {
          "SCOPE": ["r_basicprofile", "r_emailaddress"], 
          "FIELD_SELECTORS": ["email-address"]
      }
    • Press Save

LinkedIn login is now available for users.

Login with Azure AD

You can use Azure Active Directory to allow users with Office 365 Business accounts to login to Open edX. Note that this feature currently does not work with other types of Microsoft account (such as @live.com or @hotmail.com accounts).

  1. Have a Microsoft account or create one at https://account.live.com/

  2. You will need an Azure subscription. If you do not have one, you can create one by visiting https://azure.microsoft.com/en-us/pricing/free-trial/ . You must enter a credit card, but if you do not create any VMs or other services besides Azure AD, you will not be charged.

  3. Go to https://portal.azure.com/

  4. Click "New", search for Active Directory, find it and hit "Create"

  5. Enter a name, domain name, and country.

  6. Find the new Active Directory in the portal, then click Applications > Add (bottom of screen) > "Add an application my organization is developing"

  7. You should now see your Azure AD application in the portal.

  8. Click "Configure" and find the client ID, e.g. fe3c3868-0faa-44ee-a1bf-1110aeab1a65. Make a note of it.

  9. In the "Keys" section, select a 2 year duration and then hit save to create a secret key. Note the value. (e.g. abcdef12341yHlmOrR8D3vlV1cD2VtL7k9xk9DSB8vw=)

  10. Locate the "permissions to other applications" section

    • In the Delegated Permissions dropdown for Windows Azure Active Directory select only: "Sign in and read user profile"
  11. Verify the Azure AD Domain Name:

    • Find the new Active Directory in the portal; choose "Domains", add, and add the root domain you wish to use, e.g. "edx.org" (add the root domain first, and then follow the TXT record verification process). Once it has been verified you can add subdomains as well (e.g. "courses.edx.org"). Subdomains will also request verification but do not to need it.
  12. Go to the Active Directory > "applications" > choose the application created earlier, and enable "multi-tenant" support.

  13. In lms.env.json:

    • Ensure that FEATURES > ENABLE_THIRD_PARTY_AUTH is true (it is false by default)
    • If you have customized the THIRD_PARTY_AUTH_BACKENDS list, you must add "social.backends.azuread.AzureADOAuth2" to that list. If that setting does not appear in lms.env.json (it won't by default), no change is necessary since the Azure AD Backend is enabled by default.
  14. Add the secret key to lms.auth.json. Create a new key called SOCIAL_AUTH_OAUTH_SECRETS if it doesn't already exist, and then add "azuread-oauth2" to that key as follows:

    "SOCIAL_AUTH_OAUTH_SECRETS": {
        "azuread-oauth2": "abcdef12341yHlmOrR8D3vlV1cD2VtL7k9xk9DSB8vw="
    }

    (If configuring via ansible, the variable to set is called EDXAPP_SOCIAL_AUTH_OAUTH_SECRETS.)

  15. Restart the LMS server so that it will use the new settings.

  16. Go to /admin/third_party_auth/oauth2providerconfig/ (e.g. http://localhost:8000/admin/third_party_auth/oauth2providerconfig/ on devstack)

  17. Add a new provider, backend "azuread-oauth2", name "Microsoft", enabled True, client ID (from earlier application setup e.g. "fe3c3868-0faa-44ee-a1bf-1110aeab1a65"), client secret blank, icon class blank, icon image should be microsoft-white.svg ( <- Note that link is not publicly accessible, so the image will have to be hosted elsewhere )

Now users with any Microsoft Office 365 Business account can log in.

Other OAuth2 Providers (Advanced)

Any other third party authentication provider that supports the OAuth 2 standard can be added to the Open edX platform. Here's how:

  1. In lms.env.json, ensure that FEATURES > ENABLE_THIRD_PARTY_AUTH is true (it is false by default)

  2. You must install the python-social-auth authentication backend specific to that provider, and know the python module path of the backend:

    • If the provider is one of the [python-social-auth supported backends(http://python-social-auth.readthedocs.io/en/latest/backends/index.html#social-backends), it will already be installed and just needs to be enabled. Determine the full python module path to the backend; it is of the format social.backends.(file name).(class name), where file name and class name can be determined by finding the backend in this list of backends. e.g. for GitHub, the file is github.py and the class within that file is GithubOAuth2 so the backend module path would be social.backends.github.GithubOAuth2.
    • If the provider is not supported by python-social-auth, you will have to create a new python package that includes the code required to implement the backend. Your python package must contain a module with a class that subclasses social.backends.oauth.BaseOAuth2. Refer to the python-social-auth documentation for details on this, and refer to the code of the fully supported backends (such as Google or Facebook) for examples.
  3. You must enable the python-social-auth authentication backend specific to that provider: Add/edit the THIRD_PARTY_AUTH_BACKENDS setting in lms.env.json, and add the full path of the module to that list. It is recommended (but not required) that you set the value of THIRD_PARTY_AUTH_BACKENDS to match the default and then add any additional backends you need.

  4. Obtain a Client ID and Client secret from the provider.

  5. Add the client secret to lms.auth.json. Create a new key called SOCIAL_AUTH_OAUTH_SECRETS if it doesn't already exist, and then add the backend name to that key as follows:

    "SOCIAL_AUTH_OAUTH_SECRETS": {
        "backend-name": "secret"
    }

    (If configuring via ansible, the variable to set is called EDXAPP_SOCIAL_AUTH_OAUTH_SECRETS.)

  6. Restart the LMS server so that it will use the new settings.

  7. Go to /admin/third_party_auth/oauth2providerconfig/ (e.g. http://localhost:8000/admin/third_party_auth/oauth2providerconfig/ on devstack)

  8. Click "Add Provider Configuration (OAuth)"

    • Ensure "Enabled" is checked
    • For "Icon Class", if a generic icon is needed, enter fa-sign-in. If a more relevant Font Awesome icon is available, use that; or upload an SVG icon using the "Icon Image" field.
    • For "Name", enter the name of the provider.
    • For "Backend Name", select the backend name from the dropdown. (If it does not appear in the list, then either the ENABLE_THIRD_PARTY_AUTH setting or the THIRD_PARTY_AUTH_BACKENDS setting is not configured correctly.)
    • Enter the Client ID.
    • Leave "Client Secret" blank (we set the secret via lms.auth.json instead, which is more secure).
    • Press Save

Users can now log in using this OAuth2 provider.

Note: OAuth 1 providers are also supported and can be configured using these same steps; however, OAuth 2 is preferred over OAuth 1 wherever possible.

Part 4: SAML Provider setup

SAML provider setup is already well-documented.

Part 5: In depth: Personal Information using SAML

Here is some information regarding how Personal Information is involved when using SAML, and how universities can manage that.

  • Whenever a user uses SAML/Shibboleth to login to edX, the provider (the University's system, called the "Identity Provider" or IdP in SAML parlance) authoritatively asserts pieces of information about the user.

  • Each piece of information is called a SAML attribute. Each attribute has a name and a formal OID URN identifier.

  • Here are some common attributes:

    Name OID URN Example value
    User ID urn:oid:0.9.2342.19200300.100.1.1 123456789
    Full Name urn:oid:2.5.4.3 Donna Noble
    First Name urn:oid:2.5.4.42 Donna
    Last Name urn:oid:2.5.4.4 Noble
    Email urn:oid:0.9.2342.19200300.100.1.3 dnoble@school.edu
    eduPersonPrincipalName urn:oid:1.3.6.1.4.1.5923.1.1.1.6 dnoble@school.edu
    eduPersonEntitlement urn:oid:1.3.6.1.4.1.5923.1.1.1.7 urn:mace:school.edu:confocalMicroscope
  • When a new user uses SAML to login to edX, the identity provider will send information about the user to Open edX in the form of these attributes. These attributes are used to pre-fill the registration form, but attributes other than the user ID are normally not otherwise recorded by Open edX. So for example, when a user logs in, their server may provide this information: "urn:oid:0.9.2342.19200300.100.1.1: 123, urn:oid:2.5.4.3: John Smith, urn:oid:0.9.2342.19200300.100.1.3: jsmith@school.edu". The user ID will be saved as it is required to match future login attempts to the correct user account. The full name ("John Smith") and email ("jsmith@school.edu") will be pre-filled on the registration form, but if the user edits those (say, changes the email to "jsmith@hotmail.com"), then only the new changed version will be saved. (So Open edX would record the user's email as "jsmith@hotmail.com" and would not have any record of the "jsmith@school.edu" address)

  • Open edX can accept any set of attributes sent by a SAML identity provider, as long as the attributes contain some sort of unique, permanent identifier for each user. The URN/OID of this identifier must be specified in the SAML Provider Settings (part of the Open edX django admin) in the "User ID Attribute" field. By default, Open edX will expect the standard User ID field (urn:oid:0.9.2342.19200300.100.1.1) and will use that as the unique external ID.

  • If you want to configure Open edX to always store all of the attributes sent by the external identity provider for each user, you can enable that with a setting. Go to the "SAML Configuration" admin page (note: not "SAML Provider Configuration"), and click "Add SAML Configuration", then in the "Other Config Str" section, add:

    "EXTRA_DATA": [ "attributes" ]
    

    That setting will cause all the attributes to be saved in the social_auth_usersocialauth table's extra_data column for every new SAML user. This data will only be accessible by accessing the database directly or by going to the "User social auths" page of the Open edX LMS Django admin.

  • For universities that wish to avoid sending any personally identifiable information to Open edX during the SAML login/registration process, we recommend that the university configure their SAML identity provider to only send a single attribute: a unique, permanent, opaque user ID. This should be a number that uniquely identifies any student or staff, but is different from their student ID or any other identifier they may have. (For reporting and analytics purposes, the university can use the "Third Party Auth ID mapping API" - see below - to convert Open edX user IDs found in reports/analytics back to these opaque university user IDs, and can then convert that opaque ID back to the official student ID.)

Part 6: Advanced SSO Features

"Skip registration form"

When configuring an OAuth2 or SAML provider in the Django admin, there is a boolean option to "Skip registration form" for that provider. Recall that normally when a new user logs in with an external provider, the information sent to Open edX is only used to pre-fill the registration form. When "Skip registration form" is enabled for a provider, the information sent to Open edX is also used to pre-fill the registration form, but then the form is automatically submitted before the user even has a chance to see it. If the registration succeeds, the user will immediately be logged in to their newly created account and can start learning right away. However, if there is any error, such as no email address was provided automatically (since email addresses are required) or the email address of the student conflicts with another existing Open edX user account, then the pre-filled registration form will still be displayed to the student, along with an error message. The student can then fix the error and submit the form to complete the registration process.

"Skip email verification"

When configuring an OAuth2 or SAML provider in the Django admin, there is a boolean option to "Skip email verification" for that provider. Normally, all users are required to verify their email address by clicking a link in the verification email that gets automatically sent to the user upon registration. When this option is selected, Open edX will trust that the email address provided by the external authentication provider is correct.

Upon registering with a provider that has this option enabled, then if the user's email address matches the email address that was sent to Open edX by the external provider, the user's email address will be marked as verified, and no verification email will be required. (Remember though that the email address sent by the external provider is only used to pre-fill the registration form, and the user has a chance to edit the email address on the registration form before creating their account. If they edit their email address so that it no longer matches the email address sent by the external provider, then the user will still be required to verify their email address as usual.)

Hinted Logins

When linking to Open edX, it's possible to create "hinted links" that will prompt the user to log in using a specific provider. For example, here is a normal link to an Open edX course:

https://courses.edx.org/courses/course-v1:McGillX+Body101x+1T2016/courseware/3eddbb5919544c229d34b3175debc6d6/f9900289d2d0474096d20d23a1eeed81/

and here is a hinted link:

https://courses.edx.org/courses/course-v1:McGillX+Body101x+1T2016/courseware/3eddbb5919544c229d34b3175debc6d6/f9900289d2d0474096d20d23a1eeed81/?tpa_hint=oa2-google-oauth2

Make sure you are logged out of edX (or use an incognito window), then click on both links. You will see that the hinted link prompts you, "Would you like to sign in using your Google credentials?" and includes a large button to use Google to login, as well as a small button to use other login options.

The intended use case of this feature is for universities that wish to provide a link from some on-campus system (or a course in another LMS like Canvas) to a course in Open edX. In that case, they will want students to login using their universities SAML provider. By using hinted links, the login and/or registration process will be simpler for students, as they won't have to pick a login provider or enter a password.

To create a hinted link for an OAuth2 provider, append ?tpa_hint=oa2-providername to any Open edX URL, where providername is the "Backend Name" value from the "Provider Configuration (OAuth)" section of the Open edX Django admin.

To create a hinted link for a SAML provider, append ?tpa_hint=saml-idpslug to any Open edX URL, where idpslug is the "Idp slug" value from the "Provider Configuration (SAML IdP)" section of the Open edX Django admin.

Auto-enrollment

Open edX has a feature that allows instructors, marketing teams, etc. to create links that will automatically enroll students who click the link into a specific course.

If you send users to {LMS base URL}/account/finish_auth and include course_id, enrollment_action", and optional course_mode and email_opt_in parameters, the system will auto-enroll the user into the specified course.

For example:

https://courses.example.com/account/finish_auth?course_id=course-v1%3AedX%2BDemoX%2BDemo_Course&enrollment_action=enroll&email_opt_in=false

This will auto-enroll whatever user clicks this link into the edX Demo course (that course's ID, course-v1:edX+DemoX+Demo_Course, has been url-encoded as the value of the course_id parameter). If the user is not logged in, they will need to login/register first, and then they will be auto-enrolled.

The full behavior is somewhat complicated. Here's an explanation of the parameters than can be included:

  • enrollment_action: This is required to trigger the auto-enrollment behavior. It must be set to either enroll (for free courses) or add_to_cart (for paid courses). If add_to_cart is used, the user will be directed to the shopping cart page rather than instantly enrolled.
  • course_id: This is required. The ID of the course to enroll the user in, or add to cart, etc. It must be URL-encoded.
  • course_mode: one of audit, honor, verified, etc. Only applies if enrollment_action is enroll. If it's not specified, and the course has more than one mode, the user will be sent to the "track selection" page where they can choose which track/mode to use. If honor or audit is specified, the user will be instantly enrolled. If any other mode is specified, the user will be sent to the payment/verification flow.
  • email_opt_in: Can be true or false. If true, this indicates that the user has consented to receiving marketing emails from edX and the course partner.

This feature can also be combined with "Hinted Logins", if you create a URL such as https://courses.example.com/account/finish_auth?course_id=course-v1%3AedX%2BDemoX%2BDemo_Course&enrollment_action=enroll&email_opt_in=false&tpa_hint=oa2-facebook

Third Party Auth ID mapping API

UBC contributed an API to Open edX that can be used to retrieve the association between Open edX user IDs and the unique user identifiers sent by the external platform.

Here is Pan Luo's description of that feature, from the original pull request:

When an edX course is used in an on-campus environment and SAML, LTI or other SSO is enabled to allow students to authenticate to edX using their on-campus credentials, normally there will be an identifier sent from an on-campus IdP. This identifier is stored in edX and linked to the edX account. Later when students return from an on-campus IdP, edX is able to authenticate the student using their edX account.

Because students may create edX accounts not using their real identity, the instructors will have difficulty to identify the edX students in their courses and won't be able to upload grades from edX back to on-campus gradebook system as the downloaded grades from edX only contain edX IDs, which are unknown to on-campus system.

This new API can be used for mapping between the edX user ID and the ID provided by identity provider (IdP). This API will give information that will allow instructors or course support staff to figure out the identity of the on-campus students who are using the edX course. It will also allow grade information coming from edX to be appropriately associated to campus students for uploading to an on-campus learning management system (LMS) or student information system (SIS).

This API is suppose to be consumed by a on-campus middleware, which combines the information from on-campus system. The middleware would talk to campus system to get information about course and enrolment. Then use those information to control instructor access. So the instructor will be able to get his/her edX student on-campus identity, uploading grades back to their LMS or SIS, making groups based on on-campus activities, etc.

This API also helps with troubleshooting with the issue where students put in wrong email addresses and weren't able to activate their accounts. Thus they weren't able to login EdX through Shibboleth because of the inactive accounts. With this API, on-campus course support staff or instructor can provide EdX support the student real EdX username instead of the ID that Shibboleth passed over to EdX, thus avoid the EdX support manually querying the tables to figure out the mapping between Shibboleth ID and EdX username.

To use the API:

  1. Have one or more third party auth providers enabled, and have learners who have link their accounts to one or more of those providers.
  2. Setup authentication and authorization:
    • Setup an OAuth2 Client. In Django Admin, go to OAuth2 -> Client -> Add Client.
      • User: it is good idea to create a dedicated user for this API
      • URL, Redirect URL: enter a dummy value like http://localhost/ (the URL is not being used for this API)
      • Client Type: Confidential
      • Other fields: no specific requirements
    • Give the new client permission to this API. Go to Third_Party_Auth -> Provider API Permissions -> Add Provider API Permission. Select the new client created in the previous step, and select an external authentication provider. This will give the new client access to query that provider mapping.
  3. The API is now available at {LMS base URL}/api/third_party_auth/v0/providers/{provider_id}/users. The API client must use OAuth2 to authenticate before that endpoint will work. The {provider_id} is the same format as described above in "Hinted Logins".

To test the API:

  1. Use client credentials (from the django admin) to get the access token:

    curl --data "client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=client_credentials" http://localhost:8000/oauth2/access_token
    Return: {"access_token": "c1efde84445b2f256e1c80886b3f6d46339b84ee", "token_type": "Bearer", "expires_in": 31535999, "scope": ""}
    
  2. Use the access token to issue requests to the API. Examples:

    curl --header "Authorization: Bearer ACCESS_TOKEN" http://localhost:8000/api/third_party_auth/v0/providers/{provider_id}/users
    
    curl --header "Authorization: Bearer ACCESS_TOKEN" http://localhost:8000/api/third_party_auth/v0/providers/{provider_id}/users?username=USERNAME1,USERNAME2
    
    curl --header "Authorization: Bearer ACCESS_TOKEN" http://localhost:8000/api/third_party_auth/v0/providers/{provider_id}/users?username=USERNAME1&username=USERNAME2
    
    curl --header "Authorization: Bearer ACCESS_TOKEN" http://localhost:8000/api/third_party_auth/v0/providers/{provider_id}/users?remote_id=REMOTE_ID1,REMOTE_ID2
    
    curl --header "Authorization: Bearer ACCESS_TOKEN" http://localhost:8000/api/third_party_auth/v0/providers/{provider_id}/users?remote_id=REMOTE_ID1&remote_id=REMOTE_ID2
    
  3. Here is an example return value from the API:

    {
      "page": 1,
      "page_size": 200,
      "count": 8,
      "results": [
        {"username": "USERNAME1", "remote_id": "REMOTE_ID1"},
        {"username": "USERNAME2", "remote_id": "REMOTE_ID2"},
      ]
    }

Secondary Providers

When configuring an OAuth2 or SAML provider in the Django admin, there is a boolean option to mark the provider as a "Secondary" provider. Normally, third party login providers are displayed on the Open edX login and register pages. However, "secondary" providers are not displayed directly on the login or register pages. Instead, there will be a button that says "Use my institution/campus credentials"; clicking that will bring up a separate menu that lists all the secondary providers.

The intended use case of this feature is to keep the login/register page from being cluttered with too many buttons.

SAML attribute requirements

When integrating Open edX with a SAML provider, it is possible to allow only some users to log in based on some criteria. For example, universities may not want alumni or guest users to be able to log in to Open edX using their SAML provider, even though those users have valid university login credentials.

Users can be filtered based on eduPersonEntitlement attributes (supported out of the box), or other attributes (requires custom code). For details on how this can be set up, refer to this mailing list post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment