CASifying non-ASP.NET applications on IIS 7+

While the .NET CAS Client was designed with ASP.NET WebForms and ASP.NET MVC applications in mind, it turns out that it is also possible to CASify other types of applications running on top of IIS 7.0/7.5.

CASifying PHP 5.x + FastCGI applications

PHP CAS Client

This procedure isn't intended to be an alternative to the PHP CAS client. The intent is simply to show that the CasAuthenticationModule, FormsAuthenticationModule, and UrlAuthorizationModules can work on platforms other than ASP.NET on IIS 7+. I would generally only recommend this approach for clients who have ASP.NET and PHP applications co-existing on the same IIS 7+ web server. The only reason I am CASifying a PHP application here is because it's the non-.NET language that I'm most familiar with.

  • For Vista/Windows 2008, install the FastCGI extension for IIS 7.  For Windows 2008R2/Windows 7, you simply need to enable the CGI feature in the Programs and Features window in the control panel.
  • Create a directory on your machine for an example application (i.e., C:\inetpub\wwwroot\phptest).
  • Either create an Application mapping in IIS for that directory or convert the directory to an Application.  Make sure that the AppPool that you select is running in Integrated Pipeline mode.
  • If you don't have the .NET CAS Client installed in the Global Assembly Cache (GAC), create a Bin directory below that directory and copy the DotNetCasClient.dll there.  Otherwise you can skip this step.
  • If you haven't already done so, download PHP and install/extract it to C:\php (or wherever you prefer).
  • Grant php-cgi.exe and php5ts.dll read+execute permissions for the user associated with the default app pool (IUSR or Everyone if you're in a rush).
  • If you don't already have a php.ini, copy php.ini-development or php.ini-production to php.ini and open it in your favorite text editor.  Apply/uncomment the following settings:
    • cgi.force_redirect = 0
    • cgi.fix_pathinfo = 1
    • fastcgi.impersonate = 1
  • If you have not installed PHP+FastCGI on your entire server or on the entire web site, you can enable it for this path only by adding a Handler Mapping:
    • Path: *.php
    • Script Processor: c:\php\php5-cgi.exe (or wherever yours is)
    • Module: FastCgiModule (Don't see it?  Did you install FastCGI & enable CGI in Control Panel, Add/Remove Programs/Features/whatever your OS calls it)
    • Verb: *
    • Name: PHP
  • Edit the Default Documents to include index.php as a valid default document.
  • Create index.php at the root of the application (c:\inetpub\wwwroot\phptest\index.php) with the following contents <?php phpinfo(); ?>
  • Browse to http://yourserver/phptest/ and confirm that the PHP Info page is rendering correctly.
  • If it is, it's time to add CAS support.  Otherwise, Google is your friend.
  • In IIS, navigate to your application and double click on the Modules feature.
  • Double click on 'FormsAuthentication' and uncheck the option that says "Invoke only for requests to ASP.NET applications or managed handlers", hit OK
  • Double click on 'UrlAuthorization' and uncheck the same option, hit OK. 
  • Now edit the web.config in that directory.  The changes that you made in the IIS Manager should be reflected in the web.config.  
  • Configure CAS just as you would with any other ASP.NET application.  I'll include a sample configuration file to get you started.  Pay special attention to the 'path' parameter in the FormsAuthentication tag.  It should match the virtual directory of the app in IIS (i.e., /phptest/)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <configSections>
    <section name="casClientConfig" type="DotNetCasClient.Configuration.CasClientConfiguration, DotNetCasClient" />
  </configSections>
  <casClientConfig
    casServerLoginUrl="https://cas.server.edu/cas/login"
    casServerUrlPrefix="https://cas.server.edu/cas/"
    serverName="app.server.edu"
    notAuthorizedUrl="~/NotAuthorized.php"
    cookiesRequiredUrl="~/CookiesRequired.php"
    redirectAfterValidation="true"
    gateway="false"
    renew="false"
    singleSignOut="false"
    ticketTimeTolerance="5000"
    ticketValidatorName="Cas20"
    proxyTicketManager="CacheProxyTicketManager"
    serviceTicketManager="CacheServiceTicketManager"
    gatewayStatusCookieName="CasGatewayStatus" />
  <system.web>
    <authentication mode="Forms">
      <forms
        loginUrl="https://cas.server.edu/cas/login"
        timeout="30"
        defaultUrl="~/index.php"
        cookieless="UseCookies"
        slidingExpiration="true"
        path="/phptest/" />
    </authentication>
    <authorization>
      <deny users="?" />
    </authorization>
    <httpModules>
      <add name="DotNetCasClient" type="DotNetCasClient.CasAuthenticationModule,DotNetCasClient" />
    </httpModules>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
      <remove name="UrlAuthorization" />
      <remove name="FormsAuthentication" />
      <remove name="DotNetCasClient" />
      <add name="DotNetCasClient" type="DotNetCasClient.CasAuthenticationModule,DotNetCasClient" />
      <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="" />
      <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
    </modules>
    <handlers>
      <add name="PHP" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="c:\php\php-cgi.exe" resourceType="Unspecified" />
    </handlers>
    <defaultDocument>
      <files>
        <add value="index.php" />
      </files>
    </defaultDocument>
  </system.webServer>
</configuration>
  • Test your application again. You should be redirected to the CAS server to login (because of system.web/authorization/deny[users=?|users=?]). Upon successful login, you will be redirected back to the PHP Info page.
  • Notice that in PHP-land, $_SERVER["AUTH_TYPE"], $_SERVER["LOGON_USER"], $_SERVER["REMOTE_USER"], $_ENV["AUTH_USER"], $_ENV["LOGON_USER"], and $_ENV["REMOTE_USER"] are all set to the username the you logged in to CAS with. Also, $_SERVER["AUTH_TYPE"] and $_ENV["AUTH_TYPE"] are set to 'Jasig CAS'. The $_SERVER["AUTH_PASSWORD"] and $_ENV["AUTH_PASSWORD"] are null.

Whether this effectively CASifies third party PHP applications or not depends on their implementation of authentication. It's possible that the applications are using the session or a cookie or something and aren't respecting the AUTH_USER information, but it's probably a configuration option or at least a straightforward hack to get it working.

More details & screenshots to follow.  I just wanted to write what I did before I forgot the procedure. Please direct any questions/comments to the CAS-DEV list.