Blackboard Building Blocks APIs, Framework and Security Sunday, November 22, 2015 Bob Alcorn,...

Preview:

Citation preview

Blackboard Building Blocks

APIs, Framework and Security

Thursday, April 20, 2023

Bob Alcorn, Director, Platform Architecture

Overview

API Overview– High level review of packages, patterns

Security– Authentication and Authorization– JVM security

Audience

Knowledge of Java programmingPeople who want an overview of the entire

range of functionality exposed – (without resorting to reading the docs)

Thinking of building, don’t know what to look at first…

Design Goals – High Level

Decouple persistence from data objects– XML and Database– Originally targeted for import/export– Database abstraction

Iterative functionality– Start with simple objects, mapped to the

legacy schemaManaged extensibility

– System extensions and deployment model

A Little History…

Import/Export

R6 Portal

R6 Gradebook

R6 Assessment

Module Developer Kit

Building Blocks

Building Blocks Architecture

Core Services

Data Objects

Business Layer(JSP, Servlet, Struts)

View Layer(JSP, Servlet, Tag Library)

Log

Security

Config Persistence

Session

I18N VXI

Context Plug-ins

Road Map

Data objects and packages– What data can I see?

Persistence objects and packages– How do I get to the data?

Service objects and packages– How do I log it, authenticate it, etc.?

Security

Data Objects

blackboard.data

Object view of the schemaTyped to wrap legacy database constructs

– Type-safe enumerations for constrained database columns

– User.EducationLevel.GRADUATE_SCHOOL– Faithful adherence to existing schema has

some interesting side effects

Data Objects – BbObject

Base object for all data objects– Common attributes – Primary Key (Id), dates,

etc.“Smart” attributes

– Properties stored in an internal map, instead of member variables

– Smart load, dirty flagId attribute helps define lifecycle

– Id.UNSET_ID – default id for new objects

Data Objects – Content

blackboard.data.content

Content is the root object that can be used in the “content” areas of a course– All other objects are simple subclasses of Content

that over-ride specific valuesCustom content types should create and

manipulate Content objects; not CourseDocument objects.– CourseDocument can be used to manipulate the base

“Item” type

Data Objects – Content

ContentHandler– Ties content to URI-based “handlers”– This is really the B2 “glue” for custom content

IsFolder– Can the object contain other objects

IsLesson– Should the contents be displayed sequentially

RenderType– Render the object like “Item”, “Folder”, or “Link”

Data Object – Content

Data Objects – Course

blackboard.data.course

Course and Organization– Organization over-rides course for specific

attributesMembership

– Enrollment, Staff Assignment– Enumerated roles

Course Subgroup and Membership

Data Objects - Gradebook

Blackboard.data.gradebook

LineItem– Defines the “columns” in a course gradebook

Score– Wraps the actual outcome for a given line

item

Data Objects – Misc.

Announcement– Wraps, well, announcements– Can be system or course level

Calendar– Wrap entries in the calendar– Course and System level

Persistence Objects

Intended to be decoupled from data objects

Interfaces allow replaceable persistence implementations– Currently proprietary to Blackboard

BbPersistenceManager– Ties together different aspects of persistence– Loader/Persister broker– Container

Persistence Objects – Id

Used to encapsulate the unique identifier for each data object

Primary key, and more…– Data type– Container (database)– GUIDs are not used, so keys can collide

Persistence Objects – Loaders

Base interface to get at data– Roughly one-to-one correspondence to data objects

All type-specific loaders are geared towards known predicates– loadById()– loadByUserIdandType()– Performance. Ad hoc queries can kill the system…– Schema stability.

Persistence Objects – Persisters

Perform any action that manipulates data– Again, one-to-one correspondence with data

objects

“Smart” update– Id object state determines insert vs. update

Accessing Persisters and Loaders

They’re interfaces, not directly instantiated by callers

BbPersistenceManager is the brokerMost have a Default object for direct

accessContentDbLoader loader =

ContentDbLoader.Default.getInstance()

Putting It Together

Content content = new Content();content.setTitle();

// . . . Etc.

ContentDbPersister contentPersister = ContentDbPersister.Default.getInstance();

contentPersister.persist();

Services

Infrastructure for common utility functionsExposed as interfaces (mostly)Lookup via BbServiceManager

Services – Context

blackboard.platform.context

Critical entry point that all code must callContext wraps information about current

request to get the correct database connection

Interact via ContextManager.setContext() and ContextManager.releaseContext()

Services – Session

blackboard.platform.session

State for the current browser-based client– Stores authentication status

Cookie-based session management– Database persistent to share between Perl and Java

processes– Some assembly required

• Not all HTTP-clients (e.g., media plugins for browsers) honor the host browser’s cookies

Services – Filesystem

blackboard.platform.filesystem

FileSystemService - Broker different file system locations– Course and content– E.g., getContentDirectory()

Services – Log

blackboard.platform.log

Simple write-only log implementationSupports configurable levelsWritten before log4j and JDK 1.4

Services - Security

Blackboard.platform.security

Authentication and Authorization– AccessManagerService

Package Base

Mix of utility objectsBbList – List implementation that can enforce

type safety– Not really useful externally; since it implements List,

and you have to cast anyway, that’s what you should use

BbEnum – base class for all type-safe enumerations

NestedRuntimeException/NestedException – pre-JDK 1.4 facility for chaining exceptions

Package Base

FormattedText – encapsulation of text data entered via standard Text boxes– Defines enumeration for Smart, Plain, and

HTML text

GenericComparator – Comparator implementation that can sort based on arbitrary properties– Works with String, Boolean, Dates, and

Comparable

Administrative APIs

blackboard.admin.*

APIs geared towards data integration– Formerly called the “Event” APIs– Repackaged to be more consistent with B2

APIs– Compatibility layer supported

Base classes used in Snapshot

Administrative APIs

Follows IMS Data ModelPerson, Course (Group), and MembershipAdditional objects for Blackboard usage

– Category– Data Source

• Defines logically related entities that can be managed independently via Snapshot

Portal

blackboard.portal.external

CustomData is all you’ll need…– getModuleData()– getModulePersonalizationData()

Store name/value– Value can be string, or binary object

Beyond APIs – UI Integration

Tag LibrariesEncapsulate re-usable UI components to

capture the Blackboard look and feelTag Library Descriptors

– Re-use within individual web applications– .tld files

Beyond APIs - Deployment

Not an API, per seCritical aspect of extension development

– XML manifest used to generate records in the database that define navigation, content brokering

Anatomy of a System Extension

Package (.war/.zip file)

Platform Descriptor

Blackboard Manifest

Web Resources

Libraries

web.xml (Servlets)

Servlets, JSP (Java)

.class, .jar files (Java)

Tying It All Together

Each JSP or servlet will require touching several different APIs

1. Set context

2. Authorize current User

3. Load content object

4. Access Gradebook data

5. Perform custom calculation

6. Log result

7. Render results (bracketed via tags)

8. Release context

Thoughts

There are a lot of classes to look at…– Focus on the type of Building Block you need

to build– Take it methodically, iteratively. What’s your

first goal? Second goal?

Think of combining functions– What can I do using Content with Gradebook?

Security

Security – High Level View

Authentication– Who is using the system?

Authorization– Can that user do what they’re trying to do?

Privacy– Is the users’ data kept private?

Integrity– Has the data been tampered with?

Can the code do what it is trying to do?

Topics for B2 Developers

Common Security Tasks– Authentication, Authorization

Declaring Permissions– Often trial and error iteration… add a

permission, get stopped by another one

Authentication for Extensions

Simple, let the platform worry about it…

BbSessionManagerService sessionService = BbServiceManager.getSessionManagerService();

BbSession bbSession = sessionService.getSession( request );

AccessManagerService accessManager = (AccessManagerService)BbServiceManager.lookupService( AccessManagerService.class );

