Sunday, March 8, 2020

Custom Authentication Scheme Part1

In this post, we will walk through creating a Custom Authentication Scheme in Apex, what are the advantages of using a custom Authentication scheme and when to use the default scheme which is created by default with each new application.

When you create a new Apex application, it comes with a default Authentication scheme. This authentication scheme used to establish the identity of each user who accesses your application, the default authentication scheme requires that a user has an Apex account (Application Express Accounts are user accounts that are created within and managed in the Oracle Application Express user repository. Those accounts can be created by workspace admins in the apex workspace panel or using plsql API).
The user then should provide his user name and password if he wants to use your application, these credentials are evaluated and they either pass or fail, if the credentials pass, the user has access to the application. Otherwise, access is denied.
You use this authentication scheme and the Application Express Accounts if your applications do not require special requirements and if the users' accounts can only be created or managed by the workspace admins.
On the other hand, if you, for example, want your user's account to have more attributes or if you want to implement registration/reset password functionality into your applications to give the public-users who have an account the ability to reset the passwords or even create a new account. Then it is much better to use a custom authentication scheme and custom user account based on your requirements. In this case, you will have full control over the authentication scheme and the user's table, and you are responsible for defining the user's role, handling password strength/expiration.
Another advantage of using a custom Scheme based on custom users table is when you have many workspaces, then your users will be shared across all the workspaces.

When you create an authentication scheme, you have the option of choosing from several pre-configured authentication schemes, copying an authentication scheme from an existing application, or creating your own custom authentication scheme.
In this article, we will create one from scratch. But before that, we have to create a users' table where we will save the accounts information.
In this example, we will just implement a username and email in addition to the password.
For creating the table you can use the code below
Now we want to add a user to the users' table, before that we want to draw your attention that we should not save the user's password in plain text, it is not recommended for security and privacy reasons. So we will hash the password and save it in hashed form, to do this we have two options, we can hash the password in the Apex application before the page is been submitted when we create a user or when the user registers, in this approach we have to include this process in all of our applications. The second option is to create a trigger that will be triggered automatically each time we insert a new user into the users' table. Because the trigger is based on the table, we don't have to rewrite the code each time we create an application in apex.
Later when we implement update user password functionality (In part2), we will need to hash the password again (when a user changes his password). So let's make the encryption reusable by creating a function and call it anywhere we need it.
Notice the upper and the lower functions, we want to standardize our data so all the user names are in upper case and the emails are in lower case.
Now we create a trigger which runs before insert and calls the encryption function
let's insert the user now
Once we have created the table we can now start creating the authentication functions. The authentication function accepts two parameters username and password. It will first check if the user exists in the users' table. If the user does not exist in the user's table, the function will return false and the login is denied otherwise if the user exists, it will compare the user's saved password with the one which the function has received if they match, the function returns true and the user will log in otherwise it returns false and the login is denied.
we almost have done with building the backend, well the plsql part, and we will now start implementing what we did in Apex. The first step is to create a new Application, we will name it Custom Auth
Next, go to SQL Workshop and navigate to SQL Scripts
Click on Create and paste the "create users table" script, give it a name then click Run (we can actually upload a script file which includes all our code and run it, but we want to create everything step by step)
After you see the success message, go back to SQL scripts and create a new script, paste the "encryption function" script give it a name and click run
Now to create the trigger and inserting the user we will create a new script, just do the same steps and paste the "create trigger" code and the "insert user" code
You should now see one user in your users' table
Again go to SQL scripts and run "create Auth function" script

Now navigate to the application we have created, go to shared components then go to Authentication schemes
Click on Create button it will open a wizard for creating an Authentication scheme, in the first step choose the option "based on the pre-configured scheme", click next
in the next step, give the Authentication scheme a name, and choose the scheme type custom it will show now many fields, in the Authentication Function Name field write your Auth function which you have created and click Create
Now run your application and log in using the user which we have inserted in our users' table if everything were successfully you will be redirected to the Home page.

so that's it, we hope you enjoyed and you learned something :), feel free to ask us if you run into any issue.
In the next post, we will implement the remember me functionality so our users will authenticate themself just once and if they close the browser and later open it again, they will automatically log in, and we will create a page where our users can register or update/reset there password.


Labels: , ,


At March 10, 2020 at 4:24 AM , Blogger Gaspar said...

Good job at describing the process and the how-to.
Can I suggest you do the same for an app in which the clients register and the admin eventually accepts/decline the new account?

Kind of like those sites that you need to be approved prior to accessing the site?


At March 10, 2020 at 8:33 AM , Blogger fadiz said...

it's possible when I run application its show home page without authentication
when I click on login button then show login region then I putt username and password then login with back to the home screen?

At March 18, 2020 at 2:15 AM , Blogger Francisco Pérez said...

Excellent article. Very detailed and explained in a simple way. We are implementing an application where the user self-registers. What links do you recommend in this case. When would I publish client authentication part 2. Thank you so much. regards

At March 21, 2020 at 6:17 PM , Blogger Mohamad Bouchi said...

Hi Gaspar and thank you for your suggestion, I really like the Idea and I will work on this maybe in the part2 or part3 of this series

At March 23, 2020 at 2:21 PM , Blogger Timo said...

Hey Fadiz, sorry for the delay! Of course it is possible ;-)
On your Home Page you have to set under "Security > Authentication" the Atrribute "Page is Public" instead of "Page requires Authentication".
Then you need a Login Button with the Target to the Login Page (Page 9999).
Cheers Timo

At March 23, 2020 at 2:24 PM , Blogger Timo said...

Hey Francisco,
thank´s for the feedback :-)
I think the next post will be "Custom Authentication Part 2".
Maybe next Week or the week after. Keep your eyes open :-)

At June 23, 2020 at 10:03 AM , Anonymous Anonymous said...

Hi, I've been trying your method but I get the ORA-04070: invalid trigger name error when it comes to the create trigger and insert user sql script. I have asked a question about this in stackoverflow as well. Can you help?

At March 10, 2021 at 7:57 PM , Anonymous Anonymous said...

Hi, who is part 2 ?

At March 10, 2021 at 8:00 PM , Anonymous Anonymous said...

Please can you post the next step?

At March 11, 2021 at 8:10 AM , Blogger Timo said...

Hey, here is Part 2 -->


Post a Comment

Note: Only a member of this blog may post a comment.

Subscribe to Post Comments [Atom]

<< Home