By: Adrian Png On: December 20, 2017 In: APEX Developer Solutions Comments: 12

The Security Assertion Markup Language 2.0 (SAML2) is an XML-based markup language and an open standard for identity and service providers to communicate authentication and authorization information. Software-as-a-Service (SaaS) providers like Oracle, Google, Microsoft and many others, use SAML2 for identifying and providing access to users. For example, if your organization is subscribed to Google’s G Suite, the same credential used to login to Gmail, can also seamlessly provide access to Slack.

There are many advantages to using Single Sign-on (SSO). The most obvious reason is that users do not have to maintain an excessive number of account credentials, thereby reducing password fatigue. It also provides a more productive user experience as application users can navigate seamlessly between systems without having to re-enter user ID and passwords. For IT managers, it simplifies the overall infrastructure and user management support. Additionally, using a matured user management system means avoiding the need to “reinvent the wheel” and repeated cycles of security testing. Last but not least, reputable Identity Providers (IdP) often offer extra features such as multi-factor authentication to further protect logins. These can sometimes be costly or time-consuming to implement.

No out-of-the-box solutions, but not to worry

There are currently no out-of-the-box solutions for authenticating Oracle Application Express (APEX) applications using SAML2. However, integrating this Single Sign-on technology doesn’t need to be hard. The following recipe will show you how.

⦁ Oracle Linux 7.4
⦁ Apache HTTP Server version 2.4 or later. In addition to the modules installed by the package manager, the following two modules must also be installed:
⦁ mod_auth_mellon
⦁ mod_ssl
⦁ Java EE application server, e.g. Oracle WebLogic, Apache Tomcat
⦁ Oracle Database 11g R2 or later
⦁ APEX version 4.2 or later

The ideal setup would look something like this:

Single sign-on ideal setup

A. Initial Setup and Installation of mod_auth_mellon

⦁ Install mod_auth_mellon using the package manager. On Oracle Linux 7.4:
$ yum install -y mod_auth_mellon
⦁ Create the directory /etc/httpd/mellon:
$ mkdir /etc/httpd/mellon
⦁ Set this as the current working directory:
$ cd /etc/httpd/mellon
⦁ Download the file mellon_create_metadata.sh, e.g:
$ wget https://raw.githubusercontent.com/UNINETT/mod_auth_mellon/master/mellon_create_metadata.sh
⦁ Make the file executable:
$ chmod a+x mellon_create_metadata.sh
⦁ Create the SAML2 metadata, by providing the Entity ID and Mellon endpoint. In the example, the domain is mysp.contoso.com. Replace this with an appropriate fully qualified domain name (FQDN) that is resolvable. Change the paths for the Entity ID and endpoint accordingly.
$ ./mellon_create_metadata.sh https://mysp.contoso.com/entityid https://mysp.contoso.com/myendpoint
Output files:
Private key: https_mysp.contoso.com_entityid.key
Certificate: https_mysp.contoso.com_entityid.cert
Metadata: https_mysp.contoso.com_entityid.xml
Host: mysp.contoso.com

SingleLogoutService: https://mysp.contoso.com/myendpoint/logout
AssertionConsumerService: https://mysp.contoso.com/myendpoint/postResponse

Note the inputs and outputs from the script creating the SAML2 metadata for your server.

