Blackboard APIs: A Guided Tour

Download Report

Transcript Blackboard APIs: A Guided Tour

Blackboard Building Blocks
APIs, Framework
and Security
Bob Alcorn, Director, Platform Architecture
Thursday, July 16, 2015
Overview
API Overview
– High level review of packages, patterns
Security
– Authentication and Authorization
– JVM security
Audience
Knowledge of Java programming
People 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 schema
Managed extensibility
– System extensions and deployment model
A Little History…
Import/Export
Building Blocks
Module Developer Kit
R6 Gradebook
R6 Assessment
R6 Portal
Building Blocks Architecture
Business Layer
(JSP, Servlet, Struts)
View Layer
(JSP, Servlet, Tag Library)
Data Objects
Core Services
Security
Log
Config
Session
Context
Persistence
Plug-ins
I18N
VXI
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 schema
Typed 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 flag
Id 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 values
 Custom 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
attributes
Membership
– 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 broker
Most have a Default object for direct
access
ContentDbLoader 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 functions
Exposed as interfaces (mostly)
Lookup via BbServiceManager
Services – Context
blackboard.platform.context
Critical entry point that all code must call
Context 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 implementation
Supports configurable levels
Written before log4j and JDK 1.4
Services - Security
Blackboard.platform.security
Authentication and Authorization
– AccessManagerService
Package Base
 Mix of utility objects
 BbList – 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 Model
Person, Course (Group), and Membership
Additional 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 Libraries
Encapsulate re-usable UI components to
capture the Blackboard look and feel
Tag Library Descriptors
– Re-use within individual web applications
– .tld files
Beyond APIs - Deployment
Not an API, per se
Critical 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
web.xml (Servlets)
Blackboard Manifest
Web Resources
Libraries
Servlets, JSP (Java)
.class, .jar files (Java)
Tying It All Together
 Each JSP or servlet will require touching
several different APIs
1.
2.
3.
4.
5.
6.
7.
8.
Set context
Authorize current User
Load content object
Access Gradebook data
Perform custom calculation
Log result
Render results (bracketed via tags)
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 the code do
– Can that
useritdo
they’re
trying to do?
what
iswhat
trying
to do?
Privacy
– Is the users’ data kept private?
Integrity
– Has the data been tampered with?
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
User
SystemRole
*1
1
*
*
Entitlement
**
*
Membership
CourseRole
*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 restrictions
Enforce API usage disclosure
– Manifest must declare required permissions
Basic Class Hierarchy
Principal
+getName()
0..* Has
1
Has
Class
+getProtectionDomain()
1
1
+getCodeSource()
+getPermissions()
1
PermissionCollection
Has
ProtectionDomain
1
1
Permissions
+add()
+implies()
+elements()
Has
Contains
*
0..*
1
CodeSource
Permission
+getCertificates()
+getPermissions()
+implies(in codeSource : CodeSource)
+implies()
+getName()
+getActions()
AllPermission
checks
SecurityManager
+checkPermission()
BasicPermission
PersistPermission
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
AccessControlManager
 For 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 walk
If the current frame has permission, allow
access
Allows 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
Initiates Stack Walk
SecurityManager.checkPermission()
Query.executeQuery()
DbConnectivityPrivilege.run()
NewBaseDbLoader.loadObject()
AnnouncementDbLoaderImpl.loadById()
ExtensionClass.foo()
ExtensionServlet.service()
Terminates Stack Walk
Stack Walk
Call Sequence
ConnectionManager.getConnection()
Policies
Policies define the Permissions associated
with code bases
Default implementation uses a policy file
Grant/deny permissions to code bases
Grant/deny permissions to Subjects
– New in JDK 1.4 with addition of JAAS
Example Policy File Entries
Tomcat.policy
// Tomcat gets all permissions
grant codeBase "file:${tomcat.home}${/}lib${/}-" {
permission java.security.AllPermission;
};
grant {
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
}
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 root
Read access to data (via APIs)
Read access to system properties
Everything 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 permission
Spawning 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 >