Building CAS client
Template setup
We will have three templates for this. Two are the index.php pages that were discussed on the previous page. The third is hte cas.conf file which will be placed within /etc/httpd/conf.d/.
We're only doing this for the development environment, but if you need CAS clients for prod or test, you can include a separate file for each. Only the CAS server name, or possibly the Certificate section at the end, will differ here.
roles/cas-client/templates/dev-cas-client.conf.j2:
LoadModule auth_cas_module modules/mod_auth_cas.so
<Directory "/var/www/html/secured-by-cas">
<IfModule mod_auth_cas.c>
AuthType CAS
</IfModule>
Require valid-user
</Directory>
<IfModule mod_auth_cas.c>
CASLoginUrl https://{{ CAS_DEV_URL }}/cas/login
CASValidateUrl https://{{ CAS_DEV_URL }}/cas/serviceValidate
CASCookiePath /var/cache/httpd/mod_auth_cas/
CASSSOEnabled On
CASDebug Off
CASAttributePreffix CAS-
# Set the following instead you're having issues:
#LogLevel Debug
#CASDebug On
# Set the following if you're using a self-signed or other non-commercially signed cert
# such as from a local CA
CASCertificatePath /etc/pki/tls/certs/dev-cas.crt
</IfModule>
Setup certificate
If you're using a non-commercially signed certificate - you'll need to tell the CAS client where it is. Easiest way to do this is to download that into the template directory and have a task ensure it is referenced in the CAS config.
If you're using a self-signed cert, or a local certificate authority, copy that certificate to your templates directory as dev-cas.crt (it will have to be referenced by name in dev-cas-client.conf.j2.
Task setup
This is a small task - but I still prefer to use sub-tasks in my main.yml file. It makes it easier to expand it later.
roles/cas-client/tasks/main.yml:
---
# tasks file for cas-client
- include_tasks: setup-cas-client.yml
- include_tasks: setup-test-pages.yml
# The following is only needed if you are using a non-commercially signed cert in
# your development or test environments.
- include_tasks: non-commercial-cert.yml
setup-cas-client.yml task
Then you'll create 'setup-cas-client.yml'. It will do the following:
- Ensure the prerequisite packages to build the CAS client are installed
- Yes - some of these were installed by earlier playbooks, but you may want to have the CAS client installed on places other than the CAS server.
- Check if the CAS client is already installed (if so - the rest is ignored via the when statements)
- Download the source from Apereo's github, unpack it, configure and compile it
- Runs make install (to put mod_auth_cas.so in the httpd modules directory)
- Places the cas-client.conf into /etc/httpd/conf.d
- Reloads Apache httpd (if necessary)
roles/cas-client/tasks/setup-cas-client.yml:
---
- name: Setup prerequisite dnf packages
ansible.builtin.dnf:
name:
- gcc
- httpd
- httpd-devel
- libcurl-devel
- libtool
- make
- openssl-devel
- pcre-devel
- php
- redhat-rpm-config
state: present
- name: Check if CAS client is already installed
ansible.builtin.stat:
path: /etc/httpd/modules/mod_auth_cas.so
register: cas_client
- name: Check if cas client zip file exists
ansible.builtin.stat:
path: "/tmp/cas-client.zip"
register: cas_client_zip
# Only download source zip if it isn't already downloaded
# and the CAS client isn't already installed
- name: Download source zip when it doesn't already exist
ansible.builtin.get_url:
url: https://github.com/apereo/mod_auth_cas/archive/master.zip
dest: /tmp/cas-client.zip
mode: 0600
when: cas_client_zip.stat.exists == False and cas_client.stat.exists == False
# Only unpack archive if the cas_client isn't already installed
# and the CAS client isn't already installed
- name: Unpack cas-client source archive
ansible.builtin.unarchive:
src: "/tmp/cas-client.zip"
dest: /tmp/
remote_src: yes
when: cas_client.stat.exists == False and cas_client.stat.exists == False
# Only do this if the cas_client isn't already installed
- name: Run autoreconf for CAS client
ansible.builtin.command: "autoreconf -ivf"
args:
chdir: "/tmp/mod_auth_cas-master"
when: cas_client.stat.exists == False
- name: Run configure for CAS client
ansible.builtin.command: "./configure"
args:
chdir: "/tmp/mod_auth_cas-master"
when: cas_client.stat.exists == False
- name: Run make for CAS client
ansible.builtin.command: "make"
args:
chdir: "/tmp/mod_auth_cas-master"
when: cas_client.stat.exists == False
- name: Install CAS client
ansible.builtin.command: "make install"
args:
chdir: "/tmp/mod_auth_cas-master"
when: cas_client.stat.exists == False
notify: reload httpd
- name: Ensure CAS cookie directory exists
ansible.builtin.file:
path: /var/cache/httpd/mod_auth_cas
state: directory
owner: apache
group: apache
mode: 0700
# Replace "login6dev" with whatever you are using in your dev hosts
# We use login6deva and login6devb as our dev cas servers so it will catch both of those
- name: Setup Apache CAS config file
ansible.builtin.template:
src: dev-cas-client.conf.j2
dest: /etc/httpd/conf.d/cas-client.conf
mode: 0644
owner: root
group: root
when: ("login6dev" in inventory_hostname)
notify: reload httpd
- name: "Ensure php-fpm is set to start on boot"
ansible.builtin.systemd:
name: php-fpm
state: started
enabled: yes
setup-test-pages.yml task
The following are the contents of setup-test-pages.yml, which were created on the previous page. It will just ensure the 'secured-by-cas' directory exists, and the two index.php files are placed (one in /var/www/html, one in /var/www/html/secured-by-cas)
roles/cas-client/tasks/setup-test-pages.yml:
---
- name: Setup CAS test index page
ansible.builtin.template:
src: main-index.php
dest: /var/www/html/index.php
mode: 0755
owner: root
group: root
when: ("login6dev" in inventory_hostname)
- name: Ensure secured-by-cas directory exists
ansible.builtin.file:
path: /var/www/html/secured-by-cas
state: directory
owner: root
group: root
mode: 0755
when: ("login6dev" in inventory_hostname)
- name: Setup basic 'secured-by-cas' test index page
ansible.builtin.template:
src: basic-cas-check-index.php
dest: /var/www/html/secured-by-cas/index.php
mode: 0755
owner: root
group: root
when: ("login6dev" in inventory_hostname)
setup non-commercial-cert task
If you're using a commercially signed cert, you can ignore this section. Otherwise, you'll need to do get the the public certificate of your local certificate authority or the self-signed cert of your CAS server (or load balancer), and store it in templates/.
You'll need to reference the file name variable in CAS_DEV_CERT_FILE in vars/main.yml
roles/cas-client/tasks/non-commercial-cert.yml:
# The 'source' here - should be your self signed cert if you're using one
# In our case here - this is our local certificate authority
- name: Setup self-signed cert
ansible.builtin.template:
# Make sure to define CAS_DEV_CERT_FILE in vars/main.yml
src: {{ CAS_DEV_CERT_FILE }}.crt
dest: /etc/pki/tls/certs/{{ CAS_DEV_CERT_FILE }}.crt
mode: 0644
owner: root
group: root
when: ("login6dev" in inventory_hostname)
notify: reload httpd