Implementing JWT for Secure User Authentication in Oracle APEX

Implementing JWT for Secure User Authentication in Oracle APEX

ยท

4 min read

In a previous article, we have already discussed how to use the apex_jwt package for generating and validating JWT tokens, as well as accessing RESTful resources delegated by ORDS. In this article, we will walk you through the process of using a JWT token to authenticate a user to access an APEX application.

Why use JWT as an authentication method for your applications?

Using JSON Web Tokens (JWTs) as an authentication method has become increasingly popular among businesses and academics. JWTs are particularly favored for distributed systems, stateless applications, and when scalability is a concern. This is due to their ability to accommodate various applications, such as facilitating single sign-on (SSO) across disparate platforms. Businesses and academics can improve security and enhance their overall system performance by leveraging the advantages mentioned above.

Prerequisites

All you need to follow along with this example is an Oracle APEX account.

Setting up

To get started with this demo, we need to first create a new application (or you can use an existing app) in our APEX workspace. So go ahead and create a new application, then navigate to the Shared Components in the application you created, and finally go to Authentication Schemes.

Task1: Create a new authentication scheme

In the authentication schemes, create a new one and select it based on a pre-configured scheme option. Give the new scheme the name "JWT," for example, and set the scheme type to "custom". In the sentry function name, write JWT; we will create this function later in the SQL Workshop.

๐Ÿ’ก The sentry function is executed by the Oracle APEX engine at the start of any request made to the engine, such as before each page is shown or processed, or an AJAX request is issued.

Task2: Create the Sentry function

To create the sentry function, navigate to the SQL Workshop in your Workspace and then go to the Object Browser. On the left side, right-click on functions and create a new function, give the name 'JWT', and paste the following code.

create or replace function JWT return boolean
is
    v_x01      VARCHAR2(32767);
    l_jwt      APEX_JWT.T_TOKEN;
    l_jwt_user VARCHAR2(255);
begin

    -- get the token from the url
    v_x01 := v('APP_AJAX_X01');

    -- check if the token has the jwt format xxx.xxx.xxx
    if v_x01 like '%.%.%' then
        -- decode the token
        l_jwt := apex_jwt.decode (
                    p_value         => v_x01,
                    p_signature_key => sys.utl_raw.cast_to_raw('secretKey') );
        -- validate the token using the same issuer and audience values 
        -- used to encrypt the token
        apex_jwt.validate (
            p_token => l_jwt,
            p_iss   => 'TokenProvider',
            p_aud   => 'Admins' );

        -- parse the payload 
        apex_json.parse (
            p_source => l_jwt.payload );
        -- get the username from the payload
        l_jwt_user := apex_json.get_varchar2('sub');
    end if;

    -- if the user is not logged in
    if apex_authentication.is_public_user then
        -- if the token does not contain username
        if l_jwt_user is not null then
            apex_authentication.post_login (
                p_username => l_jwt_user );
        else
            return false;
        end if;

    -- if the logged in user != the username in the token
    elsif apex_application.g_user <> l_jwt_user then
        return false;
    end if;

    return true;

    exception when others then
        apex_debug.trace('---error---: %s', sqlerrm);

end JWT;
/

Task3: Generate the JWT token and use it to access your application

The final step involves generating a JWT token and using it to access the created application. Make sure to use the same issuer, audience, and signature key when generating the token.

In this demo, we will use jwt.io to generate the token. You can use any other JWT generator or use your authentication server or identity provider.

Navigate to jwt.io and fill in the following parameters:

The "sub" parameter represents the username that will be used to log in to the application.

Copy the generated encoded token; we will use it in a moment.

Task4: login to APEX

We will pass the token to the URL using the APEX_AJAX_X01 parameter.

๐Ÿ’ก You can read more about the APEX URL syntax. You will find a link in the references section.

https://<hostname>/pls/apex/r/<workspace>/<applicatin name>/<page alias>?x01=<token>.

Replace the placeholders with the appropriate values, paste the URL in your browser, and hit enter. You should then log in directly to your application.

Conclusion

JWT (JSON Web Tokens) is a popular method for authenticating users due to several advantages it offers, such as Statelessness, Flexibility and Versatility, and Cross-Domain Usage.

However, it's important to note that while JWTs offer these advantages, their security relies heavily on how they are implemented. Mishandling or improper implementation of JWTs, such as weak key management or not validating signatures correctly, can lead to security vulnerabilities like token leakage or tampering. Therefore, using JWTs for authentication requires careful consideration of best practices and security measures.

References

ย