Implementação do CAS

Ideia de implementação da versão antiga do CAS

Princípio central (protocolo CAS 1.0)

  1. O usuário acessa a página protegida /admin/admin.aspx
  2. A configuração de permissões do web.config bloqueia usuários anônimos e redireciona automaticamente para a página de login CasEnter.aspx
  3. CasEnter.aspx verifica se existe o parâmetro ticket na URL
  • Sem ticket: redireciona para o endereço de login do servidor CAS, enviando o endereço do site atual no parâmetro service
  • Com ticket: chama a API serviceValidate para validar o billete no servidor CAS
  1. O CAS retorna um XML, o nome de usuário logado é extraído do conteúdo
  2. Após validação bem‑sucedida, executa FormsAuthentication.SetAuthCookie() para gravar o billete local do Forms e redireciona para a página alvo
  3. Nas próximas requisições aos diretórios protegidos, o ASP.NET Forms reconhece o estado de autenticação

Configuração do web.config

<system.web>
  <authentication mode="Forms">
    <!-- loginUrl aponta para CasEnter.aspx como página intermediária de entrada do 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 o diretório admin para bloquear acesso anônimo -->
<location path="admin">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>Code language: HTML, XML (xml)

Servidores CAS mais novos forçam HTTPS por padrão, o campo casUrl deve ser preenchido com https://127.0.0.1:8443/cas/

<appSettings>
  <!-- Endereço da nova versão CAS7 com barra no final -->
  <add key="casUrl" value="https://127.0.0.1:8443/cas/"/>
</appSettings>Code language: HTML, XML (xml)

Código da página CasEnter.aspx

1. CasEnter.aspx código frontend
<%@ 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>Login intermediário do 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">Refazer autenticação</asp:HyperLink>
        </div>
    </form>
</body>
</html>Code language: HTML, XML (xml)
2. CasEnter.aspx.cs lógica de backend


Interface atualizada para CAS3.0 p3/serviceValidate
Adicionado HttpClient para substituir o WebClient obsoleto

Adicionado suporte a certificados autoassinados (obrigatório para testes locais com o CAS novo)
Tratamento de namespace para o XML retornado pelo 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);

        // Sem billete, redireciona para página de login do CAS
        if (string.IsNullOrEmpty(ticket))
        {
            string redirectUrl = $"{casHost}login?service={Uri.EscapeDataString(service)}";
            Response.Redirect(redirectUrl);
            return;
        }

        // Validar o ticket
        string username = ValidateTicket(casHost, ticket, service);
        if (string.IsNullOrEmpty(username))
        {
            Label1.Text = "Desculpe! A autenticação do CAS falhou, tente novamente.";
            HyperLink1.NavigateUrl = Request.Url.AbsolutePath;
        }
        else
        {
            // Gravar billete de autenticação Forms e concluir login local
            FormsAuthentication.SetAuthCookie(username, false);
            // Redirecionar para a página alvo
            Response.Redirect(FormsAuthentication.DefaultUrl);
        }
    }

    /// <summary>
    /// Validação de billete com CAS3.0 p3/serviceValidate
    /// </summary>
    private string ValidateTicket(string casHost, string ticket, string service)
    {
        // Versões novas do CAS recomendam p3/serviceValidate (protocolo CAS3.0)
        string validateUrl = $"{casHost}p3/serviceValidate?ticket={Uri.EscapeDataString(ticket)}&service={Uri.EscapeDataString(service)}";

        // Apenas para teste local: permitir certificados SSL não confiáveis (remova em ambiente de produção!)
        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);
        // Namespace do XML retornado pelo CAS3
        nsMgr.AddNamespace("cas", "http://www.yale.edu/tp/cas");

        // Localizar nó do usuário
        XmlNode userNode = doc.SelectSingleNode("//cas:authenticationSuccess/cas:user", nsMgr);
        return userNode?.InnerText;
    }
}Code language: HTML, XML (xml)

Implementação do CAS

Previous:

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *