ALA AUTH with CAS 2 - AtlasOfLivingAustralia/documentation Wiki

ALA AUTH with CAS 2

WARNING: CAS2 and this page describing Canadensys old installation of CAS2 is DEPRECATED. Please use CAS-5 playbook.

Roles included:

How to install with playbook:

CAS 2.0.4, userdetails 0.12.0

The current AUTH on ALA install is can be used with: cas2: 2.0.4
For userdetails and apikey, the version are respectively:

You need to add 2 new roles for each coming from:

The playbook will look like:

- hosts: auth
    roles:
    - common
    - java
    - postfix
    - tomcat
    - mysql
    - webserver
    - cas2
    - userdetails-cas2
    - apikey-cas2

CAS 2.0.10, userdetails 1.0.0

You will have to create a new role for CAS2 (cas2-2). This role is similar to cas2 except for schema.sql and sp_get_user_attributes.sql which need updates.\

The playbook will look like:

    roles:
    - common
    - java
    - postfix
    - tomcat
    - mysql
    - webserver
    - cas2-2
    - userdetails-cas2
    - apikey-cas2

https://github.com/bioatlas/ala-docker/blob/develop/cas2/db/2_schema.sql

USE emmet;

DROP TABLE IF EXISTS identities;
DROP TABLE IF EXISTS passwords;
DROP TABLE IF EXISTS profiles;
DROP TABLE IF EXISTS user_role;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS role;
DROP TABLE IF EXISTS auth_key;
DROP TABLE IF EXISTS authorised_system;
DROP TABLE IF EXISTS authorities;
DROP TABLE IF EXISTS c3p0TestTable;
DROP TABLE IF EXISTS mobile_user;
--
-- Table structure for table `mobile_user`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `mobile_user` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL,
  `user_name` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `auth_key`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE  IF NOT EXISTS `auth_key` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL,
  `auth_key` varchar(255) NOT NULL,
  `mobile_user_id` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `FK5563974818294D56` (`mobile_user_id`),
  CONSTRAINT `FK5563974818294D56` FOREIGN KEY (`mobile_user_id`) REFERENCES `mobile_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `authorised_system`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE  IF NOT EXISTS `authorised_system` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL,
  `host` varchar(255) NOT NULL,
  `description` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `authorities`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `authorities` (
  `userid` int(11) NOT NULL,
  `authority` varchar(30) NOT NULL,
  PRIMARY KEY  (`userid`,`authority`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `c3p0TestTable`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `c3p0TestTable` (
  `a` char(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `identities`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `identities` (
  `userid` int(11) NOT NULL,
  `identityuri` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  PRIMARY KEY  (`userid`,`identityuri`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `passwords`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
SET sql_mode = '';
CREATE TABLE IF NOT EXISTS `passwords` (
  `userid` int(11) NOT NULL,
  `password` varchar(255) NOT NULL,
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `expiry` timestamp NOT NULL default '0000-00-00 00:00:00',
  `status` varchar(10) NOT NULL,
  PRIMARY KEY  (`userid`,`password`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `profiles`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE  IF NOT EXISTS `profiles` (
  `userid` int(11) NOT NULL,
  `property` varchar(255) NOT NULL,
  `value` varchar(255) NOT NULL,
  PRIMARY KEY  (`userid`,`property`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `role`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `role` (
  `role` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  PRIMARY KEY  (`role`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

--
-- Dumping data for table `role`
--

LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES ('ROLE_ABRS_ADMIN',''),('ROLE_ABRS_INSTITUTION',''),('ROLE_ADMIN','Admin role for ALA staff'),('ROLE_API_EDITOR','Enables a user to update the online web service API'),('ROLE_APPD_USER','APPD user'),('ROLE_AVH_ADMIN',''),('ROLE_AVH_CLUB',''),('ROLE_COLLECTION_ADMIN',''),('ROLE_COLLECTION_EDITOR',''),('ROLE_COLLECTORS_ADMIN',''),('ROLE_FC_ADMIN','Admin role for the Field Capture webapp'),('ROLE_FC_OFFICER','Field Capture officer role'),('ROLE_FC_READ_ONLY','Provides read only access to all projects in the field capture system.'),('ROLE_IMAGE_ADMIN',''),('ROLE_SPATIAL_ADMIN',''),('ROLE_SYSTEM_ADMIN',''),('ROLE_USER',''),('ROLE_VP_ADMIN',''),('ROLE_VP_TEST_ADMIN','The admin role for BVP Test server'),('ROLE_VP_VALIDATOR','');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `user_role`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE IF NOT EXISTS `user_role` (
  `user_id` bigint(20) NOT NULL,
  `role_id` varchar(255) NOT NULL,
  PRIMARY KEY  (`user_id`,`role_id`),
  KEY `FK143BF46AF129182D` (`role_id`),
  CONSTRAINT `FK143BF46AF129182D` FOREIGN KEY (`role_id`) REFERENCES `role` (`role`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

--
-- Table structure for table `users`
--

SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
SET sql_mode = '';
CREATE TABLE IF NOT EXISTS `users` (
  `userid` int(11) NOT NULL auto_increment,
  `username` varchar(255) default NULL,
  `firstname` varchar(255) default NULL,
  `lastname` varchar(255) default NULL,
  `email` varchar(255) default NULL,
  `activated` char(1) NOT NULL,
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `expiry` timestamp NOT NULL default '0000-00-00 00:00:00',
  `locked` char(1) NOT NULL,
  `temp_auth_key` varchar(255) default NULL,
  PRIMARY KEY  (`userid`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=10649 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

https://github.com/bioatlas/ala-docker/blob/develop/cas2/db/3_sp_get_user_attributes.sql

USE emmet;

DROP PROCEDURE IF EXISTS sp_get_user_attributes;
delimiter //
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_get_user_attributes`(p_username varchar(255))
begin
select 'email' as 'key', email as 'value' from users where username=p_username
union select 'firstname' as 'key', firstname as 'value' from users where username=p_username
union select 'lastname' as 'key', lastname as 'value' from users where username=p_username
union select 'displayName' as 'key', profiles.value from profiles inner join users ON users.userid=profiles.userid where users.username=p_username and profiles.property='displayName'
union select 'userid' as 'key', cast(userid as char) as 'value' from users where username=p_username
union select 'authority' as 'key', group_concat(a.role_id) as 'value' from user_role a, users u where a.user_id=u.userid and u.username=p_username;
end
//
delimiter ;


