CAS Authentication Server: Unterschied zwischen den Versionen

Aus Hostsharing Wiki
Zur Navigation springen Zur Suche springen
K (add Ansible Playbook)
KKeine Bearbeitungszusammenfassung
 
Zeile 17: Zeile 17:
Zunächst werden mit HSAdmin ein User und eine Domain eingerichtet. Darauf achten, dass der User eine gültige Login-Shell erhält, hier die Bash (''/bin/bash'').
Zunächst werden mit HSAdmin ein User und eine Domain eingerichtet. Darauf achten, dass der User eine gültige Login-Shell erhält, hier die Bash (''/bin/bash'').


  xyz00@h50:~$ hsscript -i
<syntaxhighlight lang="bash">
  xyz00@hsadmin> user.add({set:{name:'xyz00-login',shell:'/bin/bash',password:'***'}})
xyz00@h50:~$ hsscript -i
  xyz00@hsadmin> domain.add({set:{user:'xyz00-login',name:'login.hs-example.de'}})
xyz00@hsadmin> user.add({set:{name:'xyz00-login',shell:'/bin/bash',password:'***'}})
  xyz00@hsadmin> bye
xyz00@hsadmin> domain.add({set:{user:'xyz00-login',name:'login.hs-example.de'}})
xyz00@hsadmin> bye
</syntaxhighlight>


=== Einrichtung des Tomcat ===
=== Einrichtung des Tomcat ===
Zeile 30: Zeile 32:
Einrichten eines Apache Tomcat 9 im Userspace:
Einrichten eines Apache Tomcat 9 im Userspace:


  xyz00-login@h50:~$ tomcat9-instance-create tomcat9
<syntaxhighlight lang="output">
  You are about to create a Tomcat instance in directory 'tomcat9'
xyz00-login@h50:~$ tomcat9-instance-create tomcat9
  Warning: HTTP port 8080 appears to be in use.
You are about to create a Tomcat instance in directory 'tomcat9'
  Type <ENTER> to continue, <CTRL-C> to abort.
Warning: HTTP port 8080 appears to be in use.
Type <ENTER> to continue, <CTRL-C> to abort.
</syntaxhighlight>


Mit <Enter> bestätigen, dann wird eine Tomcat-Konfiguration im neuen Verzeichnis $HOME/tomcat9 angelegt.
Mit <Enter> bestätigen, dann wird eine Tomcat-Konfiguration im neuen Verzeichnis $HOME/tomcat9 angelegt.
Zeile 39: Zeile 43:
Die ''server.xml'' im Verzeichnis $HOME/tomcat9/conf wird angepasst:
Die ''server.xml'' im Verzeichnis $HOME/tomcat9/conf wird angepasst:


  <?xml version="1.0" encoding="UTF-8"?>
<syntaxhighlight lang="xml" line>
  <Server port="31530" shutdown="SHUTDOWN">
<?xml version="1.0" encoding="UTF-8"?>
    
<Server port="31530" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
 
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
   <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
    <GlobalNamingResources>
 
      <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
   <GlobalNamingResources>
              description="User database that can be updated and saved"
    <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
            description="User database that can be updated and saved"
              pathname="conf/tomcat-users.xml" />
            factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
      </GlobalNamingResources>
            pathname="conf/tomcat-users.xml" />
    
    </GlobalNamingResources>
    <Service name="Catalina">
 
      <Connector address="localhost" port="31531" protocol="AJP/1.3" redirectPort="443" />
   <Service name="Catalina">
      <Engine name="Catalina" defaultHost="localhost">
    <Connector address="localhost" port="31531" protocol="AJP/1.3" redirectPort="443" />
        <Realm className="org.apache.catalina.realm.LockOutRealm">
    <Engine name="Catalina" defaultHost="localhost">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        </Realm>
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
        <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
      </Realm>
        </Host>
      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
      </Engine>
      </Host>
    </Service>
    </Engine>
 
  </Service>
  </Server>
</Server>
</syntaxhighlight>


