Pages enfant
  • Retour de l'URN sur mise en place de CAS 6.0.4

Vous regardez une version antérieure (v. /wiki/display/CAS/Retour+de+l%27URN+sur+mise+en+place+de+CAS+6.0.4) de cette page.

afficher les différences afficher l'historique de la page

« Afficher la version précédente Vous regardez la version actuelle de cette page. (v. 5) afficher la version suivante »

Contexte

Eté 2019, l'Université de Rouen Normandie a procédé à une montée de version de son service d'authentification CAS en 6.0.4, nous partageons sur cet espace notre expérience.

Le Kit installation CAS V5.2 AMU (un grand merci Grégory et Dominique pour ce partage) a permis d'avoir un CAS v5.2.7 qui fonctionne rapidement et comprenant les éléments principaux.

On a ensuite affiné certaines configurations.

ClearPass

Ajout du clearPass qui fonctionne avec le esup-filemanager 3.2.0 - pour gérer le domaine windows, petite modification qui a depuis été intégrée :
https://github.com/uPortal-contrib/esup-filemanager/pull/58

RememberMe

Ajout du rememberme en ne laissant la case affichée que pour les mobiles.A
Dans notre surcharge du footer.html on ajoute le bloc thymeleaf/javascript suivant : 

<script type="text/javascript" th:unless="${#request.getAttribute('isMobile')}">
if(document.getElementById("rememberMe")) {
 document.getElementById("rememberMe").parentNode.style.display = "none";
}
</script>

Throttle

Modification du throttle en mettant :

cas.authn.throttle.failure.range-seconds=30
cas.authn.throttle.failure.threshold=12

Aussi sur un espace de 10 secondes (10=30/3), l'utilisateur est 'banni' à la 4ème tentative (12/3=4).

Spnego / Kerberos

Nous avons activé spnego + kerberos avec notre AD Microsoft

A noter que si l'authentification Spnego échoue (PC qui n'est pas dans le domaine ou navigateur non configuré), CAS renvoie le formulaire avec une réponse HTTP 401.

Firefox affiche alors la page de formulaire proposée, mais IE et Chrome réagissent différemment : suite au 401 ils affichent d'abord une popup d'authentifcation BASIC, en cliquant sur cancel (annuler) l'utilisateur arrive bien sur le formulaire d'authentifcation CAS mais ce comportement n'est malgré tout pas souhaitable.

Nous avons donc activé spnego uniquement pour les navigateurs Firefox :

cas.authn.spnego.supportedBrowsers=Firefox

Concernant la mise en place de spnego, il faut suivre la documentation très bien faite ici : 

https://apereo.github.io/cas/6.0.x/installation/SPNEGO-Authentication.html