if (! bbSession.isAuthenticated() ) { accessManager.sendLoginRedirect(request,response); return;}

Authentication for Extensions

Access Manager coordinates with authentication providers to do the right thing

Default providers– RDBMS– LDAP– Web Server

Custom providers

Authorization in Blackboard

Role-based assignment– System role attached to

user object– Course role attached to

enrollment record

Privileges attached to Roles– Editable– Check relies on the union

of all relevant entitlements

SystemRole

Entitlement

CourseRole

User

Membership

1

*

* 1

* 1**

**

Customizing Privileges

It All Comes Back To…

Context!– You have the user, and thus the

system role…– You have the course, and thus the

course role...– Access control works against the full

entitlements mask

Authorization for Extensions

Authorization– Role-based checks – Deprecated...– Entitlement-based checks – Not finalized…

PlugInUtil.authorizeForXXX()– authorizeForCourseControlPanel()– authorizeForSystemAdminPanel()– authorizeForCourse()– authorizeForContent()

Code Security Framework

Leverage security inherent in the Java 2 Standard Edition framework

Enforce certain API restrictionsEnforce API usage disclosure

– Manifest must declare required permissions

Basic Class Hierarchy

+implies()+getName()+getActions()

Permission

BasicPermission

Permissions+add()+implies()+elements()

PermissionCollection

+checkPermission()

SecurityManager

AllPermission

+getProtectionDomain()

Class+getCodeSource()+getPermissions()

ProtectionDomain

+getCertificates()+getPermissions()+implies(in codeSource : CodeSource)

CodeSource checks

1 1

Has

1 1

Has

*0..*

Contains1

1

Has

PersistPermission

+getName()

Principal

0..*

1

Has

Permission Class

Permission– Abstract base class for all permissions– All Permission objects define a name and

actions– Relationships can be created via

implies( Permission )BasicPermission

– Concrete base class for most permissions

Classes

Security information available through Class object– Object.getClass()

ProtectionDomain– Encapsulates information about the classes

physical source and associated permissions– Class.getProtectionDomain()

Classes

PermissionCollection– ProtectionDomain.getPermissions()– List of permissions

• PermissionCollection.implies( Permission )

CodeSource– ProtectionDomain.getCodeSource()– Physical location of class (URL)

• Hierarchical: CodeSource.implies( CodeSource )

– Certificates

Security Checks

SecurityManager.checkPermission( Permission )– Other checkXXX() methods ultimately

delegate to this method– This method, in fact, delegates to

AccessControlManagerFor each frame in call stack

– Get code source– Get permissions for code source– Requested permission implied by permissions

collection?SecurityException thrown if check fails

Checking Permissions

if( _modifyPermission != null ){ System.getSecurityManager()

.checkPermission( _modifyPermission );}

Privileged Blocks

Interrupts stack walkIf the current frame has permission, allow

accessAllows trusted code to perform actions that

may not be granted to the caller– E.g., un-trusted code may not have network

permission, but the database driver does

Examples

System Extensions cannot connect directly to the database

Our own code, which may be called by a System Extension, needs to get a database connection

Solution: Privileged block– Code executing with more privileges can accomplish

what it needs to

Example

private class DbConnectivityPrivilege implements PrivilegedExceptionAction { private Query _query; private Connection _con;

private DbConnectivityPrivilege(Query query, Connection con) { _query = query; _con = con; }

public Object run() throws Exception { _query.executeQuery( _con );

return null; } }

Example

try{ AccessController.doPrivileged( new DbConnectivityPrivilege(query, con));}catch(PrivilegedActionException pae){ castException( pae );}

Example

ExtensionClass.foo()

AnnouncementDbLoaderImpl.loadById()

NewBaseDbLoader.loadObject()

DbConnectivityPrivilege.run()

Query.executeQuery()

ConnectionManager.getConnection()

SecurityManager.checkPermission()

ExtensionServlet.service()

Ca

ll S

eq

ue

nce

Sta

ck W

alk

Initiates Stack Walk

Terminates Stack Walk