Insbesondere die beiden Angaben ''port="31530"'' und ''port="31531"'' müssen angepasst werden!
Insbesondere die beiden Angaben ''port="31530"'' und ''port="31531"'' müssen angepasst werden!
Zeile 72: Zeile 77:
In der Datei ''setenv.sh'' im Verzeichnis $HOME/tomcat9/bin ergänzenen wir den Pfad zur Java 11 Installation als Variable $JAVA_HOME (für 32-Bit bzw. für 64-Bit Systeme), dazu den Pfad für eine Datei mit der Prozess-ID Prozess-Id und eine System-Property in den Java-Opts mit dem Verzeichnis-Pfad, in dem wir später die CAS-Konfiguration ablegen:
In der Datei ''setenv.sh'' im Verzeichnis $HOME/tomcat9/bin ergänzenen wir den Pfad zur Java 11 Installation als Variable $JAVA_HOME (für 32-Bit bzw. für 64-Bit Systeme), dazu den Pfad für eine Datei mit der Prozess-ID Prozess-Id und eine System-Property in den Java-Opts mit dem Verzeichnis-Pfad, in dem wir später die CAS-Konfiguration ablegen:


  # export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-i386
<syntaxhighlight lang="bash">
  export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
# export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-i386
  export JAVA_OPTS="-Djava.awt.headless=true -Dcas.standalone.configurationDirectory=/home/pacs/xyz00/users/login/cas/conf"
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export JAVA_OPTS="-Djava.awt.headless=true -Dcas.standalone.configurationDirectory=/home/pacs/xyz00/users/login/cas/conf"
</syntaxhighlight>


Ich kopiere zum Testen gern noch das Startskript ''catalina.sh'' in die Installation des Tomcat:
Ich kopiere zum Testen gern noch das Startskript ''catalina.sh'' in die Installation des Tomcat:


  xyz00-login@h50:~$ cp /usr/share/tomcat9/bin/catalina.sh $HOME/tomcat9/bin/
<syntaxhighlight lang="bash">
  xyz00-login@h50:~$ cd tomcat9/
xyz00-login@h50:~$ cp /usr/share/tomcat9/bin/catalina.sh $HOME/tomcat9/bin/
  xyz00-login@h50:~/tomcat9$ ./bin/catalina.sh run
xyz00-login@h50:~$ cd tomcat9/
  Using CATALINA_BASE:  /home/pacs/xyz00/users/login/tomcat9
xyz00-login@h50:~/tomcat9$ ./bin/catalina.sh run
  Using CATALINA_HOME:  /usr/share/tomcat9
Using CATALINA_BASE:  /home/pacs/xyz00/users/login/tomcat9
  Using CATALINA_TMPDIR: /home/pacs/xyz00/users/login/tomcat9/temp
Using CATALINA_HOME:  /usr/share/tomcat9
  Using JRE_HOME:        /usr/lib/jvm/default-java
Using CATALINA_TMPDIR: /home/pacs/xyz00/users/login/tomcat9/temp
  Using CLASSPATH:      /usr/share/tomcat9/bin/bootstrap.jar:/usr/share/tomcat9/bin/tomcat-juli.jar
Using JRE_HOME:        /usr/lib/jvm/default-java
  <6>Server version name:  Apache Tomcat/9.0.31 (Debian)
Using CLASSPATH:      /usr/share/tomcat9/bin/bootstrap.jar:/usr/share/tomcat9/bin/tomcat-juli.jar
  [...]
<6>Server version name:  Apache Tomcat/9.0.31 (Debian)
  <6>Server startup in [75] milliseconds
[...]
<6>Server startup in [75] milliseconds
</syntaxhighlight>


Tomcat läuft, abbrechen mit <Ctrl-C>
Tomcat läuft, abbrechen mit <Ctrl-C>
Zeile 94: Zeile 103:
=== Konfiguration des Apache als Proxy ===
=== Konfiguration des Apache als Proxy ===


  cd ~/doms/login.hs-example.de/
<syntaxhighlight lang="bash">
  rm -rf subs/www subs-ssl/www
cd ~/doms/login.hs-example.de/
 
rm -rf subs/www subs-ssl/www
</syntaxhighlight>
 
Bearbeiten der ~/doms/login.hs-example.de/htdocs-ssl/.htaccess
Bearbeiten der ~/doms/login.hs-example.de/htdocs-ssl/.htaccess


  DirectoryIndex disabled
