Idea de implementación de la versión antigua de CAS
Principio fundamental (protocolo CAS 1.0)
- El usuario accede a la página protegida
/admin/admin.aspx - La configuración de permisos de
web.configbloquea usuarios anónimos y redirige automáticamente a la página de inicio de sesiónCasEnter.aspx CasEnter.aspxcomprueba si la URL contiene el parámetroticket
- Sin ticket: redirige a la dirección de inicio de sesión del servidor CAS y envía la dirección actual del sitio como valor
service - Con ticket: llama a la interfaz
serviceValidatepara validar el billete contra el servidor CAS
- CAS devuelve XML, se extrae el nombre de usuario autenticado
- Tras una validación correcta, se invoca
FormsAuthentication.SetAuthCookie()para generar el billete local de Forms y se redirige a la página destino - En accesos posteriores a directorios protegidos, ASP.NET Forms detecta el estado de la sesión
Configuración de web.config
<system.web>
<authentication mode="Forms">
<!-- loginUrl apunta a CasEnter.aspx como página de entrada intermediaria de CAS -->
<forms loginUrl="CasEnter.aspx"
defaultUrl="admin/admin.aspx"
name=".LoginFormsTicket"
path="/"
timeout="40"
protection="All">
</forms>
</authentication>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
<!-- Restringe el directorio admin para impedir accesos anónimos -->
<location path="admin">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>Lenguaje del código: HTML, XML (xml)
Los servidores CAS modernos fuerzan HTTPS por defecto,
casUrldebe completarse conhttps://127.0.0.1:8443/cas/
<appSettings>
<!-- Dirección de la nueva versión CAS7 con barra final -->
<add key="casUrl" value="https://127.0.0.1:8443/cas/"/>
</appSettings>Lenguaje del código: HTML, XML (xml)
Código de la página CasEnter.aspx
1. CasEnter.aspx parte frontal
<%@ 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>Inicio de sesión intermediario CAS</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"></asp:Label><br />
<asp:HyperLink ID="HyperLink1" runat="server">Volver a autenticar</asp:HyperLink>
</div>
</form>
</body>
</html>Lenguaje del código: HTML, XML (xml)
2. CasEnter.aspx.cs lógica backend
Interfaz actualizada a CAS3.0 p3/serviceValidate
Se agrega HttpClient para reemplazar el obsoleto WebClient
Se añade compatibilidad con certificados autofirmados (imprescindible para pruebas locales con CAS moderno)
Gestión del espacio de nombres para el XML devuelto por CAS
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);
// Sin billete, redirige a la página de inicio de sesión de CAS
if (string.IsNullOrEmpty(ticket))
{
string redirectUrl = $"{casHost}login?service={Uri.EscapeDataString(service)}";
Response.Redirect(redirectUrl);
return;
}
// Validar ticket
string username = ValidateTicket(casHost, ticket, service);
if (string.IsNullOrEmpty(username))
{
Label1.Text = "¡Lo sentimos! Falló la autenticación CAS, inténtelo de nuevo.";
HyperLink1.NavigateUrl = Request.Url.AbsolutePath;
}
else
{
// Generar billete de autenticación Forms y completar inicio de sesión local
FormsAuthentication.SetAuthCookie(username, false);
// Redirigir a la página destino
Response.Redirect(FormsAuthentication.DefaultUrl);
}
}
/// <summary>
/// Validación de billete mediante CAS3.0 p3/serviceValidate
/// </summary>
private string ValidateTicket(string casHost, string ticket, string service)
{
// Las versiones nuevas de CAS recomiendan p3/serviceValidate (protocolo CAS3.0)
string validateUrl = $"{casHost}p3/serviceValidate?ticket={Uri.EscapeDataString(ticket)}&service={Uri.EscapeDataString(service)}";
// Solo para pruebas locales: permitir certificados SSL no confiables (eliminar en producción!)
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);
// Espacio de nombres del XML devuelto por CAS3
nsMgr.AddNamespace("cas", "http://www.yale.edu/tp/cas");
// Buscar nodo de usuario
XmlNode userNode = doc.SelectSingleNode("//cas:authenticationSuccess/cas:user", nsMgr);
return userNode?.InnerText;
}
}Lenguaje del código: HTML, XML (xml)
Implementación de CAS
Previous: Instalación