CAS (Centrale Authenticatie Service): voor ontwikkelaars

CAS (Centrale Authenticatie Service): voor ontwikkelaars

Intro

CAS is de Centrale Authenticatie Service van Universiteit Gent. Via CAS kan u zich op verschillende UGent-webpagina's aanmelden met uw account.

Indien u zelf webtoepassingen ontwikkelt waarbij u gebruikers dient te authentificeren, kunt u in deze toepassingen gebruik maken van CAS. CAS biedt naast Single Sign-On ook Single Sign-Out en kan ook meer dan enkel de loginnaam teruggeven aan uw webtoepassingen.

Tip: op de CAS (Centrale Authenticatie Service): introductie-pagina leest u het antwoord op vragen als "Wat is CAS?", Wat is centrale login?", "Hoe lang blijf ik aangemeld?", "Hoe kan ik afmelden?".

Werking CAS

Uw webtoepassing brengt de gebruiker naar de CAS login pagina.

Voorbeeld:

https://login.ugent.be/login?service=https://login.ugent.be/cas-java-demo

Na authenticatie redirect CAS de gebruiker naar de oorspronkelijke webtoepassing, die via de url als service parameter werd meegegeven. Indien de gebruiker ingelogd is in een andere webtoepassing, krijgt de gebruiker geen login pagina meer te zien. (= Single Sign-On)

Voor Single Sign-Out stuurt CAS een POST request naar alle toepassingen waar de gebruiker ingelogd is.

CAS kan uitgetest worden aan de hand van onderstaande instructies. Opmerkingen over CAS of de webauth compatibiliteitsmodule stuurt u naar login@UGent.be.

Een CAS client opzetten

Registratie is vereist. U vult het volgende in:

  1. de url van uw webtoepassing
  2. een korte omschrijving van de webtoepassing
  3. de gewenste attributen

URL

CAS gebruikt de url van uw webtoepassing om de service parameter te vergelijken met geregistreerde webtoepassingen. Als in meerdere pagina's van een webtoepassing een CAS redirect voorkomt, kunt u de hoofd url doorgeven gevolgd door 2 *-en (= wildcards). Let hierbij op voor toepassingen die onder eenzelfde domein draaien.

https://foo.UGent.be/bar/**

Attributen (optioneel)

Standaard wordt de loginnaam (uid) teruggeven. Op aanvraag zijn ook volgende LDAP attributen mogelijk:

  • mail
  • department
  • givenname
  • surname
  • objectClass
  • lastenrolled
  • jobcategory
  • addressingtitle
  • extcategory
  • ugentID
  • faculty

U kunt op deze manier LDAP attributen opvragen zonder in uw toepassing de UGent LDAP aan te spreken. Naargelang de noden van de toepassingen kan de lijst aangepast worden.

Gebruik CAS enkel voor authenticatie en niet voor session management. Session management dient u te voorzien in uw webtoepassing. Zorg ervoor dat er na een succesvolle authenticatie bijgehouden wordt dat de gebruiker geauthenticeerd is.

Voorbeelden voor gebruikers

Voorbeelden in php

Opmerking

Indien u problemen ondervindt bij het updaten van uw systeem is het aangewezen een update van de CAS client te doen.

Vereisten

PHP 4.2.2+

  • −with-curl
  • −with-openssl
  • −with-dom
  • −with-zlib

Algemeen voorbeeld

Op de website van JA-SIG is een bibliotheek voor php (phpCAS) beschikbaar: http://www.ja-sig.org/wiki/display/CASC/phpCAS. Deze library is compatibel met CAS3, maar mist enkele CAS3-specifieke features.

We ontwikkelden daarom een aangepaste versie, gebaseerd op phpCAS. Deze bibliotheek is te downloaden op cas-ugent-php.zip. Tot zolang phpCAS geen ondersteuning biedt voor CAS versie 3, is het aangeraden deze bibliotheek te gebruiken.

Onderstaand voorbeeld toont hoe de bibliotheek kan gebruikt worden.

Gelieve de locatie van het certificaat aan te passen naar de plaats waar het certificaat is opgeslagen! Wanneer het pad naar het certificaat verkeerd geconfigureerd is, leidt dit tot een oneindige redirect lus.

<?php

include_once('CAS.php');

//phpCAS::setDebug('/tmp/phpCAS.log'); // Schrijft debug informatie naar een log-file

// Parameters: CAS versie, url CAS server, poort CAS server, CAS server URI (idem als host), 
// boolean die aangeeft of sessie moet gestart worden, communicatieprotocol (SAML) tussen toepassing en CAS server
phpCAS::client(SAML_VERSION_1_1,'login.ugent.be',443,'', true, 'saml');