<syntaxhighlight lang="apache" line>
  RewriteEngine On
DirectoryIndex disabled
  RewriteBase /
RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*) ajp://localhost:31531/$1 [proxy,last]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*) ajp://localhost:31531/$1 [proxy,last]
</syntaxhighlight>


Achtung: der Port 31531 ist wieder durch den Port des AJP-Listeners in der eigenen Tomcat-Konfiguration zu ersetzen.
Achtung: der Port 31531 ist wieder durch den Port des AJP-Listeners in der eigenen Tomcat-Konfiguration zu ersetzen.
Zeile 112: Zeile 125:
Anlegen von Verzeichnissen für die spätere Konfiguration des CAS Server
Anlegen von Verzeichnissen für die spätere Konfiguration des CAS Server


  cd
<syntaxhighlight lang="bash">
  mkdir -p cas/conf
cd
  mkdir -p cas/services
mkdir -p cas/conf
mkdir -p cas/services
</syntaxhighlight>


Ins Verzeichnis ''~/cas/conf'' legen wir eine Datei ''cas.properties'' mit folgendem Inhalt:
Ins Verzeichnis ''~/cas/conf'' legen wir eine Datei ''cas.properties'' mit folgendem Inhalt:


  cas.server.name=https://login.hs-example.de
<syntaxhighlight lang="ini" line>
  cas.server.prefix=${cas.server.name}/cas
cas.server.name=https://login.hs-example.de
  cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
cas.server.prefix=${cas.server.name}/cas
  logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml
cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml
</syntaxhighlight>


Die Datei ''log4j2.xml'' kopieren wir aus ''~/git/cas-overlay-template/etc/cas/config/''
Die Datei ''log4j2.xml'' kopieren wir aus ''~/git/cas-overlay-template/etc/cas/config/''


  cp ~/git/cas-overlay-template/etc/cas/config/ ~/cas/conf/
<syntaxhighlight lang="bash">
cp ~/git/cas-overlay-template/etc/cas/config/ ~/cas/conf/
</syntaxhighlight>


In der log4j2.xml passen wir den Wert für die Variable ''baseDir'' (etwa Zeile 5) an:
In der log4j2.xml passen wir den Wert für die Variable ''baseDir'' (etwa Zeile 5) an:


  <Property name="baseDir">/home/pacs/xyz00/users/login/tomcat9/logs</Property>
<syntaxhighlight lang="xml">
<Property name="baseDir">/home/pacs/xyz00/users/login/tomcat9/logs</Property>
</syntaxhighlight>


Auschecken des CAS Overlay Projektes
Auschecken des CAS Overlay Projektes


  mkdir git
<syntaxhighlight lang="bash">
  cd git
mkdir git
  git clone https://github.com/apereo/cas-overlay-template.git
cd git
  cd cas-overlay-template/
git clone https://github.com/apereo/cas-overlay-template.git
  git fetch
cd cas-overlay-template/
  git checkout 6.0
git fetch
git checkout 6.0
</syntaxhighlight>


Build und Deployment der Web-Applikation
Build und Deployment der Web-Applikation


  ./build.sh package
<syntaxhighlight lang="bash">
  cd
./build.sh package
  cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/
cd
cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/
</syntaxhighlight>


Nach einer erneuten Start des Tomcat ist das CAS-Login unter
Nach einer erneuten Start des Tomcat ist das CAS-Login unter
Zeile 161: Zeile 186:
Der betreffende Ausschnitt der Datei:
Der betreffende Ausschnitt der Datei:


