BookmarkSubscribeRSS Feed

Connecting SAS Viya and IdentityServer by OpenID

Started ‎02-10-2021 by
Modified ‎02-10-2021 by
Views 6,180

It's common (really, required) to have a way to authenticate with your own application. By default SAS Viya uses LDAP or Active Directory. But what if you want to use another method, whether it be by choice or requirement? Consider the event where your company already has a configured authentication method for your apps. Utilizing these established tools can save you some time when managing users and their access.

 

IdentityServer is an open-source authentication server that implements OpenID Connect (OIDC). The IdentityServer is designed to provide a common way to authenticate requests to all your applications, whether they're web, native, mobile, or API endpoints. In this tutorial, we will interact with the IdentityServer using an ASP.NET API based application.

 

The objective here is to use IdentityServer4 (IDS4) as another way for users to log in on SAS Viya. We are going to install Identity Server on a Windows machine, while another Linux machine will be running SAS Viya on an SMP environment.

 

Below is a representation of the solution architecture.

 

Authentication flow between SAS Viya and IdentityServerAuthentication flow between SAS Viya and IdentityServer

 

To start, let’s install and configure the Identity Server. If you already have one, just skip to Step 2.

 

Step 1 – Setting up and configuring IdentityServer for SAS Viya

 

Clone the sas-viya-oidc repository from GitHub. The project contains a base installation of IdentityServer, with some SAS Viya configurations.

Open the code with Visual Studio IDE. You will need to edit the files Config.cs and Properties-> LaunchSettings, before executing the IdS.csproj on the Visual Studio ASP.NET project. Below are sample files with notes for the required edits.

 

Config.cs

           new TestUser
          {
            SubjectId = "sasdemo01",
            Username = "sasdemo01",
            Password = "sasdemo01",
            Claims =
            {
              new Claim(JwtClaimTypes.Name, "sas"),
              new Claim(JwtClaimTypes.GivenName, "demo"),
              new Claim(JwtClaimTypes.FamilyName, "sasdemo01"),
              new Claim(JwtClaimTypes.Email, "sasdemo01@email.com"),
new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
              new Claim(JwtClaimTypes.Role, "admin"),
new Claim(JwtClaimTypes.WebSite, "http://sasdemo.com"),
new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address),
                IdentityServerConstants.ClaimValueTypes.Json)
            }
          },

 

Code note: It’s important that the SubjectId matches the username on the SAS Viya LDAP. If you do not do that, SAS Viya throws an error indicating the user is not mapped when trying to log in.

 

Config.cs continued

        new Client
        {
          ClientId = "interactive",
   ClientSecrets = {new Secret("SuperSecretPassword".Sha256())},

          AllowedGrantTypes = GrantTypes.Code,
   RedirectUris =          {"https://10.0.0.19/SASLogon/login/callback/external_oauth"},
          FrontChannelLogoutUri = "https://10.0.0.19/SASLogon",
          PostLogoutRedirectUris = {"https://10.0.0.19/SASLogon"},

          AllowOfflineAccess = true,
          AllowedScopes = {"openid", "profile", "weatherapi.read"},
          RequirePkce = false,
          RequireConsent = true,
          AllowPlainTextPkce = false
        },

 

Code note 1: Define CliendId and ClientSecret with appropriate values. In this case, we will use "interactive" as ClientId and “SuperScretPassword” as ClientSecret. Keep in mind, you will use this information to configure SAS Viya integration with IDS4 during a later step.

 

Code note 2: It’s very important to set the RedirectUris parameter to the callback URL /SASLogon/login/callback/external_oauth endpoint; otherwise, the IdentityServer will not redirect correctly when you are logging in. In this example, overwrite 10.0.0.19 with your SAS Viya host or IP address.

 

LaunchSettings

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
/*Change localhost below to your client machine. You will need to create a self-signed certificate to IISExpress using your own host. Please check README on GitHub for detailed instructions */
      "applicationUrl": "http://localhost:10789",
      "sslPort": 44397
    }
  },

 

Code Note: Change "localhost" to your own client host.

 

As stated in the Launchsetting's code block, you need to create a self-signed certificate using your own host. The instructions for this are outlined in the GitHub repository associated with this article.

 

Prior to running the code using IIS Express, you'll need to install multiple required packages. In Visual Studio, select Tools-> NuGet Package Manager-> Package Manager Console.

 

Use NuGet Package Manager Console to intall dependenciesUse NuGet Package Manager Console to intall dependencies

 

In the Package manager Console (pictured above), enter the following commands to install the dependent packages:

Install-Package IdentityServer4.EntityFramework -Version 4.1.1
Install-Package IdentityServer4 -Version 4.1.1
Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore -Version 5.0.1
Install-Package Serilog -Version 2.10.0
Install-Package Serilog.Sinks.File -Version 4.1.0
Install-Package Serilog.Sinks.Console -Version 3.1.1
Install-Package IdentityServer4.AccessTokenValidation -Version 3.0.1

 

After making the code updates, creating the certificate, and installing the required dependencies, run the code using IIS Express on Visual Studio.

 