Policies

Policies define the Permissions associated with code bases

Default implementation uses a policy fileGrant/deny permissions to code basesGrant/deny permissions to Subjects

– New in JDK 1.4 with addition of JAAS

Example Policy File Entries

// Tomcat gets all permissionsgrant codeBase "file:${tomcat.home}${/}lib${/}-" { permission java.security.AllPermission;};

grant {

permission java.util.PropertyPermission "java.version", "read"; permission java.util.PropertyPermission "java.vendor", "read";}

Tomcat.policy

Activating Security

Run-time properties on the command line– -Djava.security.manager– -Djava.security.policy

java.security – Configuration file for setting security providers– policy.provider – Class that is responsible for

implementing the policy• Default is sun.security.provider.PolicyFile

Blackboard Implementation

wrapper.properties/tomcat.sh– Points to tomcat.policy

service-config.properties– code-level-access-control=true– Can disable SecurityManager regardless of

command line options

Custom Policy implementation

Blackboard Implementation

SecurityUtil.checkPermission()– Hides check for SecurityManager– Propagates Security Exceptions

BbPolicy– Wraps code sources for System Extensions– Attempts to prevent “over-riding”

• You can’t just put permissions in the policy file

Blackboard Permissions

blackboard.persist.PersistPermission– Name is the data object, actions are

“read,create,modify,delete”– Base persister and loader classes check for

permission

Blackboard Permissions

blackboard.data.AttributePermission– Controls access to attributes on a data object– Naming convention allows single attributes or

groups to be protected– E.g., untrusted code can load a user, but can’t

get the (hashed) password

Blackboard Permissions

<permission type=“persist” name=“Content” actions=“create,modify,delete”/>

<permission type=“attribute” name=“user.authinfo” actions=“read,write”/>

System Extensions

Deployed as a web application with a unique code source– Code source is attached to /plugin directory, so it

encompasses the /webapp and /config directories

Manifest includes a permissions block– Some filtering to restrict certain permissions– Manifest is equivalent of policy file

System Extensions

Enabling an extension at startup– Read permissions from database– Associate with web app code source– Register servlet context with Tomcat

• Registration of servlet context only occurs if extension is “Available” or “Unavailable”. Otherwise, no code may be executed

System Extensions

Permissions block contains 0 or more permission elements

Same meaning as “grant” entries in the standard Java policy file– No explicit deny

Simple mnemonics for common types– Runtime, Socket, Persist, Attribute

Type attribute can be any fully qualified Java classname– Must be a Permission sub-class, with two argument

constructor (String, String)

Example Permissions

<permissions><permission type=“socket” name=“api.google.com” actions=“connect”/><permission type=“runtime” name=“accessDeclaredMembers” actions=“”/><permission type="java.util.PropertyPermission" name="java.protocol.handler.pkgs" actions="write"/>

</permissions>

Default Permissions

Read/write access to extension’s home directory

Read access to Blackboard rootRead access to data (via APIs)Read access to system propertiesEverything else must be explicitly

declared…

Manifest Limitations

No escape syntax– Properties that require user input, or

information from local system, cannot be encoded in permission block

Manifest – Administrators View

Tips

Read the Javadoc for any third party libraries you are using– Many developers don’t test their code with a

security manager, so they don’t know what they’re touching

• E.g., Axis configuration routines will throw SecurityException if run with a SecurityManager

Think security…– What would you as an administrator want to

see disclosed?

Tips – Common Restrictions

System.getProperties() – returns a mutable copy of the system

permission; thus you need <permission type=“java.util.PropertyPermission”name=“*” actions=“read,write”/>

Reflection requires runtime permissionSpawning a process requires a runtime

permission

Final Thoughts

Framework is effective for what it is… a simple data access API and deployment model

Limitations– No transactions (you can’t get to the database

connection)– Some counter-intuitive patterns– Business logic not well encapsulated

Well positioned to be greatly expanded and streamlined– Deployment model works well

Thank You

Demos to Follow >

Recommended