CAS Implementation

Implementation Idea of Legacy CAS Version

Core Principle (CAS 1.0 Protocol)

  1. User accesses protected page /admin/admin.aspx
  2. web.config permission rules block anonymous users and auto‑redirect to login page CasEnter.aspx
  3. CasEnter.aspx checks whether the URL contains the ticket query parameter
  • No ticket: Redirect to CAS server login endpoint and pass current site address as service
  • Ticket present: Call serviceValidate API to validate ticket against CAS server
  1. CAS responds with XML; parse out logged‑in username
  2. Upon successful validation, invoke FormsAuthentication.SetAuthCookie() to issue local Forms auth ticket and redirect to target page
  3. Subsequent requests to protected directories rely on ASP.NET Forms for login state recognition

web.config Configuration

<system.web>
  <authentication mode="Forms">
    <!-- loginUrl points to CasEnter.aspx as CAS entry relay page -->
    <forms loginUrl="CasEnter.aspx" 
           defaultUrl="admin/admin.aspx" 
           name=".LoginFormsTicket" 
           path="/" 
           timeout="40" 
           protection="All">
    </forms>
  </authentication>
  <authorization>
    <allow users="*"/>
  </authorization>
</system.web>

<!-- Restrict admin directory, deny anonymous access -->
<location path="admin">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>Code language: HTML, XML (xml)

Modern CAS server enforces HTTPS by default. casUrl must be set to https://127.0.0.1:8443/cas/

<appSettings>
  <!-- Address for CAS‑7 with trailing slash -->
  <add key="casUrl" value="https://127.0.0.1:8443/cas/"/>
</appSettings>Code language: HTML, XML (xml)

CasEnter.aspx Page Source

1. CasEnter.aspx Markup
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CasEnter.aspx.cs" Inherits="CasStudy.Web.CasEnter" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>CAS Relay Login</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server"></asp:Label><br />
            <asp:HyperLink ID="HyperLink1" runat="server">Re‑Authenticate</asp:HyperLink>
        </div>
    </form>
</body>
</html>Code language: HTML, XML (xml)
2. CasEnter.aspx.cs Code‑Behind


API upgraded to CAS3.0 p3/serviceValidate
Replaced deprecated WebClient with HttpClient

Added self‑signed certificate compatibility (mandatory for local testing against modern CAS)
Namespace handling for CAS‑returned XML

using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Xml;
using System.Web.Security;

public partial class CasEnter : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string casHost = ConfigurationManager.AppSettings["casUrl"];
        string ticket = Request.QueryString["ticket"];
        string service = Request.Url.GetLeftPart(UriPartial.Path);

        // No ticket, redirect to CAS login page
        if (string.IsNullOrEmpty(ticket))
        {
            string redirectUrl = $"{casHost}login?service={Uri.EscapeDataString(service)}";
            Response.Redirect(redirectUrl);
            return;
        }

        // Validate ticket
        string username = ValidateTicket(casHost, ticket, service);
        if (string.IsNullOrEmpty(username))
        {
            Label1.Text = "Sorry, CAS authentication failed. Please try again.";
            HyperLink1.NavigateUrl = Request.Url.AbsolutePath;
        }
        else
        {
            // Issue Forms authentication ticket for local sign‑in
            FormsAuthentication.SetAuthCookie(username, false);
            // Redirect to target page
            Response.Redirect(FormsAuthentication.DefaultUrl);
        }
    }

    /// <summary>
    /// CAS3.0 p3/serviceValidate ticket validation
    /// </summary>
    private string ValidateTicket(string casHost, string ticket, string service)
    {
        // Modern CAS recommends p3/serviceValidate (CAS3.0 protocol)
        string validateUrl = $"{casHost}p3/serviceValidate?ticket={Uri.EscapeDataString(ticket)}&service={Uri.EscapeDataString(service)}";

        // Local test only: allow untrusted SSL certificates (remove in production!)
        ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, err) => true;

        using var httpClient = new HttpClient();
        string xml = httpClient.GetStringAsync(validateUrl).Result;

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);
        XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
        // CAS3 response XML namespace
        nsMgr.AddNamespace("cas", "http://www.yale.edu/tp/cas");

        // Locate user node
        XmlNode userNode = doc.SelectSingleNode("//cas:authenticationSuccess/cas:user", nsMgr);
        return userNode?.InnerText;
    }
}Code language: HTML, XML (xml)

CAS Implementation

Previous:

Leave a Reply

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