dependencies {
<syntaxhighlight lang="java" line>
    // [...] Teile ausgespart
dependencies {
  // [...] Teile ausgespart
    /**
 
    * CAS dependencies and modules may be listed here.
  /**
    *
    * CAS dependencies and modules may be listed here.
    * There is no need to specify the version number for each dependency
    *
    * since versions are all resolved and controlled by the dependency management
    * There is no need to specify the version number for each dependency
    * plugin via the CAS bom.
    * since versions are all resolved and controlled by the dependency management
    **/
    * plugin via the CAS bom.
    **/
    // email notification, service registry
 
    implementation "org.apereo.cas:cas-server-core-notifications"
  // email notification, service registry
    implementation "org.apereo.cas:cas-server-support-json-service-registry"
  implementation "org.apereo.cas:cas-server-core-notifications"
  implementation "org.apereo.cas:cas-server-support-json-service-registry"
    // jdbc datasource
 
    implementation "org.apereo.cas:cas-server-support-jdbc-drivers"
  // jdbc datasource
    implementation "org.apereo.cas:cas-server-support-jdbc"
  implementation "org.apereo.cas:cas-server-support-jdbc-drivers"
  implementation "org.apereo.cas:cas-server-support-jdbc"
    // password reset
 
    implementation "org.apereo.cas:cas-server-support-pm-webflow"
  // password reset
    implementation "org.apereo.cas:cas-server-support-pm-jdbc"
  implementation "org.apereo.cas:cas-server-support-pm-webflow"
  implementation "org.apereo.cas:cas-server-support-pm-jdbc"
    // openid-connect / oidc
 
    implementation "org.apereo.cas:cas-server-support-oidc"
  // openid-connect / oidc
  implementation "org.apereo.cas:cas-server-support-oidc"
    /**
 
    * Do NOT modify the lines below or else you will risk breaking the build.
  /**
    */
  * Do NOT modify the lines below or else you will risk breaking the build.
    implementation "org.apereo.cas:cas-server-core-api-configuration-model"
  */
    implementation "org.apereo.cas:cas-server-webapp-init"
  implementation "org.apereo.cas:cas-server-core-api-configuration-model"
  implementation "org.apereo.cas:cas-server-webapp-init"
    // [...] Teile ausgespart
 
}
  // [...] Teile ausgespart
}
</syntaxhighlight>


Wir bauen das cas.war mit den folgenden Befehlen neu:
Wir bauen das cas.war mit den folgenden Befehlen neu:


  cd ~/git/cas-overlay-template
<syntaxhighlight lang="bash">
  ./build.sh package
cd ~/git/cas-overlay-template
  cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/
./build.sh package
cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/
</syntaxhighlight>


Der Pfad zur Service-Registry war in der oben erstellten ''cas.properties'' bereits enthalten.
Der Pfad zur Service-Registry war in der oben erstellten ''cas.properties'' bereits enthalten.
Zeile 206: Zeile 235:
''hsexamplecloud-1000001.json'' und wird im Verzeichnis ''~/cas/services/'' abgelegt. Der Inhalt:
''hsexamplecloud-1000001.json'' und wird im Verzeichnis ''~/cas/services/'' abgelegt. Der Inhalt:


  {
<syntaxhighlight lang="json" line>
    "@class" : "org.apereo.cas.services.RegexRegisteredService",
{
    "serviceId" : "^https://cloud.hs-example.de.*",
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
    "name" : "hsexamplecloud",
  "serviceId" : "^https://cloud.hs-example.de.*",
    "id" : 1000001,
  "name" : "hsexamplecloud",
    "description" : "Nextcloud HS-Example",
  "id" : 1000001,
    "evaluationOrder" : 10000
  "description" : "Nextcloud HS-Example",
  }
  "evaluationOrder" : 10000
}
</syntaxhighlight>


Der Name der Datei setzt sich aus Service-Name und Service-Id zusammen!
Der Name der Datei setzt sich aus Service-Name und Service-Id zusammen!
Zeile 230: Zeile 261:
Wir erweitern wieder die Datei ''build.gradle'' im Abschnitt ''dependencies''.  
Wir erweitern wieder die Datei ''build.gradle'' im Abschnitt ''dependencies''.  


  dependencies {
<syntaxhighlight lang="java" line>
    compile "org.apereo.cas:cas-server-webapp${project.appServer}:${casServerVersion}"
dependencies {
    // Other CAS dependencies/modules may be listed here...
  compile "org.apereo.cas:cas-server-webapp${project.appServer}:${casServerVersion}"
    compile "org.apereo.cas:cas-server-support-json-service-registry:${project.'cas.version'}"
  // Other CAS dependencies/modules may be listed here...
    compile "org.apereo.cas:cas-server-support-jdbc-drivers:${project.'cas.version'}"
  compile "org.apereo.cas:cas-server-support-json-service-registry:${project.'cas.version'}"
    compile "org.apereo.cas:cas-server-support-jdbc:${project.'cas.version'}"
  compile "org.apereo.cas:cas-server-support-jdbc-drivers:${project.'cas.version'}"
  }
  compile "org.apereo.cas:cas-server-support-jdbc:${project.'cas.version'}"
}
</syntaxhighlight>


