Blackboard Collaborate

Introduction

TBD

References

https://docs.blackboard.com/collab/Authorize%20and%20Authenticate%20in%20Blackboard%20Collaborate.html

"sample code for demonstrating the Blackboard Learn REST APIs in Python"

https://github.com/blackboard/BBDN-REST-DEMO_Python

"literally just screwing around. Don't take it seriously, please. I'm learning"

https://github.com/ryanhaber/Blackboard-REST-SDK-python


JWT Token (Collaborate)

pom.xml (Spring Boot 2.4.3 w/ Java 11)

<properties>

    <jjwt.version>0.11.2</jjwt.version>

</properties>

<dependencies>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-api</artifactId>

<version>${jjwt.version}</version>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-impl</artifactId>

<version>${jjwt.version}</version>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-jackson</artifactId>

<version>${jjwt.version}</version>

<scope>runtime</scope>

</dependency>

</dependencies>


Imports & constants

import javax.crypto.spec.SecretKeySpec;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.Jws;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

...


  /** JWT signature algorithm to be used for Blackboard Collaborate (BBC) */

  public static final SignatureAlgorithm BBC_JWT_SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;


Create token

  /**

   * Get BBC JWT:<br>

   * - 'iat' (token issue instant) is the number of seconds since 1970-jan-01 (UTC)<br>

   * - 'exp' (token issue expiration) is 'iat' plus, eg, 1 hour<br>

   * <br>

   * Sample JWT JSON to encode:<br>

   * 

   * <pre>

   {

      "iss": bbcKey,

      "sub": bbcKey,

      "iat": seconds_since_epoch,

      "exp": seconds_since_epoch + 3600

   }

   * </pre>

   * 

   * @param bbcKey    E.g: fake-D237593C-0913-A21A-45D1-F0EB08CE2812

   * @param bbcSecret E.g: BE4C6409-4798-41C2-B892-20B85723EC56

   * @return BBC JWT

   */

  /*-package*/ String createBbcJwt(final @NotBlank String bbcKey,

      final @NotBlank String bbcSecret) {

    long tokenValidityMs = 1L * 60 * 60 * 1000;

    //

    Date jwtIat = new Date();

    Date jwtExp = new Date(jwtIat.getTime() + tokenValidityMs);

    //

    byte[] apiKeySecretBytes = bbcSecret.getBytes();

    java.security.Key signingKey = new SecretKeySpec(apiKeySecretBytes, BBC_JWT_SIGNATURE_ALGORITHM

        .getJcaName());


    //

    return Jwts.builder()//

        // Data

        .setIssuer(bbcKey)//

        .setSubject(bbcKey)//

        .setIssuedAt(jwtIat)//

        .setExpiration(jwtExp)//

        // Sign

        .signWith(signingKey, BBC_JWT_SIGNATURE_ALGORITHM)//

        .compact();

  }


Round trip token

 /**

   * Round trip for BBC JWT (don't delete this method!).

   * 

   * @param bbcSecret E.g: BE4C6409-4798-41C2-B892-20B85723EC56

   * @param bbcJwt    BBC JWT

   * @return The claims of 'bbcJwt'

   */

  /*-package*/ Jws<Claims> fromBbcJwt(final @NotBlank String bbcSecret,

      final @NotBlank String bbcJwt) {

    //

    byte[] apiKeySecretBytes = bbcSecret.getBytes();

    java.security.Key signingKey = new SecretKeySpec(apiKeySecretBytes, BBC_JWT_SIGNATURE_ALGORITHM

        .getJcaName());

    //

    /*- DOC jjwt very.old.version

     return Jws<Claims> claims = Jwts.parser().setSigningKey(signingKey).parseClaimsJws(bbcJwt)

     */

    /*- DOC jjwt 0.11.5 which it's deprecated

     return Jwts.parserBuilder().setSigningKey(signingKey).build().parseClaimsJws(bbcJwt);

    */

    /*- DOC jjwt 0.12.2 */

    return Jwts.parser().verifyWith(signingKey).build().parseSignedClaims(bbcJwt);

  }


Verify token methods

  /**

   * Round trip BBC JWT.

   */

  @Test

  void createBbcJwtTest() {

    // Encrypt token

    String jwt = this.bbcHelper.createBbcJwt(bbcKey, bbcSecret);


    // Decrypt token

    Jws<Claims> claims = this.bbcHelper.fromBbcJwt(bbcSecret, jwt);


    String iss = claims.getBody().getIssuer();

    String sub = claims.getBody().getSubject();

    Date iat = claims.getBody().getIssuedAt();

    Date exp = claims.getBody().getExpiration();


    // Verify token

    assertEquals(bbcKey, iss);

    assertEquals(iss, sub);

    assertTrue(iat.before(exp));

  }