Le code qui suit reprend celui de mon article précédent pour y ajouter la lecture des rôles et sa mise à disposition dans une application asp.net.
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
// Récupération du cookie d'authentification
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = application.Request.Cookies[cookieName];
// Si cookie != null
if (authCookie != null)
{
// lecture du cookie d'authetification asp.net
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// Lecture des roles de l'utilisateur, depuis le cookie d'authentification
string[] roles = authTicket.UserData.Split(new char[] { '|' });
// Création d'un principal pour l'application
FormsIdentity identity = new FormsIdentity(authTicket);
GenericPrincipal principal = new GenericPrincipal(identity, roles);
// attach the principal to tue context objet that will flow throughout the request.
application.Context.User = principal;
}
else
{
/**
* jouons avec cas
**/
// lecture du ticket dans la requête http
string casTicket = application.Request.QueryString["ticket"];
string service = application.Request.Url.GetLeftPart(UriPartial.Path);
// le ticket est vide : étape 2 du protocole, redirection vers le serveur CAS
if (casTicket == null || casTicket.Length == 0)
{
// mémorisation de la demande initiale dans un cookie
application.Response.Cookies[ReturnUrl].Value = application.Request.Path;
// redirection vers le serveur CAS
string redir = cashost + "login?" + "service=" + service;
application.Response.Redirect(redir);
return;
}
else
// Retour de l'authentification cas : étape 6 du protocole
{
// vérification du ticket auprès du serveur CAS
string validateurl = cashost + "serviceValidate?" + "ticket=" + casTicket + "&" + "service=" + service;
WebClient client = new WebClient();
StreamReader Reader = new StreamReader(client.OpenRead(validateurl));
// Put the validation response in a string
string resp = Reader.ReadToEnd();
string netid = null; // logon utilisé à récupérer dans la balise user de resp
reader.Close();
// En principe redirection vers la page demandé
if (netid == null)
{
application.Response.Write("Votre identité n'a pas été validé par le serveur CAS");
// TODO: Renvoi vers une erreur 500 ou autre le serveur CAS est HS ou usurpation
}
else
{
application.Response.Write("Bienvenue " + netid);
// Lecture des roles de l'utilisateur, il suffit remplacer le tableau par du code
// qui retourne un tableau de string
string[] roles = new string[] { "role1", "role2" };
// Création du ticket d'authentification cas
FormsAuthenticationTicket formAuthTicket = new
FormsAuthenticationTicket(
1, // version
netid, // user name
DateTime.Now, // creation
DateTime.Now.AddMinutes(20), // expiration
false, // persistant
String.Join("|", roles)); // userData
// encryptage du ticket
string encryptedTicket = FormsAuthentication.Encrypt(formAuthTicket);
// création du cookie d'authentification
authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
// ajout du cookie dans le flux de réponse
application.Response.Cookies.Add(authCookie);
// redirection vers la page demandé
string returnUrl;
// Si jamais on perd l'url de retour, renvoie vers la racine du site
if (application.Request.Cookies[ReturnUrl] == null)
returnUrl = application.Request.ApplicationPath;
else
returnUrl = application.Request.Cookies[ReturnUrl].Value;
application.Response.Redirect(returnUrl);
}
}
}
}