''cas-server-support-jdbc-drivers'' liefert JDBC-Treiber für die gängigen Open-Source Datenbanksysteme. ''org.apereo.cas:cas-server-support-jdbc'' liefert das eigentliche CAS-Authentication Backend.
''cas-server-support-jdbc-drivers'' liefert JDBC-Treiber für die gängigen Open-Source Datenbanksysteme. ''org.apereo.cas:cas-server-support-jdbc'' liefert das eigentliche CAS-Authentication Backend.
Zeile 242: Zeile 275:
Zur Konfiguration wird die Datei ''cas.properties'' im Verzeichnis ''~/cas/conf/'' erweitert:
Zur Konfiguration wird die Datei ''cas.properties'' im Verzeichnis ''~/cas/conf/'' erweitert:


  cas.server.name=https://login.hs-example.de
<syntaxhighlight lang="java" line>
  cas.server.prefix=${cas.server.name}/cas
cas.server.name=https://login.hs-example.de
  cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
cas.server.prefix=${cas.server.name}/cas
  logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml
cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
  logging.level.org.apereo=DEBUG
logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml
  cas.authn.jdbc.query[0].sql=SELECT * FROM USERS WHERE UID=?
logging.level.org.apereo=DEBUG
  cas.authn.jdbc.query[0].url=jdbc:postgresql://localhost/xyz00_cas
cas.authn.jdbc.query[0].sql=SELECT * FROM USERS WHERE UID=?
  cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.PostgreSQL92Dialect
cas.authn.jdbc.query[0].url=jdbc:postgresql://localhost/xyz00_cas
  cas.authn.jdbc.query[0].user=xyz00_cas
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.PostgreSQL92Dialect
  cas.authn.jdbc.query[0].password=Ein_schlechtes_Passwort
cas.authn.jdbc.query[0].user=xyz00_cas
  cas.authn.jdbc.query[0].driverClass=org.postgresql.Driver
cas.authn.jdbc.query[0].password=Ein_schlechtes_Passwort
  cas.authn.jdbc.query[0].fieldPassword=PSW
cas.authn.jdbc.query[0].driverClass=org.postgresql.Driver
  cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
cas.authn.jdbc.query[0].fieldPassword=PSW
  cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
  cas.authn.accept.users=
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.accept.users=
</syntaxhighlight>


Hier ein Beispiel für eine PostgreSQL-Datenbank mit einer Tabelle ''USERS'' mit den Spalten ''UID'' und ''PSW''. Die Spalte ''UID'' enthält den Login-Namen des Users, die Spalte ''PSW'' das Passwort mit dem BCrypt-Algorithmus verschlüsselt.
Hier ein Beispiel für eine PostgreSQL-Datenbank mit einer Tabelle ''USERS'' mit den Spalten ''UID'' und ''PSW''. Die Spalte ''UID'' enthält den Login-Namen des Users, die Spalte ''PSW'' das Passwort mit dem BCrypt-Algorithmus verschlüsselt.

Aktuelle Version vom 14. Juni 2024, 11:16 Uhr

CAS Authentication Server

Der CAS Server ("Central Authentication Service" oder "CAS Authentication Server") ist eine SSO- ("Single Sign On") Lösung.

CAS ist für große, verteilte Deploments von Web-Anwendungen geeignet. Er stammt aus dem Universitätsumfeld in den USA. Er wurde bei der Yale Universität entwickelt und wird aktuell bei JA-SIG / Apereo als freie Software unter der Apache Lizenz gepflegt. [1], [2]

Die Hostsharing eG nutzt CAS seit Jahren als Login-Lösung insbesondere für die Administrationswerkzeuge von Hsadmin.

