The OAAM Server provides a challenge processor framework that allows for custom implementations of challenge mechanisms.
This chapter contains the following sections:
A challenge processor is java code that implements the ChallengeProcessorIntf
interface or extends the AbstractChallengeProcessor
class.
Challenge processors can be created to perform the following tasks for a challenge:
Generate challenge secret (password) to send to the user.
Validate the user answer
Control delivery wait page (if needed)
Check if delivery service is available (if needed)
For example, to use SMS, you must implement a method for generating the secret PIN and checking the status of the send and the class that is called for by a challenge type.
This section contains information on the challenge processor class and methods to implement. An implementation example is also provided for your reference.
To implement a challenge processor, you will need to extend the following class:
com.bharosa.uio.processor.challenge.AbstractChallengeProcessor
Later, you will compile the code by adding oaam.jar from $ORACLE_IDM_HOME\oaam\cli\lib
folder to the build classpath.
For instructions on customizing, extending, or overriding Oracle Adaptive Access Manager properties, refer to Chapter 7, "Customizing Oracle Adaptive Access Manager."
The methods used in a challenge processor are listed in the sections following.
Table 20-1 Challenge Processor Methods
Methods | Description |
---|---|
protected boolean generateSecret(UIOSessionData sessionData, boolean isRetry) |
This method is used to generate code to send to client |
protected boolean validateAnswer(UIOSessionData sessionData, String answer) |
This method is used to validate the user answer. |
public String checkDeliveryStatus(UIOSessionData sessionData, boolean userWaiting, boolean isRetry) |
This method is used if you want to provide a wait until message is sent. |
public boolean isServiceAvailable(UIOSessionData sessionData) |
This method is used to check if external service is available. |
An implementation of the email challenge processor is shown as follows:
package oracle.oaam.challenge.processor.challenge; import com.bharosa.common.util.*; import com.bharosa.uio.util.UIOUtil; import com.bharosa.uio.util.UIOSessionData; import com.bharosa.common.logger.Logger; import java.io.Serializable; /** * Email Challenge Processor - provides OTP Code generation, delivery and validation */ public class EmailChallengeProcessor extends com.bharosa.uio.processor.challenge.AbstractOTPChallengeProcessor implements Serializable{ static Logger logger = Logger.getLogger(EmailChallengeProcessor.class); public EmailChallengeProcessor( ) { } /** * Generates OTP Code and stores it in sessionData * * @param sessionData data object available for the session * @param isRetry boolean value if method was called as a result of a failed answer attempt * @return */ protected boolean generateSecret(UIOSessionData sessionData, boolean isRety) { String otpCode = sessionData.getOTPCode(); // If no secret code is present in session, generate one. if (StringUtil.isEmpty(otpCode)) { if (logger.isDebugEnabled()) logger.debug("ChallengeEmail generating security code for user: " + sessionData.getCustomerId()); otpCode = generateCode(sessionData); // save the code for later reference - validate / resend sessionData.setOTPCode(otpCode); } if (logger.isDebugEnabled()) logger.debug("OTP code for user " + sessionData.getCustomerId() + " : " + otpCode); if (StringUtil.isEmpty(otpCode)) { logger.error("Email Challenge pin generation returned null."); return false; } // isRetry flag is turned on if user fails to answer the question if (!isRetry) { return sendCode(sessionData); } return true; } /** * Validate user entered answer against value in sessionData * * @param sessionData validate code and return result. * @param answer answer provided by the user * @return */ protected boolean validateAnswer(UIOSessionData sessionData, String answer){ //need to authenticate OTP Code String otpCode = sessionData.getOTPCode(); if (otpCode != null && otpCode.equals(answer)) { // Expire OTP Code sessionData.setOTPCode(null); return true; } return false; } /** * Private methods to send secret code to client * * @param sessionData * @return */ private boolean sendCode(UIOSessionData sessionData){ String otpCode = sessionData.getOTPCode(); try { // UIOUtil.getOTPContactInfo fetches the information registered by the user. Refer to ChallengeEmail.requiredInfo in configuration. String toAddr = UIOUtil.getOTPContactInfo(sessionData, "email"); if (StringUtil.isEmpty(toAddr)) { logger.error("No user email in profile."); return false; } // Send secret code to customer using your email provider } catch (Exception ex) { logger.error("ChallengeEmail Error sending code.", ex); return false; } return true; } public String checkStatus(UIOSessionData sessionData, boolean userWaiting, boolean isRetry) { String target = ChallengeProcessorIntf.TARGET_WAIT; // user already has code, trying again - send to challenge page if (isRetry){ return ChallengeProcessorIntf.TARGET_CHALLENGE; } boolean sendComplete = false; if (userWaiting){ // if secret code is sent set target to target = ChallengeProcessorIntf.TARGET_CHALLENGE; // failed to send target = ChallengeProcessorIntf.TARGET_ERROR; // still processing target = ChallengeProcessorIntf.TARGET_WAIT; } return target; } }
This section contains instructions on defining a delivery channel type. Examples are provided for your reference.
Challenge types are configured by the enum, challenge.type.enum
. The actual enum value is shown as follows:
bharosa.uio.<application>. challenge.type.enum.<challenge type>
For example,
bharosa.uio.default.challenge.type.enum.ChallengeEmail
The challenge type enum is used to associate a challenge type with the java code needed to perform any work related to that challenge type. An example of implementing an email challenge processor is shown in Section 20.2.3, "Example: Email Challenge Processor Implementation."
The Challenge Type ID (for example, ChallengeEmail) should match a rule action returned by the rules when that challenge type is used. The rule action for ChallengeEmail is rule.action.enum.ChallengeEmail. The rule action is to challenge the user using email using the email delivery channel. "Channel" normally refers to the delivery channel used to send to the user.
To define a challenge type, use the following property:
bharosa.uio.default.challenge.type.enum.MyChallenge
In the property, default is the UIO application name, and MyChallenge is the Challenge Type being added. For example, ChallengeEmail is the Challenge Type in the example below.
bharosa.uio.default.challenge.type.enum.ChallengeEmail
The rule action is to challenge the user with email using the email delivery channel.
rule.action.enum.ChallengeEmail
To enable/disable a challenge type, the available flag should be set:
bharosa.uio.default.challenge.type.enum.MyChallenge.available = false
Table 20-2 Challenge type Flags
Property | Description |
---|---|
available |
if the challenge type is available for use (service ready and configured). To enable/disable an OTP challenge type, the available flag should be set. |
processor |
java class for handling challenges of this type. |
requiredInfo |
comma separated list of inputs from the registration input enum |
Setting the available flag and setting the enabled flag are different. The enabled flag would remove it from list.
Example for Defining a Channel Type
Attributes bharosa.uio.default.challenge.type.enum with example values are shown as follows:
bharosa.uio.default.challenge.type.enum.MyChallenge = 1 // unique value to identify Challenge Email in bharosa.uio.default.challenge.type.enum bharosa.uio.default.challenge.type.enum.MyChallenge.name = MyChallenge // unique string to identify Challenge Email in bharosa.uio.default.challenge.type.enum, no spaces bharosa.uio.default.challenge.type.enum.MyChallenge.description = Email Challenge // descriptive name bharosa.uio.default.challenge.type.enum.MyChallenge.processor = oracle.oaam.challenge.processor.challenge.EmailChallengeProcessor // Processor used for sending emails instance of com.bharosa.uio.processor.challenge.ChallengeProcessorIntf bharosa.uio.default.challenge.type.enum.MyChallenge.requiredInfo = email // comma separated field names, User registration flow captures these data fields, check Contact information Inputs section to define this enum bharosa.uio.default.challenge.type.enum.MyChallenge.available = false // to turn off this service bharosa.uio.default.challenge.type.enum.MyChallenge.otp = true // indicates this challenge is used for OTP, set it to true
bharosa.uio.default.challenge.type.enum.ChallengeEmail = 1 bharosa.uio.default.challenge.type.enum.ChallengeEmail.name = Email Challenge bharosa.uio.default.challenge.type.enum.ChallengeEmail.description = Email Challenge bharosa.uio.default.challenge.type.enum.ChallengeEmail.processor = com.bharosa.uio.processor.challenge.EmailChallengeProcessor bharosa.uio.default.challenge.type.enum.ChallengeEmail.requiredInfo = mobile bharosa.uio.default.challenge.type.enum.ChallengeEmail.available = true bharosa.uio.default.challenge.type.enum.ChallengeEmail.enabled = true
bharosa.uio.default.challenge.type.enum.ChallengeSMS = 2 bharosa.uio.default.challenge.type.enum.ChallengeSMS.name = SMS Challenge bharosa.uio.default.challenge.type.enum.ChallengeSMS.description = SMS Challenge bharosa.uio.default.challenge.type.enum.ChallengeSMS.processor = com.bharosa.uio.processor.challenge.SmsChallengeProcessor bharosa.uio.default.challenge.type.enum.ChallengeSMS.requiredInfo = mobile bharosa.uio.default.challenge.type.enum.ChallengeSMS.available = true bharosa.uio.default.challenge.type.enum.ChallengeSMS.enabled = true
Instructions to configure user information properties are in the following sections:
For instructions on customizing, extending, or overriding Oracle Adaptive Access Manager properties, refer to Chapter 7, "Customizing Oracle Adaptive Access Manager."
Default configurations for enabling for registration and preference input are listed as follows:
Contact information registration
bharosa.uio.default.register.userinfo.enabled=false
Contact information preferences
bharosa.uio.default.userpreferences.userinfo.enabled=false
If user information registration and user preferences are true, configure input information.
Contact information inputs are defined in userinfo.inputs.enum. The enum element is:
bharosa.uio.<application>.userinfo.inputs.enum.<inputname>
Table 20-3 Properties for Contact Input
Property | Description |
---|---|
inputname |
Name used for the input field in the HTML form |
inputtype |
Set for text or password input |
maxlength |
Maximum length of user input |
required |
Set if the field is required on the registration page |
order |
The order displayed in the user interface |
regex |
Regular expression used to validate user input for this field |
errorCode |
Error code used to look up validation error message (bharosa.uio.<application ID>.error.<errorCode>) |
managerClass |
java class that implements com.bharosa.uio.manager.user.UserDataManagerIntf (if data is to be stored in Oracle Adaptive Access Manager database this property should be set to com.bharosa.uio.manager.user.DefaultContactInfoManager) |
bharosa.uio.default.userinfo.inputs.enum.email=1 bharosa.uio.default.userinfo.inputs.enum.email.name=Email Address bharosa.uio.default.userinfo.inputs.enum.email.description=Email Address bharosa.uio.default.userinfo.inputs.enum.email.inputname=email bharosa.uio.default.userinfo.inputs.enum.email.inputtype=text bharosa.uio.default.userinfo.inputs.enum.email.maxlength=40 bharosa.uio.default.userinfo.inputs.enum.email.required=true bharosa.uio.default.userinfo.inputs.enum.email.order=2 bharosa.uio.default.userinfo.inputs.enum.email.enabled=true bharosa.uio.default.userinfo.inputs.enum.email.regex=.+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3} bharosa.uio.default.userinfo.inputs.enum.email.errorCode=otp.invalid.email bharosa.uio.default.userinfo.inputs.enum.email.managerClass=com.bharosa.uio.manager.user.DefaultContactInfoManager
By default, challenge devices that will be used are configured through rules. The rules are under the AuthentiPad checkpoint where you can specify the type of device to use based on the purpose of the device.
To create/update policies to use the challenge type:
Add a new rule action, MyChallenge, with the enum, rule.action.enum.
Create policy to return newly created action, MyChallenge, to use the challenge method.
Alternatively, if you want to configure challenge devices using properties, you can bypass the AuthentiPad checkpoint by setting bharosa.uio.default.use.authentipad.checkpoint
to false
.
Devices to use for the challenge type can be added.
bharosa.uio.<application>.<challengeType>.authenticator.device=<value>
The examples shown use the challenge type key, ChallengeEmail and ChallengeSMS to construct the property name.
bharosa.uio.default.ChallengeSMS.authenticator.device=DevicePinPad bharosa.uio.default.ChallengeEmail.authenticator.device=DevicePinPad
Available challenge device values are DeviceKeyPadFull, DeviceKeyPadAlpha, DeviceTextPad, DeviceQuestionPad, DevicePinPad, and DeviceHTMLControl.
Table 20-4 Authentication Device Type
Property | Description |
---|---|
None |
No HTML page or authentication pad |
DeviceKeyPadFull |
Challenge user using KeyPad. |
DeviceKeyPadAlpha |
Challenge user with the alphanumeric KeyPad (numbers and letters only, no special characters) |
DeviceTextPad |
Challenge user using TextPad. |
DeviceQuestionPad |
Challenge user using QuestionPad. |
DevicePinPad |
Challenge user using PinPad. |
DeviceHTMLControl |
Challenge user using HTML page instead of an authentication pad. |