On note que la création d'un compte AD pour le Service Principal Name consiste à créer un compte AD usuel et à appeler dans un powershell exécuté en tant qu'administrateur (domain-account est le nom du compte, à l'URN on a préféré prendre un nom type cas-krb) : 

Setspn -s HTTP/cas.example.com domain-account

On note également que dans cette commande précédente ainsi que dans celle-ci : 

ktpass /out myspnaccount.keytab /princ HTTP/cas.example.com@REALM /pass * /mapuser domain-account@YOUR.REALM

cas.example.com (cad cas) pointe corrrespond au nom de machine et non à un alias. C'est une erreur récurrente dans la mise en place de kerberos.
A l'URN on a donc non pas saisi cas.univ-rouen.fr mais cast.univ-rouen.fr dans ces lignes de commande (cast étant le nom de machine hébergeant notre CAS : cf "host cas.univ-rouen.fr").

Agimus

On a patché (et proposé ces patchs par PR) de cas-server-support-agimus-logs et cas-server-support-agimus-cookie pour qu'ils supportent CAS en 6.0.x : 

Endpoints

En 6.0.x, CAS propose d'utiliser les endpoints à la spring-boot pour interagir avec CAS, en bref, CAS propose par ce biais des API REST. 

Ces possibilités sont notamment décrites ici : https://apereo.github.io/2018/11/06/cas6-admin-endpoints-security/

A l'URN, on a activé ces endpoints pour notre application de gestion de comptes, afin qu'elle puisse demander à CAS d'expirer les tickets de comptes compromis.

management.endpoints.web.exposure.include=*
management.endpoints.enabled-by-default=true
cas.monitor.endpoints.endpoint.defaults.access=IP_ADDRESS
cas.monitor.endpoints.endpoint.defaults.requiredIpAddresses=10.0.0.22,127.0.0.1

On a implémenté la destruction des sessions CAS d'un utilisateur ainsi depuis notre application de gestion de comptes (java/spring) : 

public class CasService {
	
	protected Logger log = Logger.getLogger(CasService.class);
	
	RestTemplate restTemplate;
	
	String casSsoSessionsUrl;
	
	String casDestroySsoSessionsUrl;
	
	public void setRestTemplate(RestTemplate restTemplate) {
		this.restTemplate = restTemplate;
	}

	public void setCasUrl(String casUrl) {
		casSsoSessionsUrl = casUrl + "/actuator/ssoSessions?type=ALL";
		casDestroySsoSessionsUrl = casUrl + "/actuator/ssoSessions/{ticketGrantingTicket}";
	}

	public synchronized String destroySsoSessions(String login) {	
		String message = "";
		CasSsoSessions casSsoSessions = restTemplate.getForObject(casSsoSessionsUrl, CasSsoSessions.class);
		for(CasSsoSession casSsoSession : casSsoSessions.activeSsoSessions) {
			if(login.equals(casSsoSession.principal)) {
				log.info(String.format("Call Cas Destroy ticket %s for user %s", casSsoSession.principal, casSsoSession.ticketGrantingTicket));
				Map<String, String> urlVariables = new HashMap<String, String>();
				urlVariables.put("ticketGrantingTicket", casSsoSession.ticketGrantingTicket);
				CasSsoSessionDestroyResponse casSsoSessionDestroyResponse = restTemplate.postForObject(casDestroySsoSessionsUrl, null, CasSsoSessionDestroyResponse.class, urlVariables);
				log.info(String.format("CAS response : %s",  casSsoSessionDestroyResponse.toString()));
				message += casSsoSessionDestroyResponse.toString() + "\n";
			}
		}
		return message;
	}
	
}

Tickets Registry

Sans doute la partie qui devrait intéresser le plus les membres du Groupe de Travail Authentification.

Cf ci-dessus, on souhaite proposer à nos utilisateurs la possibilité de conserveur leur session CAS sous mobile durant 2 semaines (14 jours, soit 1209600 secondes). Sans rememberme de demandé, on propose une conservation de session CAS comme donné par défaut : cad 8 heures (28800 secondes).

Celà correspond à mettre en oeuvre le remember-me ou long term authentication tel que décrit ici :

https://apereo.github.io/cas/6.0.x/installation/Configuring-LongTerm-Authentication.html

Le TGT est alors conservé pendant 2 semaines ... et un TGT prend une certaine place ce qui fait dire que le ticket registry, c'est à dire le méanisme de persistence des tickets, doit permettre une telle persistence.

Ainsi la documentation donnée ci-dessus indique :

A security policy that requires that long term authentication sessions MUST NOT be terminated prior to their natural expiration would mandate a ticket registry component that provides for durable storage, such as the JPA Ticket Registry.

Nous nous sommes donc dans un premier temps dirigé vers l'usage d'un ticket registry jpa, en utilsiant postgresql que nous affectionnons particulièrement.

En test nous n'avons pas eu à nous en plaindre, en production le choix de JPA s'est avéré très  problématique, cf ci-dessous.

JPA (PostgreSql)

Rien à signaler sur la configuration avec JPA et Postgresql.

Pour implémenter ce que nous souhaitons faire, nous avons mis les propriétés suivantes pour les temps de conservation des tickets :

cas.ticket.tgt.maxTimeToLiveInSeconds=28800
cas.ticket.tgt.timeToKillInSeconds=28800
cas.ticket.tgt.rememberMe.timeToKillInSeconds=1209600

Passé en production, nous avons constaté que  :

  • chaque TGT prenait beaucoup de place, celà nous a conforté dans un premier temps aux choix de JPA et donc de la base de données pour la persistence des tickets
  • la base de données ne faisait qu'augmenter ... et donc la purge des tickets ne se faisait vraissemblablement pas correctement - cf 

Redis


Misc

Via des versions à jour de spring-boot et spring-security, CAS en 6.0.x amène l'usage des dernières technologies web, notamment en matière de sécurité (csp, xss, csrf, xsrf ...) et de protocole (chunked transfer encoding).

Notre migration depuis un CAS 4 a ainsi posé problèmes à 2 applications.

Iframe

Ainsi l'authentification d'une de nos applications ne fonctionnait plus après le passage sur notre nouveau CAS car celle-ci intègre le CAS dans une iframe. En attendant de corriger celà côté de l'application, on a ajusté (temporairement donc) la chose pour que ça passe à nouveau : suppression de l'entête http X-Frame-Options en positionnant simplement la règle suivante sur notre Apache qui fait office de proxy avec notre Tocmat CAS :

Header unset X-Frame-Options

Chunked transfer encoding

On conserve à l'URN une version ancienne 2.x.y de notre webmail SOGo (en plus de la nouvelle version SOgo 4 qui n'a posé aucun problème avec le nouveau CAS) qui est cassifié.

Cf https://sogo.nu/bugs/view.php?id=2408&nbn=22 cette version est sensible aux réponses CAS et s'attend à avoir dans son sialoguqe ProxyCAS, une réponse HTTP proposant simplement le contenu XML avec un Content-Length correspondant.

Ici, le nouveau CAS utilise maintenant le 'Chunked transfer encoding' qui n'est pas du tout apprécié par cette ancienne version de SOGo ; pour continuer de faire fonctionner le proxy-cas avec ce vieux SOGo (en fin de vie à l'URN malgré tout), on a reproduit un proxy (cgi python sur el apache de CAS) spécifique pour ce SOGo pour l'accès aux urls CAS en /proxy et /serviceValidate : 

#!/usr/bin/python                                                                                                                                                                             

import os
import cgi
import urllib2

def pageget(url):
    req = urllib2.Request(url)
    rep = urllib2.urlopen(req)
    data = rep.read()
    return data

if __name__ == '__main__':
     url = os.environ["REQUEST_URI"]
     content = pageget('https://cas.univ-ville.fr' + url)
     print "Status: 200"
     print "Content-Length: " + str(len(content)+1)
     print
     print content












...

  • Aucune étiquette