SAS 9.4 has supported authenticating users of web applications through the SAS Web Server for quite some time. In this post I want to describe how authentication occurs at a high level and provide some details of the basic steps. Then in future posts we’ll look at how this feature can be used to allow modern web authentication protocols such as OpenID Connect alongside SAS 9.4.
So, to start with what exactly do we mean when we use the term SAS 9.4 Web Server Authentication. It means that we are going to configure SAS Logon Manager to trust that users have been authenticated elsewhere. SAS Logon Manager will accept a given username from the party doing the authentication and establish a session for that user in the SAS 9.4 web applications. The party doing the authentication will be the SAS Web Server.
The SAS Web Server is based on the standard Apache HTTP Server and any authentication modules created for Apache HTTP Server can be used in this scenario. That authentication module will be responsible for the authentication event. That could be by processing local files, submitting information to database, or interacting with OIDC or SAML Identity Providers.
The key part is that the Apache HTTP Server authentication module should provide an authenticated username to the SAS Web Server. The SAS Web Server is then configured to include this authenticated username on the requests of SAS Logon Manager. SAS Logon Manager is equally configured to accept the forwarded authenticated username and establish a session for the user. To establish the session, the authenticated username must match a login defined against a Metadata identity.
What is to stop a bad actor from submitting a username to gain access? To prevent this, we need to share a secret between the two parties, so between the SAS Web Server and SAS Web Application Server. Then we will only accept an authenticated username from a party that is also able to provide the shared secret.
Before we move forward with looking at how these parts are configured, we do need to point out a major impact of using SAS Web Server Authentication. Namely, that there will be no credentials made available to SAS 9.4 for launching a SAS Workspace Server session. As such, we need to provide credentials in an alternative way. We could configure SAS Token Authentication for the SAS Workspace Server. Or we could store a credential in an authentication domain.
There are four distinct segments to the configuration of SAS Web Server Authentication. We need to:
Select the image to see a larger version.
Mobile users: To view the image, select the "Full" version at the bottom of the page.
In this post we will not focus too much attention on the authentication module setup in the SAS Web Server. We will address this is future posts, when we look at modern authentication with SAML and OpenID Connect. At this point we will just stress that everything we configure in the SAS Web Server must be scoped to only impact requests to the login endpoint of SAS Logon Manager. We do not want authentication or anything else to occur on requests to the other SAS 9.4 web applications.
So, all the configuration changes we make to the SAS Web Server will be made inside a location block. This allows us to limit the scope of the enclosed directives by URL. At the simplest this will be:
<Location /SASLogon/login>
AuthType authentication_type
require valid-user
</Location>
Which file we add this to will depend on how we have configured the SAS Web Server. If the SAS Web Server is only serving HTTP, then we edit the SAS-configuration-directory\Levn\Web\WebServer\conf\httpd.conf file. Whereas, if we are serving HTTPS, we edit the SAS-configuration-directory\Levn\Web\WebServer\conf\extra\httpd-ssl.conf file, and add the location block inside the VirtualHost directive.
In step 2 we need to be able to send the authenticated username from the SAS Web Server to the SAS Web Application Server. As we’ve stated above, we don’t want to include this on all requests, we just want to insert the username on requests to the login endpoint of SAS Logon Manager. So, we need to add something to the location block that will send the authenticated username to the SAS Web Application Server.
When we authenticate the user, the module in the SAS Web Server must set the REMOTE_USER environment variable. We want to add this as a header to the requests to the login endpoint for SAS Logon Manager. But how we do this is slightly different if we are using HTTP or HTTPS for the SAS Web Server. When we use HTTP, we need to add the following:
<Location /SASLogon/login>
AuthType authentication_type
require valid-user
RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1,NS]
RequestHeader set X-Remote-User "%{RU}e" env=RU
</Location>
These lines turn on the rewrite engine so that the subsequent rewrite lines will work. The rewrite condition uses look-aheads which perform an internal (URL-based) sub-request to determine the final value of variable. This can be used to access variable for rewriting, which is not available at the current stage, but will be set in a later phase. For instance, to rewrite according to the REMOTE_USER variable from within the per-server context (httpd.conf file) you must use %{LA-U:REMOTE_USER} - this variable is set by the authorization phases, which come after the URL translation phase (during which mod_rewrite operates).
The dot and the hyphen in the rewrite rule match any URI containing at least one character, but the hyphen means do not change the URL. Then the rewrite rule sets the environment variable RU (Remote User) to the value of the first backreference %1 from the preceding rewrite condition. The NS means no sub request; this ensures the rule is skipped if the request is an internal sub request.
However, if we have configured the SAS Web Server to use HTTPS we just need to add:
<Location /SASLogon/login>
AuthType authentication_type
require valid-user
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
Since we are using mod_ssl to provide the TLS implementation in the SAS Web Server we don’t need the look-ahead that was used in the HTTP version. Also, this is using the SSL environment variable hence the lower-case s following the REMOTE_USER.
To ensure the SAS Web Server is trusted to send the authenticated username to the SAS Web Application Server we will share a secret with both parties. Then if the request does not contain the shared secret, it will be ignored. On the SAS Web Server we will insert the shared secret as an authentication header added to the request. Then on the SAS Web Application Server we encrypt the shared secret and insert it into a properties file so it can be validated when a request is received.
For the authentication header in the SAS Web Server, we need to take our shared secret and Base64-encode it. Strictly speaking the string, we encode is username:password, but the username can be blank. If the username is blank, then the colon delimiter must be included. We can use an online tool to base64-encode our string. If we use "Th1sISth3P@ssw0rd" as the shared secret, then we encode ":Th1sISth3P@ssw0rd". Using https://www.base64encode.org/ we get: OlRoMXNJU3RoM1BAc3N3MHJk. So, we add to the location block another request header line, giving us, in the HTTPS case:
<Location /SASLogon/login>
AuthType authentication_type
require valid-user
RequestHeader set X-Remote-User %{REMOTE_USER}s
RequestHeader set Authorization "Basic OlRoMXNJU3RoM1BAc3N3MHJk"
</Location>
With the shared secret set on the SAS Web Server, we now need to provide the same string to the SAS Web Application Server. This needs to be encrypted and added to the SAS-config-directory\Levn\Web\WebAppServer\SASServern_m\conf\catalina.properties file. The mechanism to encrypt the string has changed for different versions of SAS 9.4, check the documentation for older releases. With the current release on UNIX, we run the following from within the SAS Web Application Server directory SAS-config-directory/Levn/Web/WebAppServer/SASServern_m /bin:
cd SAS-config-directory/Levn/Web/WebAppServer/SASServern_m/bin
export JAVA_HOME=SAS-home-directory/SASHome/SASPrivateJavaRuntimeEnvironment/9.4/jre
export CATALINA_HOME=SAS-home-directory/SASWebApplicationServer/9.4/
apache-tomcat-10.1.35
./decoder.sh -encode -config sasmtr01 -pwf SAS-configuration-directory/Levn/Web/
WebAppServer/SASServern_m/conf/secure.file -v value-to-encrypt
While on Windows we run:
cd SAS-config-directory/Levn/Web/WebAppServer/SASServern_m/bin
export JAVA_HOME=SAS-home-directory/SASHome/SASPrivateJavaRuntimeEnvironment/9.4/jre
export CATALINA_HOME=SAS-home-directory/SASWebApplicationServer/9.4/
apache-tomcat-10.1.35
.\decoder.bat -encode -config sasmtr01 -pwf SAS-config-directory\Levn\Web\
WebAppServer\SASServern_m\conf\secure.file -v value-to-encrypt
The encrypted string that you obtain is then added as a property to the SAS-config-directory\Levn\Web\WebAppServer\SASServern_m\conf\catalina.properties file as follows:
pw.sas.valve.PrincipalFromRequestHeadersValve=sasmtr01:encoded_password
The string must be added to at least every instance of the SAS Web Application Server where SAS Logon Manager is running. This completes providing the shared secret to the SAS Web Server and SAS Web Application Server.
The final part of the configuration is updating the SAS Web Application Server to include the SAS provided security module. This module with extract the authenticated username from the request header sent from the SAS Web Server. SAS Web Application Server uses Tomcat valve configuration to do this. Valves perform actions that are inserted into the request processing pipeline for the Catalina container. The valve pulls the user ID out of an HTTP request header to create a principal and sets the user ID in the request that is sent to the SAS Logon Manager. This is done by configuring the com.sas.vfabrictcsvr.authenticator.PrincipalFromRequestHeadersValve class.
To configure the module, we add the following valve configuration to the SAS-home-directory\SASWebInfrastructurePlatform\9.4\Static\wars\sas.svcs.logon\META-INF\context.xml file:
<Valve className="com.sas.vfabrictcsvr.authenticator.PrincipalFromRequestHeadersValve"
secretPassword="${pw.sas.valve.PrincipalFromRequestHeadersValve}"
uriPattern = "/SASLogon/login.*$" fallThrough = "true" />
Notice the secretPassword property references the encrypted shared secret that we just added.
As an alternative to updating the context.xml file, you can edit the SASLogon.xml deployed file for the SAS Web Application Server that contains the SAS Logon web application. It is located here: SAS-configuration-directory\Levn\Web\WebAppServer\SASServern_m\conf\Catalina\localhost\SASLogon.xml. This avoids the need to rebuild and redeploy the application, but you must make sure that your changes are not overwritten if the application is redeployed at a later date.
For the changes to the SAS Web Server and SAS Web Application Server to be picked up we need to restart both components. Also, if you chose to only edit the context.xml you will need to rebuild and redeploy the web applications. Then we can look at attempting to authenticate using the module in the SAS Web Server.
If you want to isolate the SAS Web Server authentication module you can eliminate this and just validate the link between SAS Web Server and SAS Web Application Server. As such, you would edit the location block to:
<Location /SASLogon/login>
# Removed for testing
# AuthType authentication_type
# require valid-user
# Removed for testing
# RequestHeader set X-Remote-User %{REMOTE_USER}s
# Added fixed username
RequestHeader set X-Remote-User "sasdemo"
RequestHeader set Authorization "Basic OlRoMXNJU3RoM1BAc3N3MHJk"
</Location>
Here, we have commented the authentication lines and the initial request header line. The request header line we have then added merely sets the X-Remote-User header to the fixed string of a valid username. After restarting the SAS Web Server, you should be able to access SAS Logon Manager and see that you are authenticated as the username you provided. If this does not occur, then it points to a problem with the shared secret.
Alternatively, you could eliminate the shared secret part of the configuration to test just the authentication in the SAS Web Server. For this, you will need to edit the SAS Web Server configuration to comment out the request header line setting the authorization header. Also, you need to update the SAS Web Application Server configuration to remove the secretPassword from the Principal from Request Headers valve. Here you are better off editing the SAS-configuration-directory\Levn\Web\WebAppServer\SASServern_m\conf\Catalina\localhost\SASLogon.xml file, so you don’t have to rebuild and redeploy the web applications. With the shared secret eliminated you can validate that the SAS Web Server authenticates and correctly sends the authenticated username to SAS Logon Manager. However, after validating authentication you should re-establish the shared secret.
In this post we’ve presented the main steps for configuring SAS Web Server authentication. From this you can see there are some core steps that must be completed irrespective of the authentication module used in the SAS Web Server. Presenting the information this way allows us to focus in future posts on using either OpenID Connect or SAML to authenticate with our Microsoft Entra ID accounts.
Remember, users authenticating to the SAS 9.4 web applications with this method will not have a cached credential to launch a SAS Workspace Server session. You will need to look at alternative configuration to allow you users to launch a session.
If you want to explore this topic in more detail a workshop is available in learn.sas.com called SAS® 9.4 Advanced Topics in Authentication – Modern Web Authentication. This workshop includes both video information and hands-on practice sessions.
Find more articles from SAS Global Enablement and Learning here.
Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.
Explore Now →The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.