Dieser Beitrag erläutert die Installation von CAS in einem Hostsharing Webspace und die Konfiguration von Beispielanwendungen zum Login mit CAS. Als Nutzerdatenbank wird ein vorhandener Nutzerstamm in einer SQL-Datenbank benutzt,

Erste Installation

Die aktuelle stabile Version des CAS Server ist 6.6.7 Diese Version erfordert Java 11. Die empfohlene Installation eines Standalone-CAS erfolgt über das WAR Overlay Projekt [3]. Eine ausführliche Deployment-Anleitung (leider noch für Version 5.x) findet sich bei The New School [4]. Eine Anleitung für die aktuelle Version 6.6.x ist unter [10] verfügbar.

Service-User und Domain

Zunächst werden mit HSAdmin ein User und eine Domain eingerichtet. Darauf achten, dass der User eine gültige Login-Shell erhält, hier die Bash (/bin/bash).

xyz00@h50:~$ hsscript -i
xyz00@hsadmin> user.add({set:{name:'xyz00-login',shell:'/bin/bash',password:'***'}})
xyz00@hsadmin> domain.add({set:{user:'xyz00-login',name:'login.hs-example.de'}})
xyz00@hsadmin> bye

Einrichtung des Tomcat

Für den Apache Tomcat Webserver ist die Option "Eigener Daemon" notwendig. Bei der Anmeldung (bei service(at)hostsharing.net bitte den Service User xyz00-login und die gewüschte Anzahl IP-Ports angeben). Hier verwenden wir die Ports 31530, 31531 und 31532.

Weiter geht es als User xyz00-login

Einrichten eines Apache Tomcat 9 im Userspace:

xyz00-login@h50:~$ tomcat9-instance-create tomcat9
You are about to create a Tomcat instance in directory 'tomcat9'
Warning: HTTP port 8080 appears to be in use.
Type <ENTER> to continue, <CTRL-C> to abort.

Mit <Enter> bestätigen, dann wird eine Tomcat-Konfiguration im neuen Verzeichnis $HOME/tomcat9 angelegt.

Die server.xml im Verzeichnis $HOME/tomcat9/conf wird angepasst:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="31530" shutdown="SHUTDOWN">

  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
            description="User database that can be updated and saved"
            factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
            pathname="conf/tomcat-users.xml" />
    </GlobalNamingResources>

  <Service name="Catalina">
    <Connector address="localhost" port="31531" protocol="AJP/1.3" redirectPort="443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
      </Host>
    </Engine>
  </Service>
</Server>

Insbesondere die beiden Angaben port="31530" und port="31531" müssen angepasst werden!

In der Datei setenv.sh im Verzeichnis $HOME/tomcat9/bin ergänzenen wir den Pfad zur Java 11 Installation als Variable $JAVA_HOME (für 32-Bit bzw. für 64-Bit Systeme), dazu den Pfad für eine Datei mit der Prozess-ID Prozess-Id und eine System-Property in den Java-Opts mit dem Verzeichnis-Pfad, in dem wir später die CAS-Konfiguration ablegen:

# export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-i386
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export JAVA_OPTS="-Djava.awt.headless=true -Dcas.standalone.configurationDirectory=/home/pacs/xyz00/users/login/cas/conf"

Ich kopiere zum Testen gern noch das Startskript catalina.sh in die Installation des Tomcat:

xyz00-login@h50:~$ cp /usr/share/tomcat9/bin/catalina.sh $HOME/tomcat9/bin/
xyz00-login@h50:~$ cd tomcat9/
xyz00-login@h50:~/tomcat9$ ./bin/catalina.sh run
Using CATALINA_BASE:   /home/pacs/xyz00/users/login/tomcat9
Using CATALINA_HOME:   /usr/share/tomcat9
Using CATALINA_TMPDIR: /home/pacs/xyz00/users/login/tomcat9/temp
Using JRE_HOME:        /usr/lib/jvm/default-java
Using CLASSPATH:       /usr/share/tomcat9/bin/bootstrap.jar:/usr/share/tomcat9/bin/tomcat-juli.jar
<6>Server version name:   Apache Tomcat/9.0.31 (Debian)
[...]
<6>Server startup in [75] milliseconds

