In this post I want to explore some help I provided a customer who was using the SAS Fallback authentication module. More information on the Fallback Module can be found in in the Middle-Tier Admin Guide. This customer wanted to be able to access the SAS Logon Manager form after configuring Integrated Windows Authentication without having to go through the custom error page. I looked at the different options we could use to make this work.
A long time ago in a galaxy far, far away…
Well almost, back in the first maintenance release of SAS 9.4, SAS included the fallback authentication module. This module allows customers to have several different authentication mechanisms live and working for their middle-tier.
Remember: The mechanisms supported by the fallback module are only those mechanisms internal to the SAS Web Application Server. Yes you – that means SAML is not going to work with the fallback module. Confused – go read the manual.
The module was written for some specific customers – but there is a great use case for practically all sites wanting to use Integrated Windows Authentication (IWA) for the middle-tier. This use case is trying to access some of the Administration functions after the you have enabled IWA. With just vanilla IWA you must work through and add all required roles & capabilities to each end-user, since the internal accounts are no-longer going to work. However, with fallback, all you need to do is access the web application in a browser not configured for IWA and you will get presented with the normal SAS Logon Manager form. You can then manually log-in with the internal account.
Also using the fallback module makes the configuration of IWA much easier. When using the fallback module all you need to change in the web.xml for the SAS Logon Manager is to uncomment the custom error page for 401. This is the key to how the fallback module works.
Essentially, all the custom error page does is to redirect to the SAS Logon Manager with an additional parameter "fallback=true". Since browsers not configured for IWA display the custom 401 error page rather than sending a Kerberos token this means the non-IWA browser gets sent to the SAS Logon Manager with the parameter sent. For example a broswer not configured for IWA automatically redirects requests for SASAdmin to:
So for this customer they are testing accessing the web applications from a different browser and having difficulties. Some of this is specific to this customer, but many customers have Internet Explorer as their standard browser and when this is unable to do IWA it quite often attempts NTML before displaying the 401 error page. This means the browser pops-up a login box for the user to attempt to type credentials. Using the pop-up box will not work and so it confuses the users. So the customer wanted a simple approach to make using the fallback module easier.
Having sent a draft of these materials to others at SAS it was suggested rather than the novel approach below I should instead "Keep it simple, stupid". Since the SAS 9.4 Middle-Tier automatically provides for Single Sign-On (SSO) between the applications. Remember, once you’ve logged into the Middle-Tier from one browser session you can access any other application from the same browser session without having to log in again. So if the first page you visit is https://servername:port/SASLogon/login?fallback=true, you’ll immediately see the SAS Logon Manager form. After you have logged in with the form you can then just access any of the other SAS web applications and you’ll remain logged in. The only thing is that post logon you’ll need to type the URL of the other application you want to access. As Leonardo da Vinci would put it "Simplicity is the ultimate sophistication".
What about cases where the user does not necessarily want to type one URL, log in, and then type another URL. Could we have a simple URL the customer could use to access the fallback version of the SAS Logon Manager specific for the application they are trying to access?
So what I’d thought about doing was to just add something simple to the standard SAS web application URL and have this redirected by the SAS Web Server to the correct page. What I ended up using for my testing is just "fb" for fallback. So typing https://servername:port/fb/SASAdmin will get me access to the fallback version of the SAS Logon Manager even in a browser configured for IWA and then on logon redirect me to the correct application.
Now for my testing environment I have TLS configured for the SAS Web Server. So my changes might be slightly different to your attempts if you don’t have TLS configured. Since I have TLS configured I’m looking at the:
Whilst if you are working with a site where TLS is not configured you’d be looking at the:
Remember: When you deploy a SAS web application with the SAS Deployment Manager the sas.conf file will be recreated and any changes you make will need to be put back.
The mechanism we will use to take the URL containing "/fb/" and redirecting this back to the SAS Logon Manager is the Rewrite module. In either the httpd-ssl.conf or the sas.conf you will find the line:
We need to remove the comment "#" from this line to enable the Rewrite Engine. Then we can add our new Rule to rewrite the URL:
There are three main sections to the rewrite rule; the first is a Perl compatible Regular Expression which is applied to the URL-path of the request. The pattern "^/fb/(.*)" will match any URL the starts /fb/. Also everything after the second forward slash will be placed into a variable that can be used in the rest of the rule.
The second part is the substitution. This needs to include the SAS Web Server hostname and port to ensure the request is correctly resubmitted rather than just a redirect to a directory local to the SAS Web Server. Then we have the "/SASLogon/login?service" part of the URL we want to redirect to. To ensure the equals sign is correctly processed this is escaped with a backward slash so "\=". Then we have an encoded representation of the SAS Web Server hostname and port number, where "%3A" is a ":" and "%2F" is a "/". Next we have the part of the original URL with the "$1" and then finally the "j_spring_cas_security_check" and the all-important "&fallback=true".
The final part of the rule is a set of flags. Where we have the following:
If your SAS Web Server is not configured for TLS then you should use HTTP rather than HTTPS in your RewriteRule.
So with the rule in place I can access any of the SAS web applications at https://servername:port/fb/SASApplication and get the SAS Logon Manager form even if the browser is configured for IWA. Since the change is not impacting any other parts of the infrastructure and we’re using a standard URL once we get to the SAS Logon Manager it has no implications for using the applications.
Finally, if you want to get rid of the rule and are concerned that your users might have book marked the URL’s with "/fb/" in them just change the rule to the following:
This will just send any requests for https://servername:port/fb/SASApplication to https://servername:port/SASApplication.
Stuart Rogers
The RewriteRule works great except when the URL has a trailing slash, like https://example.com:8343/fb/SASStoredProcess/
The rule then translates the trailing / to // causing an error.
I added a RewriteRule for a URL that has a trailing slash, to run before the original rule:
RewriteRule "^/fb/(.*)/$" "https://%{SERVER_NAME}:%{SERVER_PORT}/SASLogon/login?service\=https\%3A\%2F\%2F%{SERVER_NAME}\%3A%{SERVER_PORT}\%2F$1\%2Fj_spring_cas_security_check&fallback=true" [B,NE,NC,R,L]
RewriteRule "^/fb/(.*)" "https://%{SERVER_NAME}:%{SERVER_PORT}/SASLogon/login?service\=https\%3A\%2F\%2F%{SERVER_NAME}\%3A%{SERVER_PORT}\%2F$1\%2Fj_spring_cas_security_check&fallback=true" [B,NE,NC,R,L]
it works better now for me.
I found that this does not work for direct links to reports, like:
https://example.com/SASVisualAnalyticsViewer/VisualAnalyticsViewer.jsp?reportName=MyFirstReport&reportPath=/Shared Data/Reports/&type=Report.BI§ion=vi1&appSwitcherDisabled=true&reportViewOnly=true&propertiesEnabled=false&commentsEnabled=false
The Rewrite Rule rewrites the URL to:
https://example.com/SASLogon/login?service=https%3A%2F%2Fexample.com%3A443%2FSASVisualAnalyticsViewer%2fVisualAnalyticsViewer%2ejsp%2Fj_spring_cas_security_check&fallback=true
Apart from the parameters that are not being passed, the callback is https://example.com:443/SASVisualAnalyticsViewer/VisualAnalyticsViewer.jsp/j_spring_cas_security_check
which does not exist and so gives a HTTP Status 404 – Not Found
Is there a solution for this?
Hello @bheinsius,
Thank you for taking the time to comment on the article. I'm sure the code to remove the trailing slash will be very helpful to others looking at this.
For the direct linking to reports as you've identified this does not work with the short-cut to provide fallback authentication. This is because the Apache HTTP rewrite rule is discarding the QUERY_STRING and just taking the URL. While you might be able to store the QUERY_STRING as part of the flow of rewrite rules I can't see a straight forward way of associating this back to the original request post-logon. So at best you would be able to access SASVisualAnalyticsViewer but you would not be able to directly link to the report through the rewrite rule.
A slight tweak to the regex for the comparison will enable either the trailing slash or sub-pages to be correctly rewritten to just the application name as the service parameter for SASLogon. Changing the rule to:
RewriteRule ^/fb/([^/]*). https://%{SERVER_NAME}:%{SERVER_PORT}/SASLogon/login?service\=https\%3A\%2F\%2F%{SERVER_NAME}\%3A%{SERVER_PORT}\%2F$1\%2Fj_spring_cas_security_check&fallback=true [B,NE,NC,R,L]
should then rewrite /fb/SASStoredProcess/ to /SASLogon/login?service=https%3A%2F%2F<<YOUR SERVER>>%3A<<YOUR PORT>>%2FSASStoredProcess%2Fj_spring_cas_security_check&fallback=true. Equally it will take:
https://example.com/SASVisualAnalyticsViewer/VisualAnalyticsViewer.jsp?reportName=MyFirstReport&reportPath=/Shared Data/Reports/&type=Report.BI§ion=vi1&appSwitcherDisabled=true&reportViewOnly=true&propertiesEnabled=false&commentsEnabled=false
and rewrite this to:
https://example.com/SASLogon/login?service=https%3A%2F%2Fexample.com%2FSASVisualAnalyticsViewer%2Fj_spring_cas_security_check&fallback=true
Which would enable your users to leverage fallback authentication to access the SAS Visual Analytics Viewer, but as mentioned before would not enable direct linking to reports.
Thank you
Stuart
Hi @StuartRogers,
Thanks I updated the rule.
I still received prompts for credentials in my browser within SAS VA, when switching between the VA apps, like from hub to designer. I asked SAS and the reason seams to be that switching always goes through SASLogon and there the /fb/ is not in the URL and also cannot be inserted. So the prompts appear again.
SAS said the browser sends the request to the SAS Server. The SAS Server replies with 401 and header WWW-Authenticate: Negotiate. For a browser within the same domain, and the right security settings, it means start Kerberos ticket exchange, and SSO will work as planned. However when a user is outside a domain, the browser does not allow Kerberos. It will try NTLM, and that is why the prompt shows up.
SAS suggested a workaround, to add the following lines to sas.conf that take out the WWW-Authenticate:negotiate from the HTTP header for certain IP ranges where you know that SSO will not work, so it will not be attempted:
<IfModule setenvif_module> SetEnvIf Remote_Addr (192.168.240.*) IS_customerx Header unset WWW-Authenticate env=IS_customerx </IfModule>
And that works.
Note that sas.conf is regenerated when (re)deploying the webapps, for instance after hotfix installation, so this change would need to be redone after (re)deploying them.
Hi @StuartRogers and @bheinsius
Our customer same need direct linking to reports. If we have additional way ?
If I will added this module:
<IfModule setenvif_module>
SetEnvIf Remote_Addr (192.168.240.*) IS_customerx
Header unset WWW-Authenticate env=IS_customerx
</IfModule>
this remove all tickets and we got error 401 in SAS Content Server.
Regards,
Alexei
Hello @AlexeiN,
First just a reminder that the Remote_Addr value should be matching just those clients that are unable to perform Kerberos authentication. If those same clients need to have direct access to SAS Content Server then you can just update the block to unset the environment variable "IS_customerx" when the requested URI includes "SASContentServer". So it would become:
<IfModule setenvif_module> SetEnvIf Remote_Addr (192.168.240.*) IS_customerx SetEnvIf Request_URI "^/SASContentServer/.*" !IS_customerx Header unset WWW-Authenticate env=IS_customerx </IfModule>
With this in place you can access SAS Content Server in the browser from a matching IP address and the BASIC authentication prompt will still be presented.
Alternatively, you could change the "Header unset" line to make it conditional on only matching requests to SASLogon:
<IfModule setenvif_module> SetEnvIf Remote_Addr (192.168.240.*) IS_customerx=1 Header unset WWW-Authenticate "expr=%{REQUEST_URI} =~ m#^/SASLogon/.*# && env('IS_customerx') = 1" </IfModule>
This would also allow you to browse SAS Content Server from one of the matching IP addresses, since the header will only be unset if the request is to SAS Logon Manager.
Thank you for your time.
Stuart
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.