District SSO - Best Practices & Edge Cases

This page highlights best practices for a successful SSO integration and describes how to handle certain edge cases.

Best Practices

Review the list of best practices below in order to set yourself up for a successful District SSO integration!

  • Don't exchange an authorization code value multiple times. You will receive an error.
  • Your integration must allow users to log in when arriving from the Clever Portal or an Instant Login Link. Do not just redirect users to your login page.
  • Your application's first defined redirect URI must handle logins for all districts without requiring additional parameters or subdomains.
    • Use a centralized redirect URI to capture users, then send users to specialized domains and URLs as necessary.
  • You must use HTTPS on your production user-facing redirect URI. The rest of your application should also use HTTPS.
  • Your application should include a Log in with Clever button.
  • Implement session overrides when a new authentication request comes in to account for shared devices. There are many cases where district users share devices. While you have no visibility into the active Clever session on the device, you will need to ensure that your application processes new authentication requests when there's an existing session and overrides the old session with a new one.
  • Have helpful indicators in your UI to let the user know they are logged in to their own account. This can be a name or a username somewhere obvious and visible.
  • Include a logout button! This is a good security practice.
  • If you need school information, which is not included in the District SSO access tier, you can ask the user to provide this information upon their first login.
    • This applies to other required fields that are not provided by the Clever District SSO access tier.

Edge Cases

Multi-role Users

With v3.0 of the APIs, Clever introduced multi-role users. This is meant to support users that have multiple roles within a district (e.g. a counselor who works in the capacity of an administrator as well as a teacher). This new paradigm was implemented to support the many combinations of user roles at school districts across the Clever ecosystem.

In Clever, users with multiple roles amongst the 3 non-student roles (teacher, staff/school admin, district admin) can have their different Clever user accounts tied together by an email address. While in Clever, they have a different UI for every role. However, you can choose to design a user experience that blends those roles and permissions or allows easy navigation between roles.

In API responses at /v3.0/users, you will see a roles node that contains each role a user has that is shared with your application. Each role in this list will have role-specific information, including a legacy_id, which is a Clever GUID that represents that specific role. It is important to note the distinction between this legacy_id and the user's id value found in the root JSON node. See the example response below:

{
    "data": {
        "created": "2022-05-15T22:20:03.535Z",
        "district": "62817af12d430f5d54001f99",
        "email": "[email protected]",
        "last_modified": "2024-07-10T16:22:11.422Z",
        "name": {
            "first": "PE",
            "last": "Bot"
        },
        "roles": {
            "teacher": {
                "schools": [],
                "legacy_id": "6298ef2e9e30ed3d9066e118"
            },
            "district_admin": {
                "legacy_id": "62817af1d65e86e415b6f68d"
            }
        },
        "id": "62817c88dc4dc002ea40b594"
    },
    "links": [
        {
            "rel": "self",
            "uri": "/v3.0/users/62817c88dc4dc002ea40b594"
        }
    ]
}

When a multi-role user kicks off SSO from Clever, you as the relying party will not have the context of which role they are logging in as. As such, it is important to design a default behavior for these cases. For example, a user with both an admin and a teacher role might by default be redirected to their admin console upon logging in. This all depends on what works best for your application.

State Parameters

If you are implementing OAuth 2.0 or OIDC with some sort of identity management system (IDM) such as Okta or Auth0, you might find that those services have a state parameter requirement.

The state parameter is an important security feature in OAuth 2.0 and OpenID Connect authentication flows. It is used to prevent Cross-Site Request Forgery (CSRF) attacks and to maintain state between the authorization request and the callback from the authorization server.

This particular requirement does not work well by default with Clever-initiated logins where a state parameter will not be generated. To account for this, Clever-initiated logins without a state parameter should be ignored and instead be treated as a trigger to re-initiate an authentication request from your site, thereby including a state parameter. When an authentication request is initiated with a state parameter appended, Clever will simply pass it through after processing the authorization and authentication.

If you are unsure of how to implement this workflow, feel free to reach out to our support team in our Help Center chat. However, please note that it will ultimately be up to you to handle this use case.

Supporting Multiple Applications with one Clever Login Button

There are some cases where you might support multiple environments for your product with multiple integration accounts in Clever. However, you may have a singular login page that serves as an entry point for your different environments. If this is the case, you may be wondering how you can provide Clever authentication for these different environments using one "Log in with Clever" button. To address this issue, we have the return_unshared=true parameter, which can be appended to the authorization link tied to your LIWC button. See an example below:

https://clever.com/oauth/authorize?response_type=code&redirect_uri=&client_id=&return_unshared=true

If a user that does not have access to your app and you supply this parameter, then instead of showing the user an error we will send an error message to the given redirect_uri with the message unauthorized-user.

When your app receives this message, you should then initiate a new login attempt using a different client ID (and different redirect URI if relevant). You can repeat this process as many times as necessary. Below is a basic flow diagram describing expected behavior:


🚧

Infinite Loop

Please ensure that the last attempted app DOES NOT supply the return_unshared param. Always including the return_unshared param can result in infinite looping behavior if the user does not have access to any of your apps.

Shared Devices for Students

If your application has strict security needs and you need a way to ensure that students can't accidentally access the wrong account on a shared device, you can use the confirmed=false to ask Clever to confirm the identity of the student. Clever does this by surfacing the following prompt:

You can include this parameter in your LIWC button to ensure that students cannot unintentionally initiate SSO using a cached Clever session of another student. This does not work for non-student user types.

https://clever.com/oauth/authorize?response_type=code&redirect_uri=&client_id=&confirmed=false

Implicit Grants

Clever uses the Authorization Grant flow. In some cases the Implicit Grant flow, documented here, may also be allowed.

Single Logout

🚧

Clever does not support SLO

As such, please ensure you are employing safe and secure user session management practices, taking into consideration common user behavior in a school setting, such as sharing devices.

Single Logout (SLO) describes the practice of being able to log a user out of multiple applications or services with a single action using a centralized authentication service.

Clever sessions can last up to 24 hours depending on the device being used. It is not recommended to log a user out of their Clever session once their session in your application ends. A core purpose of Clever SSO is to allow students quick access to all of their resources without having to re-enter credentials repeatedly. Logging a user out of Clever would disturb this workflow. Rest assured that school districts have policies in place to ensure proper logout practices on shared devices. If you have concerns and believe you have a good use case for logging a user out of Clever, please reach out to our support team in our Help Center chat.

Identifying Impersonations

You may find that district admins are able to impersonate users and potentially use SSO into your application on behalf of a user at their district. This might muddy your analytics on logins or inflate certain login metrics. We do have the ability to surface a flag that indicates if an SSO request was done via impersonation. If you're interested in this feature, reach out at support.clever.com.

Once set up, if a login attempt was done through impersonation, your redirect will include an appended loginas_by_admin=true parameter.