Introduction
This design document describes the proposed authentication framework. In addition to authentication this design will leverage a session for the framework to track requests for a user to prevent the need to authenticate for every operation. In addition to authentication, Client - Server Validation will be performed to ensure the client is allowed to make the requests. This is particularily important when the client is a portal server which only uses a token (userPrincipal) to obtain a openptk session. This is needed to prevent others from masquarading as another user.
Use Cases
Client |
Authen Mechanism |
Authen Artifact |
Description |
OpenPTK Server |
anonymous
Service UserId / Pass
OpenSSO
Admin |
anonymous (default)
web session auth uid / pass
userid / pass
HTTP header variable |
Anonymous will be allowed by default for limited functionality. Userid and password authenticaiton will be supported as a pass through to a OpenPTK Service. OpenSSO with an agent will protect the server web application. If the standard OpenSSO token is available, it can be validated with the OpenSSO apis or an agent can be used. If an agent is used, it agent is configured to added the openptkid and value in the HTTP header, and the OpenPTK token authenticator will be used. |
RESTful
browser-based client |
OpenSSO |
web session token |
URLs that support HTTP operations (PUT,GET,DELETE,POST) need to protected. Protection covers two main topics; authentication and authorization. This document will only address Authentication. |
RESTful
non-browser (iPhone - JavaFX) |
TBD |
TBD |
TBD |
RESTful
programmatic |
Certificate |
x.509 Cert |
TBD |
JSR-168 Portlets |
Portlet specific authen |
JSR-168 userPrincipal |
Leverage the Portlet's userPrincipal object which is created when the user logs into the Portal |
WSDL-based Web Service |
OpenSSO |
web session token |
TBD |
CLI |
OpenPTK Authenticator |
OpenPTK Credential |
End User will provide user id and password |
Architecture
Description
The OpenPTK server provides authentication and authorization for both the Service interface and the REST interface. In order to access anything on the OpenPTK server, a valid session must exist. Sessions are created with an authenticator based on the supplied credentials from the client.
Session Types
This session may be one of the following types:
Type |
Description |
INTERNAL |
A serverside limited session for internal use only for state management (example: forgotten password services) |
ANON |
Anonymous session with limited access |
USER |
A normal end user session which with limited access for the users own record |
SYSTEM |
A super user session with full access to the server and configuration information /contextroot/config |
The server can be configured to use all or only the desired types listed above. The session types are created on the server based on the authenticator which was used to create the session. Authenticators are configured with a single session type and users who obtain a session with that authenticator will obtain the matching session type.
Client Identifiers and Global Defaults for Authentication
The server contains client identifiers which contain a list of metadata about how a given client will interact with the OpenPTK server. The client configuration includes the following information:
Value |
Description |
ID |
Identifier for a specific client |
Shared Secret |
An optional shared secret to be used for client validation |
Authenticators |
A list of all authenticators which are "chained" for login requests for this client |
Default Authenticator |
The default authenticator for this client |
Contexts |
The available contexts for this client |
There is a global default clientid which is configured for the server. This will typically be used to allow anonymous access to the server and the recommended configuration will only include a single (Anonymous) authenticator.
Not Enforced URIs and HTTP operations
In order to process authentication when anonymous is not configured (in the client authenticators for a specific client of the global default), there are several URIs which need to be accessible to clients in order to login. Examples include:
HTTP Operation |
Not Enforced URI |
Description |
GET, POST |
/contextroot/login |
login URI - (this will not require a session to be present in order to login) |
GET, POST |
/contextroot/logout |
logout URI - (this will not require a session to be present in order to logout) |
GET, POST |
/contextroot/anon/* |
Server anonymous URI - user registration, forgotten password interaction, login error page(s) |
POST |
/contextroot/resources/contexts/{contextid}/subjects |
Registration |
GET |
/contextroot/resources/contexts/{contextid}/subjects/{subjectid}/password/forgot |
Forgotten Password Phase 1 - to get forgotten password questions |
PUT |
/contextroot/resources/contexts/{contextid}/subjects/{subjectid}/password/forgot |
Forgotten Password Phase 2 - to answer forgotten password questions (obtained from Phase 1). Also used to change the password after Phase 2 is successful - Phase 3 |
In order to accomodate the non - anonymous access to the operations for forgotten password and registration, a new session (type INTERNAL), is used to manage state. A mapping of the JSESSIONID to an INTERNAL session is used to provide the required state management for these operations.
Client Interaction
The following examples define the client interaction with the OpenPTK Server.
Out of band authentication
In order to interact with the OpenPTK server, a valid session must exist. The client can either use an anonymous session (provided anonymous is enabled on the server) or request an explicit out of band authentication.
Explicit login requires an HTTP POST to the following URI:
http://server:port/contextroot/login
The following login parameters are relevant for the request:
Type |
Name |
Description |
Request Parameter |
user |
User unique identifier |
Request Parameter |
password |
Verify the user |
Request Parameter |
clientid |
Client (application) unique identifier |
Request Parameter |
clientcred |
Verify the clientid |
If login is successful, a cookie with the openptk sessionid will be added to the HTTP response.
Explicit logout requires an HTTP POST to the following URI:
http://server:port/contextroot/logout
If logout is successful, the openptk sessionid will be invalidated and an anonymous session will be created (if configured).
Global Default clientid
The Global default clientid is used to configure the in band authentication options. This is typically used to allow anonymous access to the server without the need to explicitly create a session at a specific URI in advance.
If a clientid is not supplied in a request, the session is validated and if no session exists or the supplied session is invalid, the authenticators in the global default clientid will be used to attempt to create a session for the user.
NOTE: This default clientID is typically only used to enable limited anonymous access to the OpenPTK Server, (See Authorization Design for instructions for limiting what anonymous session are allowed to access.
Client Validation
In order to supply a secure way to transfer data between the client and the server, each client has an optional secret that can be supplied. This was designed in order to ensure that when portal integration is done, the userprincipal supplied to a portlet can be used by the client API along with the shared secret to validate the client is trusted.
Client Interaction with no client secret
The client will obtain a session (either due to an explicit login request to /contextroot/login by sending a POST and supplying the appropriate parameters, or by getting an anonymous session. When an explicit login is performed, all parameters will be sent in an HTTP POST in test strings. As is typical for web applications, SSL can be used to protect the data sent to the server.
Client Interaction with a client secret
If a client being used has a secret defined in the openptk.xml file, a clientcred parameter must be supplied which is used to validate the client. This contains a string which was encrypted by the client with the shared secret. The server decrypts the string in order to validate that the client has access to the shared secret. Any additional parameters required for authentication are also encrypted with the shared secret prior to being sent to the server as parameters. The server will decrypt these values. If they are not sent encrypted the authentication will fail. This process validates that the client is trusted based on access to a shared secret and that the attributes used in the authenticaion are encrypted in transit to the server. For additional protection, SSL can be used to protect the data sent to the server.
example:
<Client id="portal" secret="gKZo9rUyLeY56vSsFpxxxx">
Server Implementation
- Authenticator is implemented (i.e. {{IdPassAuthenticator})
- Authenticator is defined in the Configuration file openptk.xml
- Authenticator is associated with a the context in the Configuration file
This is an example of how the OpenPTK Server handles the authentication and session process. The org.openptk.server.servlet.filters.AuthNFilter Servlet Filter is configued in the web.xml for the server to enable authentication and session persistence in a cookie for all request for both the server web pages (.jsps) and the RESTful resources.
<filter>
<filter-name>AuthN</filter-name>
<filter-class>org.openptk.server.servlet.filters.EngineAuthNFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthN</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Configuration, Servlet Filter
Several required Global properties are now used by the Engine servlet filter so nothing is hard coded for authentication;
<Property name="auth.token.name.client" value="clientid" />
<Property name="auth.token.name.password" value="password" />
<Property name="auth.token.name.user" value="user" />
<Property name="auth.token.name.httpheader" value="openptkid" />
<Property name="auth.token.name.clientcred" value="clientcred" />>
<Property name="http.session.cookie.uniqueid" value="OPENPTKSESSIONID" />
<Property name="server.cookiepath" value="/" />
<Property name="server.defaultclient" value="anon" />
The AuthNFilter looks for the following pieces within a request:
Logic for authentication in Servlet filter
- User attempts to access a resource (web content, or REST uri) on the OpenPTK Server, using HTTP operations
- Filter interrogates the request prior to forwarding the request to the destination
- Check to see if an existing session is present
- Look for OPENPTKSESSIONID Cookie in the HTTP Request
- Using the Cookie value of OPENPTKSESSIONIF lookup a Session with the same Id
- Check for Client-App credentials (clientid, clientcred) in the request'
- Check for End-User credentials (user, password, http header) in the request
- If URI accessed in /uri/login and credentials or clientid is supplied in the request:
- call authenticate (String clientId, HashMap credentials)
- Check to see if a secret is configured for the supplied clientid. If present, the clientcred must be validated prior to proceeding.
- authenticate method gets the authenticators for the clientId supplied and evaluates each type of authenticator (Token, UserPass, and Anonymous) appropriately. A list of authenticators can be configured, in a clientid. The authenticators are processed in order, if a successful authentication is performed, the authentication process stops, and the session is created. There is no authentication chaining. If anonymous session authentication is needed for a clientid as well as other authenticators, the authenticators are used in the order they appear in the openptk.xml file (the anonymous authentication should be last).
- set message if necessary in jsession (for UI feedback)
- set authSuccess=true
- check to see if the existing session is valid
- (if session is not valid) Check to see if a default authenticator is present (by the anon clientid): NOTE this could be called default
- authenticate with this clientId
- set message if necessary in jsession (for UI feedback)
- if is authentication (anon access is allowed) successful, create new session (with new userid, Type, Level)
- check to see if the existing session is valid
- if not valid, authentication failed or anonymous access not allowed, and the requested URI is NOT part of the NOTENFORCEDLIST
- If part of the Server web UI: Redirect to /login
- if part of the REST /resources URI, set the appropriate HTTP response / required authentication information
- if is authentication successful, create new session (with new userid, Type, Level)
- Check to see if a logout uri /uri/logout is requested is supplied in the request
Example client configuration with authenticators defined:
<Client id="apitest" secret="McP7NoBoPTPHrJZLfXsnDEod">
<Authenticators>
<Authenticator id="Employees-IdPass-JDBC"/>
<Authenticator id="Anonymous"/>
</Authenticators>
<Contexts default="Employees-MySQL-JDBC">
<Context id="Employees-MySQL-JDBC" />
<Context id="Employees-OpenDS-JNDI" />
<Context id="Person-SunIdm-SPE" />
<Context id="Person-SunIdm-SPML1" />
<Context id="Customers-OpenDS-JNDI" />
<Context id="Register-Oracle-IdMgr" />
<Context id="User-Oracle-OIMClient"/>
</Contexts>
</Client>
NOTE: in order to explicitly logout (versus letting you session expire), the /logout URI must be used. An optional goto parameter can be passed to the /logout request to redirect the user to a specific destination after successful logout has occurred.
There are several Authenticators which are available on the server:
Object |
Description |
AuthenticatorIF |
Java Interface describing the basic components of an Authenticator |
Authenticator |
Java Class that will be used to extend specific types of Authenticators (i.e. File..., Jdbc, .....). This class will contain all of the base class variable and method implementations such as:
|
AnonAuthenticator |
Specific instance of an AuthenticatorIF implementation for File based authentication (similar to /etc/passwd) |
IDPassAuthenticator |
Abstract class and a specific instance of an AuthenticatorIF implementation for ID and password based authentication |
IDPassServiceAuthenticator |
Subclass of IDPassAuthenticator. Specific instance of an AuthenticatorIF implementation for user ID and password based authentication. This will leverage an OpenPTK Service for the actual authentication |
IDPassSystemAuthenticator |
Subclass of IDPassAuthenticator. Specific instance of an AuthenticatorIF implementation for user ID and password based authentication. This will leverage an OpenPTK username and password for a superuser in the openptk.xml file for the actual authentication |
TokenAuthenticator |
Abstract class and a specific instance of an AuthenticatorIF implementation for token based authentication |
OpenSSOTokenAuthenticator |
Subclass of TokenAuthenticator. Specific instance of an AuthenticatorIF implementation for opensso session based authentication |
HTTPHeaderTokenAuthenticator |
Subclass of TokenAuthenticator. Specific instance of an AuthenticatorIF implementation for userPrincipal session based authentication |
ClientPrincipalTokenAuthenticator |
Subclass of TokenAuthenticator. Specific instance of an AuthenticatorIF implementation for userPrincipal session based authentication |

Principals and Credentials for Authentication
A BasicPrincipal (extends principal, implements PrincipalIF) will be used by the authenticators. The principal will contain a BasicCredentials object (extends Credentials, implements CredentialsIF) to store the values presented in the request which are needed by any authenticator. The Credentials object internally includes a HashMap of objects which will be used for authentication which is supplied to the constructor. This is imutable. An accessor method for a credential will be used to return an object needed by an authenticator from the Credentials object.
Configuration of Alternate Username Attributes for Authentication
The default configuration will expect that the users will provide their uniqueid when authenticating. In some circumstances the username will be a different attribute, for example: email address. Additional attributes to use for authentication can be defined in the Definition. Here is an example of the Person Definition in the sample openptk.xml file. The definition.authenid property is used to define the attributes used for the username during authentication. If this value is not supplied, the uniqueid of the user will be required for authentication. The definition.password property is used to define the attribute used for the password during authentication. This property is required for authentication.
In this example, both email and the user id can be used for the username during authentication.
<Definition id="Person">
<Properties>
<Property name="definition.classname" value="org.openptk.definition.BasicSubject" />
<Property name="definition.description" value="A generic employee,partner,consultant" />
<!-- Example of authentication against multiple attributes. -->
<Property name="definition.authenid" value="id,email" />
<Property name="definition.password" value="password" />
Client Implementations
Java Client API
The "Client", is represented as a JAR file (OpenPTK-Client.jar) that provides a Java API. The "Client" performs the following functions.
- Obtains client-side configuration data (local Properties file)
- Logs In to Server using Client Data and optional User Data
- Uses "execute()" method to perform operations
- Logs Out to Server when complete
The Client API leverages the Input and Output classes to communicate with the "Server". The Client marshals/encode application requests and sends them to the Server using XML. It's also responsible to decode/un-marshals the XML message to a response.
A user of the "Client API" leverages the following interfaces:
Interface |
Methods |
Returns |
Decription |
Setup |
Setup("openptk_client") |
SetupIF |
Creates a Setup object using the specified Properties file |
SetupIF |
getConnection()
getConnection(user)
getConnection(user,password) |
ConnectionIF |
Get connection to the Server.
The getConnection() method is used for anonymous. The getConnection(user) would apply to "trusted" clients where it is assumed the user has already been authenticated, such is in a Portal. The getConnection(user,password) would be used by applications that can provide user input, such as "UML" |
ConnectionIF |
init() |
void |
One time initialization, typically called by the Setup object |
ConnectionIF |
open() |
void |
Open connection to the Server, typically called y the Setup object |
ConnectionIF |
close() |
void |
Close connection to the Server |
ConnectionIF |
setDebug(boolean) |
void |
Turn debug flag on/off |
ConnectionIF |
isDebug(boolean) |
boolean |
Is debug flag turned on/off |
ConnectionIF |
execute(Opcode, Input) |
Output |
Executes the Operations using the Input |
ConnectionIF |
getContextId() |
String |
Returns the current Context Id |
ConnectionIF |
getContextIds() |
String[] |
Returns array of all available Context Ids |
ConnectionIF |
setContextId(String) |
void |
Sets the ContextId, must be a valid Context |
ConnectionIF |
getSession() |
StructureIF |
Get the end-user Session information StructureIF, (see below) |
Session Structure:
session |
|
uniqueId |
SessionId |
|
type |
ANON, USER, SYSTEM |
|
clientId |
ClientId |
|
principal |
|
|
uniqueId |
PrincipalId |
|
|
contextId |
ContextId |
The Session Structure will always contain a uniqueId and a type. If the type is ANON then the princiapl sub-Structure will be null. Example Structures:
|
ANON
session = {
uniqueId = "1234-abcd-5678-efgh",
type= "ANON",
client=,
principal = {
uniqueId =,
contextId =
}
}
|
USER
session = {
uniqueId = "1234-abcd-5678-efgh",
type= "USER",
client="uml",
principal = {
uniqueId = "bsmith",
contextId = "Employee-JNDI-OpenDS"
}
}
|
- Create a new Setup object using a "properties" file.
- The properties file contains:
- Client Id
- Shared Secret
- uri (base)
- Call getConnection() method on Setup to obtain a ConnectionIF object
- Instantiate class the implements ConnectionIF ... JerseyConnection
- Call open() method on ConnectionIF
- Use "Shared Secret" to encrypt "payload", used as clientcred
- Set HTTP Request parameters: clientid and clientcred
- If user authentication, Set HTTP Request parameters: user and password
- HTTP POST to Server for: .../login
- Create Input object
- Set the uniqueid if needed
- Add Attributes as needed
- Add Query as needed
- Call execute(Opcode, Input) on ConnectionIF
- Convert Input to a StructureIF object hierarchy
- ConnectionIF implementation processes Structure
- ConnectionIF converters / encodes StructureIF to XML payload (as needed)
- ConnectionIF invokes HTTP operation using XML payload
- ConnectionIF receives HTTP Response, contains XML payload
- ConnectionIF converters / decodes XML payload to StructureIF
- ConnectionIF converts StructureIF object hierarchy to Output object
- Call close() method on ConnectionIF
- HTTP POST to Server for: .../logout
|
|
Example Applications that use the Client API:
Name |
Description |
Authentication |
APItest |
Set of stand-alone Java examples that test individual operations |
setup.getConnection()
setup.getConnection("ja1324")
setup.getConnection("ja1324","Passw0rd") |
UML |
JSP application that uses the OpenPTK Taglib |
<ptk:getConnection var="..." />
<ptk:getConnection var="..." user="ja1324" />
<ptk:getConnection var="..." user="ja1324" password="Passw0rd" /> |
Portlet |
JSR-168 Portlet application using Java API |
setup.getConnection()
setup.getConnection("ja1324")
setup.getConnection("ja1324","Passw0rd") |
CLI |
Command-Line Interface |
setup.getConnection()
setup.getConnection("ja1324")
setup.getConnection("ja1324","Passw0rd") |
Authenticator Testing
Codes: |
= Pass |
= Fail |
= Conditional |
N/A = Not Applicable |
Anon
 |
Identity Central
Need to sometimes login before anon searching/reading will work. Usually after a (re)start |
CLIENT |
Embedded DB |
MySQL DB |
Oracle DB |
JNDI/OpenDS |
UnboundId |
OIM 11g |
Identity Central |
|
|
|
|
|
|
UML (register) |
|
|
|
|
|
|
Register JSP |
|
|
|
|
|
|
Register Portlet |
|
|
|
|
|
|
ID/Pass Service
CLIENT |
Embedded DB |
MySQL DB |
Oracle DB |
JNDI/OpenDS |
UnboundId |
OIM 11g |
Identity Central |
|
|
|
|
|
|
CLI |
|
|
|
|
|
|
UML Self Service |
|
|
|
|
|
|
Portlet Self Service |
|
|
|
|
|
|
Token (HTTP Header)
CLIENT |
Embedded DB |
MySQL DB |
Oracle DB |
JNDI/OpenDS |
UnboundId |
OIM 11g |
Identity Central |
|
|
|
|
|
|
UML Self Service |
|
|
|
|
|
|
Trusted Client
CLIENT |
Embedded DB |
MySQL DB |
Oracle DB |
JNDI/OpenDS |
UnboundId |
OIM 11g |
WSDL-Web Service |
|
|
|
|
|
|
Portlet |
|
|
|
|
|
|
ID/Pass System
CLIENT |
(Internal) |
OpenPTK Server |
 |
Identity Central |
 |
CLI |
 |
UML |
 |
Portlet Admin |