// Geeft aan vanaf welke server logout requests mogelijk zijn
phpCAS::handleLogoutRequests(true, array('cas1.ugent.be','cas2.ugent.be','cas3.ugent.be','cas4.ugent.be','cas5.ugent.be','cas6.ugent.be'));

// Locatie van het "trusted certificate authorities" bestand:
phpCAS::setCasServerCACert('/etc/ssl/certs/ca-certificates.crt');
// Geen server verificatie (minder veilig!):
//phpCAS::setNoCasServerValidation();
// Hier gebeurt de authenticatie van de gebruiker
phpCAS::forceAuthentication(); 

// Opvangen van logout requests
if (isset($_REQUEST['logout'])) {
        phpCAS::logout();
}


?>

<html>
  <head>
    <title>phpCAS simple client</title>
  </head>
  <body>
    <h1>Successfull Authentication!</h1>

    <p>the user's login is <b><?php echo phpCAS::getUser(); ?></b>.</p>
    <p>the attributes are:
    <?php
    echo '<ul>';
    $attr = phpCAS::getAttributes();
    foreach ($attr as $key => $value)
    {
        if(!is_array($value))
        {
                echo '<li>' . $key . ' => ' . $value . '</li>';
        }
        else
        {
                echo '<li>' . $key . '</li>';
                echo '<ul>';
                foreach($value as $v)
                {
                        echo '<li>' . $v . '</li>';
                }
                echo '</ul>';
        }
    }
    echo '</ul>';
    ?>

    </p>
    <p>phpCAS version is <b><?php echo phpCAS::getVersion(); ?></b>.</p>
    <p><a href="?logout=">Logout</a></p>

  </body>
</html>

UGCAS_Simple voorbeeld

Dit voorbeeld is specifiek ontworpen voor webpages.ugent.be en users.ugent.be (= sites op webshares), maar kan ook op andere plaatsen gebruikt worden. De identiteit van de gebruiker (gebruikersnaam) wordt afdrukt. Er zijn geen extra attributen noch logout voorzien.

UGCAS_Simple is te downloaden op UGCAS_Simple-0.1.zip en bevat:

  • UGCAS_Simple.php: php CAS module. Sla de module op in een map binnen uw PHP path!
  • hello.php: eenvoudig voorbeeld
  • hello2.php: licht uitgebreid voorbeeld

Een voorbeeld in java

U kunt het voorbeeld testen op https://login.ugent.be/cas-java-demo

Een praktijkvoorbeeld, kunt u downloaden van cas-java-demo.zip

Voor een Java Webtoepassing volstaat het een aantal door de CAS ontwikkelaars voorziene filters in te stellen.

Belangrijk: Onderstaande uitleg gaat uit van cas-client versie 3.1.3

1. De volgende libraries dient u toe te voegen aan de WEB-INF/lib (of gebruik Maven):

cas-client-core-3.1.3.jar
commons-logging-1.1.jar
log4j-1.2.5.jar
opensaml-1.1.jar
xmlsec-1.3.0.jar

Download deze hier: java_servlet_filter_libs.zip

