Projects‎ > ‎

Authentication

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

  1. Authenticator is implemented (i.e. {{IdPassAuthenticator})
  2. Authenticator is defined in the Configuration file openptk.xml
  3. 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

  1. User attempts to access a resource (web content, or REST uri) on the OpenPTK Server, using HTTP operations
  2. Filter interrogates the request prior to forwarding the request to the destination
    1. Check to see if an existing session is present
      1. Look for OPENPTKSESSIONID Cookie in the HTTP Request
      2. Using the Cookie value of OPENPTKSESSIONIF lookup a Session with the same Id
    2. Check for Client-App credentials (clientid, clientcred) in the request'
    3. Check for End-User credentials (user, password, http header) in the request
    4. If URI accessed in /uri/login and credentials or clientid is supplied in the request:
      1. 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)
          • set authSuccess=true
        • 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
        • process logout

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:
  • setId(...)
  • setProps(...)
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.

  1. Obtains client-side configuration data (local Properties file)
  2. Logs In to Server using Client Data and optional User Data
  3. Uses "execute()" method to perform operations
  4. 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"
   }
}
  1. Create a new Setup object using a "properties" file.
    • The properties file contains:
      • Client Id
      • Shared Secret
      • uri (base)
  2. 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
  3. Create Input object
    • Set the uniqueid if needed
    • Add Attributes as needed
    • Add Query as needed
  4. Call execute(Opcode, Input) on ConnectionIF
    1. Convert Input to a StructureIF object hierarchy
    2. ConnectionIF implementation processes Structure
      • ConnectionIF converters / encodes StructureIF to XML payload (as needed)
      • ConnectionIF invokes HTTP operation using XML payload
        • POST
        • PUT
        • GET
        • DELETE
      • ConnectionIF receives HTTP Response, contains XML payload
      • ConnectionIF converters / decodes XML payload to StructureIF
    3. ConnectionIF converts StructureIF object hierarchy to Output object
  5. 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