.NET-based web server IIS Express.NET-based web server IIS Express

 

After completing the installation and executing IIS Express, you should see this screen:

 

IdentityServer4 homeIdentityServer4 home

 

Access to all configurations of your IdentityServer4 are in this URL: https://idshost/.well-known/openid-configuration. Keep in mind you will use this webpage when configuring SAS Viya to connect with OpenID. Below is a representation of the configuration.

 

IdentityServer4 configurationIdentityServer4 configuration

 

After successfully installing and configuring IdentityServer, we perform some verification. Open a CMD or TERMINAL window and type this command:

curl -k -X POST "https://<<clienthost>>:44397/connect/token" -H "Content-Type: application/x-www-form-urlencoded" -H "Cache-Control: no-cache" -d "client_id=m2m.client&scope=weatherapi.read&client_secret=SuperSecretPassword&grant_type=client_credentials"

 

Below is a representation of the command and response.

 

Response token from Identity ServerResponse token from Identity Server

 

If you get a token as the response, your IdentityServer is configured and installed correctly and we are ready to move to the next step.

Note: If you are using a custom host, you will need to provide the --cacert /home/<user>/certname.crt option passing the certificate you created. If you want to see how to generate this certificate, check out README file in the Github project.

 

Step 2 – Configuring certificates between IdentityServer and SAS Viya

 

We are using a Windows machine for the IDS4 installed and a Linux machine for the SAS Viya SMP topology. Because we are using a custom host and a self-signed certificate for IdentityServer4, we need to configure CAS TLS to use our custom certificate from IdentityServer.

 

To do that, follow all the steps in the Encryption in SAS Viya 3.5: Data in Motion documentation, in the “Update Certificates and Configure TLS on CAS” topic (page 22 in the current version).

There are three main parts of the configuration:

  1. add certificates to the SAS Viya truststore
  2. configure TLS between the CAS client and CAS controllers
  3. add the root certificate to the client, in our case, the IDS4 Windows machine

 

To facilitate these steps, refer to the code samples below. Remember, if you want to learn how to create the .crt, .key or .pem certs, refer to the README on GitHub. In the code below, you will need to make changes to any reference of azureuser and certname to match your environment.

 

Add certificates to the SAS Viya truststore

# Add certificates to the SAS Viya truststore
cd /opt/sas/viya/config/etc/SASSecurityCertificateFramework/cacerts
cp /home/azureuser/certname.pem .
cp /home/azureuser/certname.crt .
sudo chown sas:sas certname.pem
sudo chown sas:sas certname.crt
sudo chmod 644 certname.pem
sudo chmod 644 certname.crt
. /opt/sas/viya/config/consul.conf
export CONSUL_HTTP_TOKEN=$(sudo cat /opt/sas/viya/config/etc/SASSecurityCertificateFramework/tokens/consul/default/client.token)
/opt/sas/viya/home/bin/sas-bootstrap-config kv write --key cacerts/certname --file /opt/sas/viya/config/etc/SASSecurityCertificateFramework/cacerts/certname.pem
/opt/sas/viya/home/bin/sas-bootstrap-config kv read cacerts/certname
cd /opt/sasinside/sas_viya_playbook/
ansible-playbook -i inventory.ini ./utility/rebuild-trust-stores.yml

 

 Configure TLS between the CAS client and CAS controllers

#Configure TLS between the CAS client and CAS controllers
sudo /etc/init.d/sas-viya-all-services stop
sudo /etc/init.d/sas-viya-all-services start
sudo systemctl stop sas-viya-cascontroller-default
cd /opt/sas/viya/config/etc/SASSecurityCertificateFramework/tls/certs/cas/shared/default
cp /home/azureuser/certname.crt .
cd /opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default
cp /home/azureuser/certname.key .
openssl rsa -aes128 -in /opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default/certname.key -out /opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default/certname_encrypted.key -passout pass:Orion123
chmod 644 certname_encrypted.key
chown cas:sas certname_encrypted.key
cd /opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default
sudo bash -c 'echo -n 'Orion123' > certname_encrypted.encryption.key'
sudo chown cas:sas certname_encrypted.encryption.key 
sudo chmod 0600 certname_encrypted.encryption.key
cd /opt/sas/viya/config/etc/cas/default
vi node_usermods.lua
env.CAS_CLIENT_SSL_REQUIRED=true
env.CAS_CLIENT_SSL_CERT='/opt/sas/viya/config/etc/SASSecurityCertificateFramework/tls/certs/cas/shared/default/certname.crt'
env.CAS_CLIENT_SSL_KEY='/opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default/certname_encrypted.key' 
env.CAS_CLIENT_SSL_KEYPWLOC ='/opt/sas/viya/config/etc/SASSecurityCertificateFramework/private/cas/shared/default/certname_encrypted.encryption.key'
sudo systemctl start sas-viya-cascontroller-default

 

Import CA Certificates into the Windows Trusted Root Certificate Authorities Store

 

Finally, add the root certificate and any intermediate certificates used to sign the IdentityServer certificate to the truststore on the client (on the Windows IdentityServer machine, in this case). For this last step it’s advisable to follow use the Windows MMC app outlined in the Encryption in SAS Viya 3.5: Data in Motion documentation. In this case, I used the Windows approach (currently found on page 79).

 