DROP PROCEDURE IF EXISTS sp_get_user_authorities;
delimiter //
create procedure sp_get_user_authorities()
begin
select username, group_concat(ur.role_id) as 'authorities' from users u, user_role ur where u.userid=ur.user_id group by username;
end
//
delimiter ;


DROP PROCEDURE IF EXISTS sp_create_user;
delimiter //
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_create_user`(
`email`              varchar(255),
`firstname`          varchar(255),
`lastname`           varchar(255),
`password`           varchar(255),
`city`               varchar(255),
`organisation`       varchar(255),
`primaryUserType`    varchar(255),
`secondaryUserType`  varchar(255),
`ausstate`           varchar(255),
`telephone`          varchar(255))
BEGIN
declare userid int(11);
INSERT INTO `emmet`.`users` (`username`, `firstname`, `lastname`, `email`, `activated`, `locked`) VALUES (email, firstname, lastname, email, '1', '0');
set userid = LAST_INSERT_ID();
INSERT INTO `emmet`.`passwords` (`userid`, `password`, `status`) VALUES (userid, password, 'CURRENT');
INSERT INTO `emmet`.`user_role` (`user_id`, `role_id`) VALUES (userid, 'ROLE_USER');
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'city',              city);
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'organisation',      organisation);
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'primaryUserType',   primaryUserType);
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'secondaryUserType', secondaryUserType);
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'state',             ausstate);
INSERT INTO `emmet`.`profiles` (`userid`, `property`, `value`) VALUES (userid, 'telephone',         telephone);
END
//
delimiter ;

CAS 2.0.10 Properties:

https://github.com/bioatlas/ala-docker/blob/develop/config/cas.properties

server.name=https://auth.bioatlas.se
server.prefix=https://auth.bioatlas.se/cas
# IP address or CIDR subnet allowed to access the /status URI of CAS that exposes health check information
cas.securityContext.status.allowedSubnet=0.0.0.0

cas.themeResolver.defaultThemeName=cas-theme-default
cas.viewResolver.basename=default_views

##
# Unique CAS node name
# host.name is used to generate unique Service Ticket IDs and SAMLArtifacts.  This is usually set to the specific
# hostname of the machine running the CAS node, but it could be any label so long as it is unique in the cluster.
host.name=auth.bioatlas.se

##
# Database flavors for Hibernate
#
# One of these is needed if you are storing Services or Tickets in an RDBMS via JPA.
#
# database.hibernate.dialect=org.hibernate.dialect.OracleDialect
# database.hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
# database.hibernate.dialect=org.hibernate.dialect.HSQLDialect

##
# CAS Logout Behavior
# WEB-INF/cas-servlet.xml
#
# Specify whether CAS should redirect to the specified service parameter on /logout requests
cas.logout.followServiceRedirects=true

##
# Single Sign-On Session Timeouts
# Defaults sourced from WEB-INF/spring-configuration/ticketExpirationPolices.xml
#
# Maximum session timeout - TGT will expire in maxTimeToLiveInSeconds regardless of usage
# tgt.maxTimeToLiveInSeconds=28800
#
# Idle session timeout -  TGT will expire sooner than maxTimeToLiveInSeconds if no further requests
# for STs occur within timeToKillInSeconds
# tgt.timeToKillInSeconds=7200

##
# Service Ticket Timeout
# Default sourced from WEB-INF/spring-configuration/ticketExpirationPolices.xml
#
# Service Ticket timeout - typically kept short as a control against replay attacks, default is 10s.  You'll want to
# increase this timeout if you are manually testing service ticket creation/validation via tamperdata or similar tools
# st.timeToKillInSeconds=10

##
# Single Logout Out Callbacks
# Default sourced from WEB-INF/spring-configuration/argumentExtractorsConfiguration.xml
#
# To turn off all back channel SLO requests set slo.disabled to true
# slo.callbacks.disabled=false

##
# Service Registry Periodic Reloading Scheduler
# Default sourced from WEB-INF/spring-configuration/applicationContext.xml
#
# Force a startup delay of 2 minutes.
# service.registry.quartz.reloader.startDelay=120000
#
# Reload services every 2 minutes
# service.registry.quartz.reloader.repeatInterval=120000

##
# Log4j
# Default sourced from WEB-INF/spring-configuration/log4jConfiguration.xml:
#
# It is often time helpful to externalize log4j.xml to a system path to preserve settings between upgrades.
log4j.config.location=/data/cas/config/log4j.xml

# log4j.config.location=classpath:log4j.xml
#
# log4j refresh interval in millis
# log4j.refresh.interval=60000

##
# Password Policy
#
# Warn all users of expiration date regardless of warningDays value.
password.policy.warnAll=false

# Threshold number of days to begin displaying password expiration warnings.
password.policy.warningDays=30

# URL to which the user will be redirected to change the password.
password.policy.url=https://password.example.edu/change

cas.host=auth.bioatlas.se

cas.securityContext.serviceProperties.service=https://auth.bioatlas.se/cas/services/j_acegi_cas_security_check
cas.securityContext.serviceProperties.adminRoles=ROLE_ADMIN
cas.securityContext.casProcessingFilterEntryPoint.loginUrl=https://auth.bioatlas.se/cas/login
cas.securityContext.ticketValidator.casServerUrlPrefix=https://auth.bioatlas.se/cas

database.hibernate.dialect=org.hibernate.dialect.MySQLDialect

userStore.db.host=mysqldbcas
userStore.db.driverClassName=com.mysql.jdbc.Driver
userStore.db.url=jdbc\:mysql\://mysqldbcas/emmet
userStore.db.username=$USER_STORE_DB_USERNAME
userStore.db.password=$USER_STORE_DB_PASSWORD
userStore.db.idleConnectionTestPeriod=3600
userStore.db.automaticTestTable=c3p0TestTable

user.create.password=
userStore.password.encoding.algorithm=MD5
userStore.password.encoding.base64=true
userStore.password.encoding.salt=salt
userStore.password.sql.query=select password from passwords p, users u where u.username = ? and u.activated=1 and p.userid = u.userid and p.status='CURRENT'
userStore.attribute.sql.query=call sp_get_user_attributes(?)

ticketRegistry.db.driverClassName=com.mysql.jdbc.Driver
ticketRegistry.db.url=jdbc\:mysql\://mysqldbcas/casTicketRegistry
ticketRegistry.db.username=$TICKET_REGISTRY_DB_USERNAME
ticketRegistry.db.password=$TICKET_REGISTRY_DB_PASSWORD

userdetails.url=https://auth.bioatlas.se/userdetails
userStore.create.sql.query=call sp_create_user(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

rememberMeDuration=1209600

pac4j.callback.url=https://auth.bioatlas.se/cas/login

skin.orgNameLong=BioAtlas Sweden
skin.orgNameShort=BioAtlas
skin.homePage=https://bioatlas.se
skin.favicon=https://bioatlas.se/wp-content/themes/atlas/img/favicon/favicon.ico
skin.termsOfUse=
skin.identityProviders=
skin.allowRegister=true
skin.allowIdentityFrom=

#facebook
pac4j_facebook_consumer_key=1234567898765432
pac4j_facebook_consumer_secret=112233445566778899aabbccddeeffgg

# twitter
pac4j_twitter_consumer_key=1234567898765432
pac4j_twitter_consumer_secret=112233445566778899aabbccddeeffgg

# google
pac4j_google_consumer_key=1234567898765432
pac4j_google_consumer_secret=112233445566778899aabbccddeeffgg

# automatic registration ALA user password
user_create_password=to_be_added

# Header and footer
headerAndFooter.baseURL=https://bioatlas.se/static/bs2
ala.baseURL=https://bioatlas.se
bie.baseURL=https://bioatlas.se/ala-bie
bie.searchPath=/search

Userdetails 1.0.0 Properties:

https://github.com/bioatlas/ala-docker/blob/develop/config/userdetails-config.properties

# CAS Config
security.cas.casServerName=https://auth.bioatlas.se
security.cas.casServerUrlPrefix=https://auth.bioatlas.se/cas/
security.cas.loginUrl=https://auth.bioatlas.se/cas/login
security.cas.logoutUrl=https://auth.bioatlas.se/cas/logout
security.cas.appServerName=https://auth.bioatlas.se/userdetails/

serverURL=https://auth.bioatlas.se
serverName=https://auth.bioatlas.se
grails.serverURL=https://auth.bioatlas.se/userdetails/
grails.mail.host=mail.infrabas.se
grails.mail.port=587
[email protected]
grails.mail.password=mysecretpassword
grails.mail.props =["mail.smtp.starttls.enable":"true", "mail.smtp.port":"587"]

redirectAfterFirstLogin=https://auth.bioatlas.se/userdetails/myprofile

# Data source configuration
#dataSource.dbCreate=none
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc\:mysql\://mysqldbcas/emmet
dataSource.username=$USER_STORE_DB_USERNAME
dataSource.password=$USER_STORE_DB_PASSWORD

encoding.algorithm=MD5
encoding.salt=salt

[email protected]
homeUrl=https://bioatlas.se
mainTitle=BioAtlas Sweden
emailSenderTitle=BioAtlas Sweden
[email protected]

# Links on the profile page
sightings.url =
spatial.url =https://bioatlas.se/spatial-hub/actions/dashboard
volunteer.url =
lists.url =https://bioatlas.se/speciesList/list
biocache.search.url =https://bioatlas.se/biocache-service/occurrences/search
alerts.url =

# this property is read/used by ala-auth-plugin (included by userdetails)
userDetails.url=https://auth.bioatlas.se/userdetails/

# Header and footer
headerAndFooter.baseURL=https://bioatlas.se/static/bs3
ala.baseURL=https://bioatlas.se
bie.baseURL=https://bioatlas.se/ala-bie
bie.searchPath=/search

# Skin options
skin.orgNameLong =BioAtlas Sweden
skin.orgNameShort =BioAtlas
skin.favicon=https://bioatlas.se/wp-content/themes/atlas/img/favicon/favicon.ico
skin.homeUrl=https://bioatlas.se
# API key for external apps
webservice.apiKey=

# Default primary fields for Export to CSV functionality
admin.export.csv.primary.fields=id,userName,firstName,lastName,email,activated,locked,created

a complete install is available here: https://github.com/Canadensys/canadensys-ala-install/tree/canadensys-ala-install

ALA CAS2 behind a proxy

"You are currently accessing CAS over a non-secure connection. Single Sign On WILL NOT WORK. In order to have single sign on work, you MUST log in over HTTPS."

[User] <==(https)==> [proxy] <==(http)==> [auth]

For nginx:

server {
    server_name  your_server_name;

    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header         X-Forwarded-Host $server_name;
    proxy_set_header         X-Forwarded-Proto https;
    proxy_redirect off;
    port_in_redirect    off;

    location /cas {
        add_header Access-Control-Allow-Origin *;
        proxy_pass http://casserver:8080/cas;
    }

    location /userdetails {
        add_header Access-Control-Allow-Origin *;
        proxy_pass http://userdetails:8080/userdetails;
    }

    location /apikey {
        add_header Access-Control-Allow-Origin *;
        proxy_pass http://apikey:8080/apikey;
    }

    location / {
        add_header Access-Control-Allow-Origin *;
        proxy_pass http://casserver:8080/cas;
    }
}

For tomcat7, in /etc/tomcat7/server.xml (Ubuntu 16.04):
Comment this line \

#<!--    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443"/>-->

Add this line just after \

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" proxyPort="443" secure="true" scheme="https"/>

Thanks:

Simon, Manash, Reuben, Dave.