The smart authentication being demonstrated in this post implements a two-step authentication method to access Oracle APEX applications. The first step is the conventional username and password combination. The second one is smart code authentication in which your smartphone is used. The second method is added to the first one to add an extra layer of protection to your app. Even if your username and password falls into wrong hands, they can't access the app, because they don't have your smartphone.
To implement smart authentication, you are going to modify your app’s login page. When you run this page after modifications, it will present the conventional username and password for initial authentication. Once you are authenticated, a message containing 6 digit code will be sent to your registered smartphone. A small text box pops up on the login page at the same time to receive the 6-digit code. Once this code is verified, you are landed on the home page.
For this module, you need an SMS gateway. You
can obtain this using a hosted service by signing up with Twilio, Tropo,
Clickatell, or one of the many other providers. They'll often provide some free
credits with an API.
Once you get the API, execute the following steps to implement the smart authentication module.
1. Open your application’s login page, click its root node, and add
the following CSS code to the Inline section.
body { background-image:
url(#APP_IMAGES#BG.jpg); background-repeat: no-repeat; background-attachment: fixed; background-size: cover; } .t-Login-region { background-color:
rgba(255,255,255,0.25); border-radius: 0px; height:800px; } #verify { margin-top:250px; } #access {
margin-top: -85px;
color: #404040;
text-align: center;
z-index: 1; } |
2. Create a new region and place it just above the existing login region. The region will hold a text field item to receive a smart code that will be sent to the user’s mobile device and will be used to authenticate the user. Set the following attributes for the new region.
The User is Authenticated server-side condition ensures that the region will be displayed only when the user is logged into the application using the conventional username and password credentials.
3. Add the following text field item to the SmartCode region. The
smart code you receive through SMS on your mobile device will be entered into
this field.
4. Add a button to the SmartCode region using the following attributes. After you input the smart code, hit this button to access the application. The static id set for this button is referenced in the CSS code to align the button accordingly.
5. Go to Shared Components | Templates, and make a copy of the default Login page template. I named the copy Login (Copy). Open the Login (Copy) template, scroll down to the Body section under Definition, and replace the existing div code with the one that follows. The code sets the body width to 100%.
<div class=maindiv
style="width:100%">
<header>#REGION_POSITION_01#</header>
<main
id="main">#SUCCESS_MESSAGE##NOTIFICATION_MESSAGE##GLOBAL_NOTIFICATION##BODY#</main>
<footer>#REGION_POSITION_02#</footer>
</div>
6. Open the application Login page in Page Designer, click the root node, and set Page Template to Login (Copy).
7. Set the following attributes for the default authentication region
to align it to the right side of the page.
Property |
Value |
Start New Row |
No |
Column |
10 |
Column Span |
3 |
8. Create the following dynamic action that will call an Ajax callback
process (specified in the next step) to retrieve the user's mobile number and an auto-generated
smart code. After retrieving this information, the JavaScript code used in this
dynamic action will send an SMS to the mobile device of the logged-in user.
Again, this code will execute only when the user is authenticated by the
conventional method.
Property |
Value |
Name |
Send
SMS |
Event |
Page
Load |
Server-side Condition Type |
User
is Authenticated (not public) |
True Action |
Execute
JavaScript Code |
Code |
/*
Show a processing image */ var
lSpinner$ = apex.util.showSpinner();
apex.server.process("GENERATE_SC", {pageItems:
"#P9999_USERNAME" }, {success: function(pData)
{ /* If the AJAX is successful get the mobile
and smartcode values*/ if (pData.success ===
true){ for (var i=0; i
< pData.items.length; i++){ if (i == 0) { var
VsmartCode = pData.items[i].value; } else { var
Vmobile = pData.items[i].value; } } var xhr = new
XMLHttpRequest();
xhr.open("GET", "PUT_YOUR_API_KEY_HERE&to="+Vmobile+ "&content=Your Key is:
"+VsmartCode, true);
xhr.onreadystatechange = function(){ if
(xhr.readyState == 4 && xhr.status == 200){
console.log('success') } }; xhr.send(); } lSpinner$.remove(); }, error: function(request,
status, error) {
alert(request.responseText); lSpinner$.remove(); } } ); |
Fire on Initialization |
No |
9. Create the following Ajax callback process to generate a dynamic
six digits smart code, and retrieve the mobile number of the logged-in user from
the user's table. The six digits smart code will be stored in an APEX
collection, which is then used in a validation (specified in the next step)
for verification.
Property |
Value |
|
Name |
GENERATE_SC |
|
Type |
PL/SQL
Code |
|
PL/SQL Code |
declare VsmartCode varchar2(6); Vmobile varchar2(15); begin select DBMS_RANDOM.string('x',6) into
VsmartCode from dual;
apex_collection.create_or_truncate_collection ( p_collection_name
=> 'SMARTCODE'); apex_collection.add_member( p_collection_name
=> 'SMARTCODE', p_c001 => VsmartCode); select mobile into Vmobile from APP_USERS where upper(userid)=upper(:P9999_USERNAME); apex_json.open_object; /*This procedure writes an open curly
bracket symbol*/ apex_json.write('success', true); /*AJAX
successful tag returned to the JavaScript*/ apex_json.open_array('items'); /* This procedure writes an open
bracket symbol*/ apex_json.open_object; apex_json.write('value', VsmartCode,
true); /*Procedure to write array attributes*/ apex_json.close_object; /*
Writes a close curly bracket symbol*/ apex_json.open_object; apex_json.write('value', Vmobile, true); apex_json.close_object; apex_json.close_array; /*Close bracket
symbol*/ apex_json.close_object; /*
Close curly bracket symbol*/ exception when others then apex_json.open_object; apex_json.write('success', false); apex_json.write('message', sqlerrm); apex_json.close_object;
{
"success":true ,"items":[ {
"value":"ABCDEF" } ,{
"value":"921238989827" } ] } |
Point |
Ajax
Callback |
10.
Create a validation to verify the smart code.
Property |
Value |
Name |
Verify
Smartcode |
Type |
PL/SQL
Function (returning Error text) |
PL/SQL Function |
declare VsmartCode varchar2(6); Verrortext varchar2(150); begin
select c001 into VsmartCode from apex_collections where collection_name = 'SMARTCODE'; if :P9999_VERIFYCODE != VsmartCode then Verrortext := 'The smartcode you have
entered is not correct. Please verify
it from your smartphone.'; end if; return rtrim(Verrortext); end; |
When Button Pressed |
ACCESS |
11.
Once the smart code is verified, the user is to be redirected to
the home page. For this, create a branch (under After Processing) using the following attributes.
Property |
Value |
Name |
Go
To Home Page |
Point |
After
Processing |
Type |
Page
or URL (Redirect) |
Target Type |
Page
in this application |
Page |
1 |
When Button Pressed |
ACCESS |
12. The validation and the branch you created in the previous two steps are associated with the ACCESS button. There are three default processes named Set Username Cookie, login, and Clear Page(s) Cache that execute when you press the Login button, which is not associated with these processes by default. Since we now have an additional button (ACCESS) whose Action property is also set to Submit Page, we need to set the When Button Pressed attribute of these three processes to LOGIN so that they execute only when the login button is pressed.
13. Finally, edit application properties. On the User Interface tab, click the Edit Desktop icon. Set Home URL to f?p=&APP_ID.:9999:&SESSION. to call the Login Page and override the default behavior. If you keep the default (f?p=&APP_ID.:1:&SESSION.) value, you will not see the smart code interface and the Home page (Page 1) will be displayed instead.
Save and run the page, which should look like the figure shown at the top of this post. The conventional login form appears to the right of the screen. Enter your credentials and hit the Sign In button. The text field item specified in step 3 will pop up. At the same time, you will get a six-digit code on your mobile device. Enter that code in the text field item to access the application home page.