Tomcat läuft, abbrechen mit <Ctrl-C>

Konfiguration des Apache als Proxy

cd ~/doms/login.hs-example.de/
rm -rf subs/www subs-ssl/www

Bearbeiten der ~/doms/login.hs-example.de/htdocs-ssl/.htaccess

DirectoryIndex disabled
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*) ajp://localhost:31531/$1 [proxy,last]

Achtung: der Port 31531 ist wieder durch den Port des AJP-Listeners in der eigenen Tomcat-Konfiguration zu ersetzen.

CAS Basisinstallation

Anlegen von Verzeichnissen für die spätere Konfiguration des CAS Server

cd
mkdir -p cas/conf
mkdir -p cas/services

Ins Verzeichnis ~/cas/conf legen wir eine Datei cas.properties mit folgendem Inhalt:

cas.server.name=https://login.hs-example.de
cas.server.prefix=${cas.server.name}/cas
cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml

Die Datei log4j2.xml kopieren wir aus ~/git/cas-overlay-template/etc/cas/config/

cp ~/git/cas-overlay-template/etc/cas/config/ ~/cas/conf/

In der log4j2.xml passen wir den Wert für die Variable baseDir (etwa Zeile 5) an:

<Property name="baseDir">/home/pacs/xyz00/users/login/tomcat9/logs</Property>

Auschecken des CAS Overlay Projektes

mkdir git
cd git
git clone https://github.com/apereo/cas-overlay-template.git
cd cas-overlay-template/
git fetch
git checkout 6.0

Build und Deployment der Web-Applikation

./build.sh package
cd
cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/

Nach einer erneuten Start des Tomcat ist das CAS-Login unter https://login.hs-example.de/cas/ erreichbar.

Ein Login mit der Kennung casuser und dem Passwort Mellon sollte erfolgreich sein.

Erweiterte Konfiguration des CAS

Die Funktionalität des CAS Server ist modular erweiterbar. Im ersten Schritt erweitern wir den CAS um eine Service Registry. Für unsere einfache Standalone-Installation nutzen wir die JSON-File-Registry

JSON Service Registry

Erweiterungen werden in der Datei build.gradle im Abschnitt dependencies eingetragen. Die Datei liegt im Wurzelverzeichnis des Git-Repositories für unser CAS Overlay (~/git/cas-overlay-template/).

Der betreffende Ausschnitt der Datei:

dependencies {
  // [...] Teile ausgespart

  /**
    * CAS dependencies and modules may be listed here.
    *
    * There is no need to specify the version number for each dependency
    * since versions are all resolved and controlled by the dependency management
    * plugin via the CAS bom.
    **/

  // email notification, service registry
  implementation "org.apereo.cas:cas-server-core-notifications"
  implementation "org.apereo.cas:cas-server-support-json-service-registry"

  // jdbc datasource
  implementation "org.apereo.cas:cas-server-support-jdbc-drivers"
  implementation "org.apereo.cas:cas-server-support-jdbc"

  // password reset
  implementation "org.apereo.cas:cas-server-support-pm-webflow"
  implementation "org.apereo.cas:cas-server-support-pm-jdbc"

  // openid-connect / oidc
  implementation "org.apereo.cas:cas-server-support-oidc"

  /**
  * Do NOT modify the lines below or else you will risk breaking the build.
  */
  implementation "org.apereo.cas:cas-server-core-api-configuration-model"
  implementation "org.apereo.cas:cas-server-webapp-init"

  // [...] Teile ausgespart
}

Wir bauen das cas.war mit den folgenden Befehlen neu:

cd ~/git/cas-overlay-template
./build.sh package
cp ~/git/cas-overlay-template/build/libs/cas.war ~/tomcat9/webapps/

Der Pfad zur Service-Registry war in der oben erstellten cas.properties bereits enthalten. Nun legen wir einen ersten Service an, in meinem Fall eine Nextcloud-Installation. Die Datei heißt hsexamplecloud-1000001.json und wird im Verzeichnis ~/cas/services/ abgelegt. Der Inhalt:

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^https://cloud.hs-example.de.*",
  "name" : "hsexamplecloud",
  "id" : 1000001,
  "description" : "Nextcloud HS-Example",
  "evaluationOrder" : 10000
}

