Configuration of the CAS Infrastructure on the Errigal IDMS is outlined on the bitbucket repo
https://bitbucket.org/errigal/cas-overlay-template/overview
Errigal's Single Sign On Implementation uses https://www.apereo.org/projects/cas, the WAR overlay project is used and Errigal's modifications are stored in bitbucket.
CAS authenticates selected Services against a number of Authentication Handlers. The configuration of these are outlined in the Configuration section.
From a high level, the authentication process is:
This process is described here https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol.html but the main points are copied below.
The CAS protocol is a simple and powerful ticket-based protocol developed exclusively for CAS. A complete protocol specification may be found here.
It involves one or many clients and one server. Clients are embedded in CASified applications (called “CAS services”) whereas the CAS server is a standalone component:
The CAS server is responsible for authenticating users and granting accesses to applications The CAS clients protect the CAS applications and retrieve the identity of the granted users from the CAS server. The key concepts are:
The TGT (Ticket Granting Ticket), stored in the CASTGC cookie, represents a SSO session for a user The ST (Service Ticket), transmitted as a GET parameter in urls, stands for the access granted by the CAS server to the CASified application for a specific user. Specification versions
The current CAS protocol specification is 3.x. The actual protocol specification is available at CAS-Protocol-Specification, which is hereby implemented by the Apereo CAS Server as the official reference implementation. It’s mainly a capture of the most common enhancements built on top of the CAS protocol revision 2.0. Among all features, the most noticeable update between versions 2.0 and 3.0 is the ability to return the authentication/user attributes through the new /p3/serviceValidate response (in addition to the /serviceValidate endpoint, already existing for CAS 2.0 protocol).
Exception:
2018-11-30 07:32:06,013 [ajp-bio-8012-exec-37] ERROR util.CommonUtils - Received fatal alert: protocol_version javax.net.ssl.SSLException: Received fatal alert: protocol_version at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:328) at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:305) at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:50) at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:207) at com.errigal.snmpmanager.ShiroCasRealm.authenticate(ShiroCasRealm.groovy:26) at org.apache.shiro.grails.RealmWrapper.getAuthenticationInfo(RealmWrapper.groovy:59) at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doMultiRealmAuthentication(ModularRealmAuthenticator.java:219) at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:269) at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198) at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106) at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:270) at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256) at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53) at org.apache.shiro.cas.CasFilter.onAccessDenied(CasFilter.java:85) at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133) at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162) at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203) at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178) at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:76) at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) 2018-11-30 07:32:06,013 [ajp-bio-8012-exec-37] INFO app.realm - Unable to authenticate with com.errigal.snmpmanager.ShiroCasRealm - javax.net.ssl.SSLException: Received fatal alert: protocol_version 2018-11-30 07:32:06,506 [ajp-bio-8012-exec-33] INFO snmpmanager.AuthController - SSOFAILURE - check the grails and cas server logs, redirecting to fallback login
Resolution:
The following parameters are required in the deployed *Config.groovy, e.g. SnmpManagerConfig.groovy, for SSO to work
grails.serverURL='https://nocportal.extenetsystems.com/SnmpManager' enableSingleSignOn = true security.shiro.cas.serverUrl = 'https://nocportal.extenetsystems.com/cas'
To access an application on a specific handler, you need to instantiate the fallback URL
http://qaapps1.err:8082/SnmpManager/auth/login?fallback=true
You are then free to access the application handler as normal
SSO can be disabled via *Config.groovy, set
enableSingleSignOn = false
and restart the application. Note if restarting in production, the customer needs to be notified, alarms acknowledge etc.
Accessible via port 9418
The distributed ticket cache is an in memory, distributed hazelcast instance, please see the bitbucket configuration page.
All logging is prepended with com.hazelcast., for example, when you start up the second handler in the cluster, you should see logging like
2016-08-16 05:38:33,721 INFO [com.hazelcast.nio.tcp.TcpIpConnectionManager] - [ccicerrigalapps1]:5701 [dev] [3.6.2] Established socket connection between /10.30.95.51:5701 and /10.30.95.52:57788
2016-08-16 05:38:40,710 INFO [com.hazelcast.cluster.ClusterService] - [ccicerrigalapps1]:5701 [dev] [3.6.2]
Members [2] {
Member [ccicerrigalapps1]:5701 this
Member [ccicerrigalapps2]:5701
}
If you attempt to log into a CAS managed service and you receive the error
Application Not Authorized to Use CAS The application you attempted to authenticate to is not authorized to use CAS
This means that the application you are trying to access is not configured as a service. The service is defined in as the service parameter of the URL
https://qalb1.err/cas/login?service=https://qalb1.err/SnmpManager/shiro-cas
These services are configured as JSON files in /usr/local/conf/cas/services. Before adding any more files here
If you are adding a service you should note :
When a Ticket Granting Ticket is created, the following logging is expected
2016-08-16 05:46:50,466 INFO [org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - Audit trail record BEGIN ============================================================= WHO: admin WHAT: Supplied credentials: [admin] ACTION: AUTHENTICATION_SUCCESS APPLICATION: CAS WHEN: Tue Aug 16 05:46:50 EDT 2016 CLIENT IP ADDRESS: 212.17.60.121 SERVER IP ADDRESS: scnoc.crowncastle.com ============================================================= 2016-08-16 05:46:50,474 INFO [org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - Audit trail record BEGIN ============================================================= WHO: audit:unknown WHAT: TGT-**********************************************R3CSks5QLN-ccicerrigalapps1 ACTION: TICKET_GRANTING_TICKET_CREATED APPLICATION: CAS WHEN: Tue Aug 16 05:46:50 EDT 2016 CLIENT IP ADDRESS: 212.17.60.121 SERVER IP ADDRESS: scnoc.crowncastle.com =============================================================
A Service Ticket for the same user looks like:
2016-08-16 05:46:50,502 INFO [org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - Audit trail record BEGIN ============================================================= WHO: admin WHAT: ST-3-bOuFCpfRHx926yFSR7UD-ccicerrigalapps1 for http://localhost:8080/NocPortal/shiro-cas ACTION: SERVICE_TICKET_CREATED APPLICATION: CAS WHEN: Tue Aug 16 05:46:50 EDT 2016 CLIENT IP ADDRESS: 212.17.60.121 SERVER IP ADDRESS: scnoc.crowncastle.com =============================================================
If you are setting up a CAS instance on QA for example, you will need a self signed cert. If your system is publicly accessible, a cert from a CA like godaddy is recommended as there should be less configuration or trouble shooting, as used in https://idmsqa.errigal.com/
For information on creating self signed certs see
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="/home/john/.keystore" keystorePass="n******1"
clientAuth="false" sslProtocol="TLS"
/>
Used in Support Page project using Grails 3.2.6 on March 2017
compile 'org.grails.plugins:spring-security-core:3.1.1' compile 'org.grails.plugins:spring-security-cas:3.0.0'
You need to create User Domain using Spring Security.
grails s2-quickstart com.yourapp User Role
By default, you have to specify @Secure annotation to all controller.
You can change this by editing staticRules in application.groovy http://grails-plugins.github.io/grails-spring-security-core/v3/index.html#requestMappings
CAS Plugin document mentions that proxyCallbackUrl and proxyReceptorUrl should be set but It isn't in our Single Sign On Implementation
---
grails:
plugin:
springsecurity:
cas:
loginUri: /login
serviceUrl: http://10.5.5.8:8088/Support/login/cas
serverUrlPrefix: http://10.5.5.8:8080/cas
If you need to change Logo and Poweredby Image, open cas-overlay-template and edit top.jsp which is located in src/main/webapp/WEB_INF/view/default/ui/includes
On the load balancer:
/etc/httpd/conf/mod-jk.conf add: JkMount /search/ SnmpManagerLoadBalancer JkMount /search/* SnmpManagerLoadBalancer JkMount /search SnmpManagerLoadBalancer
/etc/httpd/conf/workers.conf add the SnmpManagerLoadBalancer to worker.list At the end: worker.SnmpManagerLoadBalancer.balance_workers=SnmpManagerWorker1 And where the workers are: worker.SnmpManagerLoadBalancer.type=lb worker.SnmpManagerLoadBalancer.sticky_session=1 worker.SnmpManagerWorker1.reference=worker.ajptemplate worker.SnmpManagerWorker1.host=qaapps1.err worker.SnmpManagerWorker1.port=8096 worker.SnmpManagerWorker1.reply_timeout=600000
Finally, restart the HTTPD so that the new settings take effect:
sudo service httpd restart
To debug, tail the following logs:
/var/log/httpd/error_log /var/log/httpd/mod_jk.log