2. de WEB-INF/web.xml file dient u aan te passen met de nodige filters.


	<context-param>
		<param-name>serverName</param-name>
		<param-value>https://mijnserver.ugent.be</param-value>
	</context-param>

	<filter>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
	</filter>
	<filter-mapping>

		<filter-name>CAS Single Sign Out Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<listener>
		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

	</listener>
	<filter>
		<filter-name>CAS Authentication Filter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>

			<param-name>casServerLoginUrl</param-name>
			<param-value>https://login.ugent.be/</param-value>
		</init-param>
		<init-param>
			<param-name>renew</param-name>

			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>gateway</param-name>
			<param-value>false</param-value>

		</init-param>
	</filter>
	<filter>
		<filter-name>CAS Validation Filter</filter-name>
		<filter-class>org.jasig.cas.client.validation.Saml11TicketValidationFilter</filter-class>

		<init-param>
			<param-name>casServerUrlPrefix</param-name>
			<param-value>https://login.ugent.be/</param-value>
		</init-param>
		<init-param>

			<param-name>tolerance</param-name>
			<param-value>300000</param-value>
		</init-param>
	</filter>
	<filter>

		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Authentication Filter</filter-name>

		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>CAS Validation Filter</filter-name>
		<url-pattern>/*</url-pattern>

	</filter-mapping>
	<filter-mapping>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<servlet>
		<description>DemoServlet</description>
		<display-name>DemoServlet</display-name>
		<servlet-name>DemoServlet</servlet-name>

		<servlet-class>be.ugent.dict.ugentssoauth.demo.servlet.DemoServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>DemoServlet</servlet-name>
		<url-pattern>/*</url-pattern>

	</servlet-mapping>
</web-app>

Een korte toelichting:

  • mijnserver.ugent.be: host waarop de toepassing draait
  • tolerance: tolerantie inzake de tijdsverschillen tussen de timestamp-berichten die uitgewisseld worden (in ms).
  • redirectAfterValidation: bij false blijft de ticket parameter in de url staan, bij true niet (= gewenst).

3. U kunt daarna met request.getRemoteUser() de user opvragen. De attributen kunt u halen uit request.getUserPrincipal()

Hieronder vindt u een voorbeeld van hoe u de remote user ophaalt samen met zijn attributen.

import org.jasig.cas.client.authentication.AttributePrincipal;

...

                out.println("You are succesfully logged in as user <b>"	+ request.getRemoteUser() + "</b><br/><br/>");

		AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
		Map attributes = principal.getAttributes();

		if (attributes.size() > 0) {

			out.println("You have " + attributes.size() + " attributes : <br/>");
			Iterator keyIterator = attributes.keySet().iterator();

			while (keyIterator.hasNext()) {

				Object key = keyIterator.next();
				Object value = attributes.get(key);
				out.println("<b>" + key + "</b>" + " : " + value);
		        }
		} else {
			out.println("You have no attributes set");
		}

Spring security

CAS authenticatie kan worden ge´ntegreerd in een Spring based toepassing d.m.v. Spring Security.

Spring Security biedt out-of-the-box ondersteuning voor CAS 3. Zie http://static.springsource.org/spring-security/site/docs/3.0.x/reference/cas.html voor de uitstekende online documentatie van Spring Security zelf. Ingeval u problemen ondervindt, gelieve ook ook de FAQ te bekijken op http://static.springsource.org/spring-security/site/faq.html#faq-start-simple

Een voorbeeld toepassing kan gedownload worden van CasSpringsecurityExample.zip. Ontwikkelaars dienen zeker de UserDetailService bean te herconfigureren naar de gewenste omgeving.

Maven

De Java CAS client kan ook eenvoudig geïntegreerd worden in een Maven-based build systeem:

<dependency>
    <groupId>org.jasig.cas</groupId>
    <artifactId>cas-client-core</artifactId>
    <version>3.1.4</version>

</dependency> 
<dependency>
    <groupId>opensaml</groupId>
    <artifactId>opensaml</artifactId>
    <version>1.1b</version>

</dependency>

SSL

Service tickets worden gevalideerd via een SSL connectie met de CAS server. Het is dus noodzakelijk dat het certificaat van de CAS server ingeladen wordt in de JVM waarop de Java toepassing zal draaien.

sudo $JAVA_HOME/bin/keytool -import -alias login.ugent.be -file CERTIFICATE_FILE 
     -keystore $JAVA_HOME/jre/lib/security/cacerts
                            

Een voorbeeld in .NET

Een praktijkvoorbeeld, kunt u downloaden van cas-NET-demo.zip.
Hier vindt u alle broncode die u nodig heeft om de .NET client te implementeren in uw project.

De eerste stap is het toevoegen van de properties in Web.config

	<appSettings>
		<add key="casLoginURL" value="https://login.ugent.be/login"/>
		<add key="casValidateURL" value="https://login.ugent.be/serviceValidate"/>
		<add key="casSamlValidateURL" value="https://login.ugent.be/samlValidate"/>
		<add key="serviceURL" value="jouw geregistreerde cas url"/>
	</appSettings>

De tweede stap is de klassen "DotNetCasClient" en "DotNetCasAttributePrincipal" toevoegen aan uw project. De derde stap is de volgende code toevoegen in uw hoofdpagina.

    protected void Page_Load(object sender, EventArgs e)
    {
        DotNetCasAttributePrincipal principal= null;
        String userId = (String)Session["userId"];
        if (userId == null)
        {
            DotNetCASClientServiceValidate client = new DotNetCASClientServiceValidate();

            principal = client.AuthenticatePrincipal(Request, Response);
        }
        if (principal != null && principal.isAutheniticated)
        {
            Session["userId"] = principal.userName;
            Session["userAttributeTable"] = principal.attributes;
        }
    }

Vanaf nu maakt uw applicatie ook gebruik van CAS.
Nota: de attributen zitten in een HashTable, elk attribuut is een arraylist van Strings. De Single Sign Out is niet geïmplementeerd. Deze zal u zelf moeten implementeren, indien u hiervan wenst gebruik maken.
Extra informatie over Single Sign Out vindt u op de cas help pagina's.