Der Name der Datei setzt sich aus Service-Name und Service-Id zusammen!

Die Konfiguration des CAS-Login in der Nextcloud erfolgt über die entsprechende "App" in Nextcloud. Die Parameter sind wie folgt:

Cas-nextcloud-app.png

Die "Dienst-URL" im Screenshot ist: https://cloud.hs-example.de/index.php/apps/user_cas/login

Die Anmeldung mit der Kennung casuser und dem Passwort Mellon sollte nun von der Nextcloud-Loginseite über den Link zum CAS-Login möglich sein.

Authentifizierung gegen JDBC Datenbank

Wir erweitern wieder die Datei build.gradle im Abschnitt dependencies.

dependencies {
  compile "org.apereo.cas:cas-server-webapp${project.appServer}:${casServerVersion}"
  // Other CAS dependencies/modules may be listed here...
  compile "org.apereo.cas:cas-server-support-json-service-registry:${project.'cas.version'}"
  compile "org.apereo.cas:cas-server-support-jdbc-drivers:${project.'cas.version'}"
  compile "org.apereo.cas:cas-server-support-jdbc:${project.'cas.version'}"
}

cas-server-support-jdbc-drivers liefert JDBC-Treiber für die gängigen Open-Source Datenbanksysteme. org.apereo.cas:cas-server-support-jdbc liefert das eigentliche CAS-Authentication Backend.

Zur Konfiguration wird die Datei cas.properties im Verzeichnis ~/cas/conf/ erweitert:

cas.server.name=https://login.hs-example.de
cas.server.prefix=${cas.server.name}/cas
cas.serviceRegistry.json.location=file:/home/pacs/xyz00/users/login/cas/services
logging.config=file:/home/pacs/xyz00/users/login/cas/conf/log4j2.xml
logging.level.org.apereo=DEBUG
cas.authn.jdbc.query[0].sql=SELECT * FROM USERS WHERE UID=?
cas.authn.jdbc.query[0].url=jdbc:postgresql://localhost/xyz00_cas
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.PostgreSQL92Dialect
cas.authn.jdbc.query[0].user=xyz00_cas
cas.authn.jdbc.query[0].password=Ein_schlechtes_Passwort
cas.authn.jdbc.query[0].driverClass=org.postgresql.Driver
cas.authn.jdbc.query[0].fieldPassword=PSW
cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.accept.users=

Hier ein Beispiel für eine PostgreSQL-Datenbank mit einer Tabelle USERS mit den Spalten UID und PSW. Die Spalte UID enthält den Login-Namen des Users, die Spalte PSW das Passwort mit dem BCrypt-Algorithmus verschlüsselt.

Die Zeile cas.authn.accept.users= deaktiviert das Default-Login als User casuser mit Passwort Mellon.

Achtung: Das Spring-Security Framework erwartet das BCrypt-Passwort mit der Kennung $2a$ als erste Zeichen des Passwortfeldes. Die PHP-Funktion password_hash schreibt $2y$ Wenn eine PHP-Passwort-Datenbank genutzt wird, muss hier ggf. eine VIEW in der Datenbank helfen.

Grafische Anpassung der CAS Login-Seiten

Die Anpassungen der Login-Seite und anderer Teile der Browser-Anwendung ist vorgesehen. Eine Anleitung findet sich unter Link [7] und [4].

Links

[1] https://de.wikipedia.org/wiki/Central_Authentication_Service

[2] https://www.apereo.org/projects/cas

[3] https://github.com/apereo/cas-overlay-template

[4] https://dacurry-tns.github.io/deploying-apereo-cas/

[5] https://apereo.github.io/2017/02/22/cas51-dbauthn-tutorial/

[6] https://apereo.github.io/2017/02/02/cas51-authn-handlers/

[7] https://apereo.github.io/2018/06/10/cas-userinterface-customizations/

[8] https://apereo.github.io/tags/#CAS

[9] https://iam.uconn.edu/java-cas-client-installation-and-configuration/

[10] https://fawnoos.com/2022/08/06/cas66-gettingstarted-overlay/

[11] https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/cas Ansible Playbook