The key information you will need:
⦁ Entity ID (https://mysp.contoso.com/entityid) – this is used to identify your SP to the IdP.
⦁ ACS URL (AssertionConsumerService, https://mysp.contoso.com/myendpoint/postResponse) – this is the callback when the IdP successfully identifies the user. The Service Provider (SP) is expected to know what URL to redirect the request to after successful authentication.
⦁ Logout URL – use this to terminate user sessions.

B. Configure the Identity Provider

The following provides instructions for configuring the service provider (SP) to use Google G Suite as the IdP. You must have access to the administrators’ console to continue. If this is not the case, please contact your administrator perform the configuration on your behalf.
⦁ Firstly, login to the G Suite administrators’ console and access (click) the organization’s Apps (see red arrow).

Easy Recipe to SAML2 Single Sign-on with Oracle Application Express- APEX

⦁ Secondly, select “SAML apps”.

Easy Recipe to SAML2 Single Sign-on with APEX

⦁ Thirdly, create a new SAML app association by clicking on the button on the bottom-right of the screen.

Easy Recipe to SAML2 Single Sign-on with Oracle Express

⦁ Then, Choose custom app, click “Setup my own custom app” at the bottom of the dialog.

Easy Recipe to SAML2 Single Sign-on with Oracle Application Express APEX

⦁ The IdP metadata file will be generated. (1) Download this file and upload to the web server’s directory for storing the Mellon metadata files, e.g. /etc/httpd/mellon/GoogleIDPMetadata-contoso.com.xml. (2) Click “Next” when this is done.

⦁ (1) Enter the application’s name, and (2) click next to continue

⦁ (1) Enter the ACS URL and EntityID obtained from Part A, Step 6
. (2) Click next to continue.

⦁ Click “Finish”. Attribute mappings can be done later if needed.

⦁ Verify that the SAML app was created successfully.

C. Update the Apache HTTP Server Configuration

⦁ Add the following to the Apache2 configuration file, e.g. /etc/httpd/conf.d/ssl.conf:
# Adds Mellon session information to all requests to the web server
MellonEnable "info"

# Use the filenames provided by the mellon_create_metadata.sh script
MellonSPPrivateKeyFile https_mysp.contoso.com_entityid.key
MellonSPCertFile https_mysp.contoso.com_entityid.cert
MellonSPMetadataFile https_mysp.contoso.com_entityid.xml

# Add the full path to the IdP metadata that was downloaded when
# configuring the IdP
MellonIdPMetadataFile /etc/httpd/mellon/GoogleIDPMetadata-myidp.com.xml

# The endpoint path used when generating the SP metadata
MellonEndpointPath /myendpoint

# Add the following line to enable Mellon for the ORDS path
MellonEnable "auth"
ProxyPreserveHost On
ProxyPass https://localhost:8443/ords/
ProxyPassReverse https://localhost:8443/ords/

# Google returns the username as the MELLON_NAME_ID.
# We can inject this to the proxied request (to ORDS) and use the header
# variable for sign on.
RequestHeader add X-APPUSER %{MELLON_NAME_ID}e

⦁ Restart the Apache service:
$ systemctl restart httpd

D. APEX Application Authentication

Create an authentication scheme using the HTTP Header Variable template. The variable name to use is based on what is injected by the reverse proxy.

Single sign-on - Authentication scheme

Specify the logout URL based on the values noted in section A. In addition to the URL, the parameter ReturnTo must also be specified. Finally, use the substitution parameter %POST_LOGOUT_URL%.

When a user signs out, the SP redirects to the IdP’s logout URL specified in the metadata before terminating the session on the service-side. Sessions on both ends must be terminated to prevent further access. Note that the IdP metadata from Google is missing the SingleLogoutService element and the following must be added to the IdP’s metadata file, after the element:

Security Considerations

We are reliant on the IdP to support the SAML Single Logout protocol. A user may initiate a sign out from either the IdP or SPs tied to the same session. If the IdP does not propagate the request, then there is a risk that the user will have continued access to your application. Therefore, most identity providers like Google and Microsoft, recommend that you close all browsers when you sign out.

Mellon’s default session length (see the configuration option MellonSessionLength) is one day. Therefore, consider reducing this value to mitigate this risk. When the Mellon session expires, it will reattempt to assert your identity. Users don’t need to reauthenticate if the IdP session remains valid.

Last but not least, as the approach uses APEX’s HTTP Header Authentication, it is critical to remember that no unauthorized user or system has direct access to the ORDS instance on the network. In the example above, it is expected that the server is hosted in a demilitarized zone (DMZ) and thus accessible by either the Internet or Intranet. If so, be doubly sure that the firewall is configured and running correctly. Only traffic to the reverse proxy ports (e.g. 443) should be permitted. It is also recommended that the application server hosting ORDS (e.g. Tomcat, WebLogic) be situated in a secured internal network that only system administrators have access to. And even so, these servers should permit HTTP/HTTPS requests only from the web proxy’s IP address and nowhere else. Failing which, a malicious actor could inject the appropriate HTTP Header variable and gain unauthorized access to the APEX applications and/or workspace!

See my Webinar on the fundamentals of identifying and managing access to APEX applications and components. It includes discussion of modern frameworks like OAuth2, SAML2, SCIM & more!


Finally, Download this pdf for additional information on enabling APEX SAML2 SSo with Microsoft Azure Active Directory (Office 365).

Share this:


    • May 28, 2020
    • Reply

    Hi Adrian,
    Great Article. I am really impressed with the your expertise and experience on the APEX.
    Above approach is applicable for Oracle APEX on-premises installation.
    I have a follow up question in regards to Oracle Apex Cloud Version.
    We are using Oracle APEX Cloud Version , it is deployed on OCI (Autonomous DB + APEX) so would you think we can make it work ?
    Appreciate any help/advise.

    Rajesh Vohra

      • Adrian Png
      • May 29, 2020
      • Reply

      Hi Rajesh,

      Thank you for your kind comments.

      Yes, you are correct. At the moment, this approach only works on-prem where you can place an Apache HTTP server as a gateway to APEX on the Autonomous Database. While there are “workarounds” to do that, I wouldn’t suggest them due to security concerns. Also, this approach requires that you block unauthorized access to ORDS.

      I would suggest using an intermediary to facilitate using OAuth2 instead. If you’d like we can chat over email.


      Best regards,

    • Tommy
    • July 17, 2020
    • Reply

    Hi Adrian,
    We have a new AWS platform setup like this: NGINX (web server) > JBoss (app server with ORDS) > Oracle RDS (APEX 20.1).
    All these servers and apps are in the VPN cloud. Our users are internal company staff.
    We need to implement the authentication scheme in our APEX apps. Platform team recommends SAML on NGINX and an architect recommends oAuth+OIDC on NGINX.
    First question is:
    is this doable with APEX 20.1 with a platform setup like this ours. If so, is there any document posts can give me some ideas how to start?
    Second questions is:
    Which option is better or is there any better alternative?

      • Adrian Png
      • July 20, 2020
      • Reply

      Hi Tommy,

      I would go with an OAuth2 approach for several reasons, however, it really depends on what you are using as an Identity Provider. What will you be using?

      Best regards,

        • Tommy
        • July 30, 2020
        • Reply

        a colleague shared this url to me and turns out I already seen it and commented on it 🙂
        got a few more questions:
        1. do we create generate the entityid and provide it to IDP?
        2. is endpoint same as our app url like https://mysp.contoso.com/ords/f?p=4550:1
        3. do you have instruction to configure this in NGINX?

          • Adrian Png
          • July 31, 2020
          • Reply

          Hi Tommy,

          1. The Entity ID is an arbitrary value and simply used to identify your service provider, i.e. APEX instance.
          2. Which endpoint are you referring to? The AssertionConsumerService endpoint is based on the value of MellonEndpointPath that you set in the Apache2 configuration file. The Mellon metadata helper script then generates the other endpoint URLs that you’ll need for the IdP configuration.
          3. I’m not aware of a similar approach with Nginx.

    • Bishal Malla
    • July 29, 2020
    • Reply

    Hi Adrian,
    I am new to oracle apex and I tried to implement SAML2 with Red Hat 6 using Microsoft Azure. However i keep on getting null username passed on the header variable. Is it something that i am doing wrong.
    I see under network tab the header is not getting generated. Could you please put some light on my problem.

    Best Regards,
    Bishal Malla

      • Adrian Png
      • July 31, 2020
      • Reply

      Hi Bishal,

      Did you follow the additional guide provided as a download on this page? Make sure the correct claims attribute is pulled and set in the headers in the Apache2 configuration file. You won’t be able to see the injected header from the browser. If you’d like to see what’s being sent, then create a temporary public page with a PL/SQL dynamic content region that calls the procedure owa_util.print_cgi_env. It will print out all the CGI variables, including the headers.

      Hope that helps.

      Best regards,

    • Tommy
    • July 31, 2020
    • Reply

    when the SAML response comes back to ACS URL /myendpoint/postResponse, how do we handle that? I cannot see your configuration actually use it.
    Could you please clarify?

      • Adrian Png
      • July 31, 2020
      • Reply

      What configuration are you referring to?

      The ACS URL is where the IdP redirects to after successful user authentication. It will provide information required by Mellon to then continue the identification workflow.

    • Tommy
    • August 01, 2020
    • Reply

    I cannot see any reference to ACS URL in step C. Update the Apache HTTP Server Configuration: /etc/httpd/conf.d/ssl.conf
    I try to understand how Mellon knows the ACS URL if it is not referenced directly in the ssl.conf.
    is the ACS URL in one of the xml files (metadata files)?
    sorry I must missed something.

      • Adrian Png
      • August 04, 2020
      • Reply

      In step A, you are asked to run the script mellon_create_metadata.sh. One of the parameters that you specify is the Mellon endpoint. This is the MellonPath that you specify in the Apache configuration file. The script generates the ACS URL for you. To my knowledge, this is not configurable and the final URL, as illustrated in the example, will always be composed of the Mellon path and /postResponse.

Leave reply:

Your email address will not be published. Required fields are marked *