Step 3 – Configuring SAS Viya discovery for OIDC

 

Next, we need to configure Identity Provider (IdP) Discovery for OIDC. Navigate to SAS Environment Manager à Configuration à Definitions. Enter sas.logon in the search and select sas.logon.zone. In the configuration dialog box, click New Configuration and enable the idpDiscovery.enabled option.

 

SAS environment manager configuration – sas.logon.zoneSAS environment manager configuration – sas.logon.zone

 

This option allows us to login using e-mail address from IdentityServer.

 

The last step is to configure SAS Viya with Information about the OIDC IdP. Return to the Definitions list, select sas.logon.oauth.providers.external_oauth.

 

SAS environment manager configuration – sas.logon.oauth.provides.external_oauthSAS environment manager configuration – sas.logon.oauth.provides.external_oauth

 

In the New sas.logon.oauth.providers.external_oauth configuration dialog box, enter values for the required fields, based on your Identity Server: 

 

Configuration Field

Value used in this tutorial

Description

addShadowUserOnLogin

On

Specifies that a local shadow user should be added once authentication is successful. This field is required.

Note: This option should always be On.

attributeMapping.user_name

sub

Specifies the attribute from the Identity Server, which contains the username. This username should match with LDAP username in order to Viya be able to map the user.

authUrl

https://idshost:44397/connect/authorize

Specifies the URL for the authorization endpoint of the third-party. This field is required.

emailDomain

email.com

Specifies a comma-separated list of email domains of users that can sign on with this provider. It is used with IdP discovery. This field is optional.

issuer

https://idshost:44397

Specifies the principal that issued the token, specified as a case-sensitive string or URI. This value must match the issue claim in the token. This field is required.

linkText

Use your Identity Server credentials

Specifies the text that should be displayed on the sign-in page. This field is optional.

relyingPartyId

interactive

Specifies the client ID that is registered with the provider. This field is required.

relyingPartySecret

SuperSecretPassword

Specifies the secret that is registered with the provider for the client ID. This field is optional.

scopes

openid,profile,weatherapi.read

This option depends on what is defined for the attributeMapping.userName. The scope tells the provider what fields to get back from the provider. Depending on the provider, they might need to include a scope to get back the user name field. This field is required.

showLinkText

On

Specifies that the link text should be shown on the sign-in page. This field is required.

tokenKey

Empty

Specifies the HMAC key or RSA public key that is used to sign ID tokens. This field is optional.

Note: Specify either this value or the tokenKeyUrl, but not both.

tokenKeyUrl

https://idshost:44397/.well-known/openid-configuration/jwks

Specifies the URL to obtain the signing key. This field is optional.

Note: Specify either this value or the tokenKey, but not both.

tokenUrl

https://idshost:44397/connect/token

The URL to obtain tokens from the provider. This value is required.

type

oidc1.0

Specifies the protocol type. This field is required.

Note: SAS Viya requires an id_token in the authorization response from the provider. However, some providers return an id_token when the scope in the authorization request is openid and respose_type=token. For those providers, use type oauth2.0.

 

 

After making these changes, restart your SAS Logon service. From the SAS Viya server command line enter the following command:

sudo systemctl restart sas-viya-saslogon-default

 

For more information on authentication with SAS, please refer to the documentation.

 

The setup is now complete. You should be able to login on SAS Viya using your e-mail from your IdentityServer:

 

SAS LogonSAS Logon

 

You will be redirected to your identity server page to authenticate:

 

Identity Server 4 LogonIdentity Server 4 Logon

 

And you will be able to access on SAS Viya using your OpenId credentials from IdentityServer4:

 

SAS Drive landing pageSAS Drive landing page

 

Finally

 

As we saw, setting up communication between IdentityServer with SAS Viya is beneficial, especially if you already use Ids4 to authenticate your other applications. You will need to have a user mapped on your identity provider with the same name as in Ids to SAS Viya be able to map their permissions and get the authorization level; however, the password and all the others information about the user can still be managed by IdentityServer.

 

Hope this will help someone in the future and if you have any doubts about it, fell free to contact me or any contributors.

 

A huge thanks to:

@lumale , @joeFurbee , and Rachel Toledo

Comments

Great article, thanks for the effort assembling it @weyner !

Good article,

 

Would like to clarify some points.

 

1. This IdentityServer is like keycloak?

2. To confirm, the user used in the example above sasdemo01 resides in the IdentityServer and not in the LDAP? What will happen to the users who are in the LDAP and are found under Users in Environment manager but not in IdentityServer? I understand the SubjectID must match between the IdentityServer User and LDAP to be able to login. Does this mean all users in IdentityServer must be in LDAP and matches the name?

 

Thanks!

Great article!

We're trying to set up something similar too.

 

Do you know if there is an updated guide for sas.logon.oath.providers? (sas.logon.oath.providers.external_oauth is deprecated)

 

Thanks!

Version history
Last update:
‎02-10-2021 02:31 PM
Updated by:

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Tags