jasig CAS upgrade + OpenID setup
In our project based until today on jasig cas 4.0.3
and pac4j 1.4.2-SNAPSHOT
, after simply bumping jasig cas version from 4.0.3
to 4.0.4
(the latest stable as of today 2015-08-13)
bash-3.2$ git diff
diff --git a/pom.xml b/pom.xml
index 9c79ae9..35cc2e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -159,10 +159,16 @@
<version>${pac4j.version}</version>
</dependency>
+ <!-- NOTE: as of cas.version 4.0.4 we need to include this -->
+ <dependency>
+ <groupId>org.restlet.jee</groupId>
+ <artifactId>org.restlet</artifactId>
+ <version>2.1.0</version>
+ </dependency>
</dependencies>
<properties>
- <cas.version>4.0.3</cas.version>
+ <cas.version>4.0.4</cas.version>
<pac4j.version>1.4.2-SNAPSHOT</pac4j.version>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
@@ -189,5 +195,9 @@
<enabled>false</enabled>
</snapshots>
</repository>
+ <repository>
+ <id>sonatype-forge</id>
+ <url>https://repository.sonatype.org/content/groups/forge/</url>
+ </repository>
</repositories>
</project>
rebuilding and redeploying, cas crashed on deploy with the following exception:
2015-08-13 03:57:01,656 ERROR [org.springframework.web.servlet.DispatcherServlet] - <Context initialization failed>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientAction' defined in ServletContext resource [/WEB-INF/cas-servlet.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/pac4j/core/client/Mechanism
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1051)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:955)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.jasig.cas.web.init.SafeDispatcherServlet.init(SafeDispatcherServlet.java:76)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1279)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1192)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5210)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5493)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
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)
Caused by: java.lang.NoClassDefFoundError: org/pac4j/core/client/Mechanism
at org.jasig.cas.support.pac4j.web.flow.ClientAction.<clinit>(ClientAction.java:91)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:121)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
... 35 more
Caused by: java.lang.ClassNotFoundException: org.pac4j.core.client.Mechanism
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 43 more
2015-08-13 03:57:01,667 ERROR [org.jasig.cas.web.init.SafeDispatcherServlet] - <SafeDispatcherServlet:
The Spring DispatcherServlet we wrap threw on init.
But for our having caught this error, the servlet would not have initialized.>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientAction' defined in ServletContext resource [/WEB-INF/cas-servlet.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/pac4j/core/client/Mechanism
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1051)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:955)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.jasig.cas.web.init.SafeDispatcherServlet.init(SafeDispatcherServlet.java:76)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1279)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1192)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5210)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5493)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
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)
Caused by: java.lang.NoClassDefFoundError: org/pac4j/core/client/Mechanism
at org.jasig.cas.support.pac4j.web.flow.ClientAction.<clinit>(ClientAction.java:91)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:121)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
... 35 more
Caused by: java.lang.ClassNotFoundException: org.pac4j.core.client.Mechanism
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 43 more
conclussion/assumption:
If you want to use jasig cas >= 4.0.4
you HAVE TO use/upgrade pac4j to 1.7.1
.
cas.properties
added in ala-cas-2.0These are the new properties that were added to cas.properties
to support the register+login with Facebook/Google/Twitter credentials:
# ...
# TODO: maybe given the number of arguments we should use "named" arguments:
# call sp_create_user(@email := ?,
# @firstname := ?,
# @lastname := ?,
# @password := ?,
# @city := ?,
# @organisation := ?,
# @primaryUserType := ?,
# @secondaryUserType := ?,
# @ausstate := ?,
# @telephone := ?) #
userStore.create.sql.query=call sp_create_user(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
# https://jasig.github.io/cas/4.0.x/installation/Configuring-Authentication-Components.html#long-term-authentication
rememberMeDuration=1209600
# automatic registration ALA user password
user.create.password=
# OAuth callback URL
pac4j.callback.url=https://nci-cas4.ala.org.au/cas/login
#facebook
pac4j.facebook.consumer.key=
pac4j.facebook.consumer.secret=
# google
pac4j.google.consumer.key=
pac4j.google.consumer.secret=
# twitter
pac4j.twitter.consumer.key=
pac4j.twitter.consumer.secret=
# github
pac4j.github.consumer.key=
pac4j.github.consumer.secret=
# linkedin
pac4j.linkedin.consumer.key=
pac4j.linkedin.consumer.secret=
# windows live
pac4j.windows.consumer.key=
pac4j.windows.consumer.secret=
# yahoo OAuth and OpenID
pac4j.yahoo.consumer.key=
pac4j.yahoo.consumer.secret=
jasig cas-4.0.x
in order to enable it, set the cas.logout.followServiceRedirects
property in the cas.properties
to true
:##
# 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
url
(the grails apps are passing appUrl
that is getting translated to url
by the ala-auth-plugin) HOWEVER jasig cas-4.0.x
expects the redirect to on logout URL to be passed in an argument named service.create (or copy) basic jasig cas-4.0.1 maven overlay pom.xml file
build it: mvn clean package
test: deploy the generated target/cas.war
file and test if you can login with the test/demo static username password credentials (casuser/Mellon); make sure cas is able to find cas.properties
and log4j.xml
file; for deployment I scp
the generated cas.war
file onto my dev vm into the /tmp
dir, then run a modified ansible script that installs cas.war
from /tmp
instead of the maven repository
extract all the xml
files in WEB-INF/
from the generated target/cas.war
file and add them to src/main/webapp/WEB-INF
; we do know because this is an upgrade from cas-3.4.2 that we are going to customize (most of?) them as we progress; once we finished we can go back and remove/delete any unmodified files from the boilerplates.
extract cas.properties
and store them somewhere on your test vm (for example /etc/cas/cas-4.0.1.properties
and /etc/cas/cas-4.1.0.properties
, etc.), exclude WEB-INF/cas.properties
(and WEB-INF/classes/log4j.xml
) from the maven overlay in your pom.xml
/etc/cas/cas-4.0.1.properties
with your server name, hostname, db credentials, etc./etc/cas/cas-4.0.1.properties
to load /etc/cas/log4j.xml
/etc/cas/log4j.xml
log file paths for cas.log
, for example: /var/log/tomcat7/cas.log
showstopper BUG fix/workaround: (might be tomcat specific and things will work OK in jetty) once i added cas-server-webapp-support
as a dependency into the pom.xml
cas threw an exception on deploy and wasn't working, after some googling i found a description of this bug (fortunatelly with a workaround); although the bug reports claim the bug was fixed that seems to be not the case, both of my cas boilerplates were affected (cas-4.0.1
and cas-4.1.0-SNAPSHOT
)
next step is to replace the test/demo authenticator with org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler
cookie value encryption
showstopper BUG for jasig cas-4.1.0-SNAPSHOT
hopefuly tomcat7
specific, and development/test will be able to progress with jetty-9.2.10
; if you only include cas-server-support-saml
in your pom.xml
tomcat-7.0.52
/cas.war
throws an exception (possible reason/solution) on deployment/startup:
******************** Welcome to CAS ********************
CAS Version: 4.1.0-SNAPSHOT Java Home: /usr/lib/jvm/java-7-oracle/jre Java Vendor: Oracle Corporation Java Version: 1.7.0_80 OS Architecture: amd64 OS Name: Linux OS Version: 3.13.0-52-generic
log4j:WARN No appenders could be found for logger (org.jboss.logging). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. 2015-05-15 04:52:23,981 INFO [org.jasig.cas.services.DefaultServicesManagerImpl] - <Loaded 2 services.> 2015-05-15 04:52:29,888 WARN [org.springframework.web.context.support.XmlWebApplicationContext] - <Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shibboleth.ParserPool' defined in URL [jar:file:/var/lib/tomcat7/webapps/cas/WEB-INF/lib/cas-server-support-saml-4.1.0-SNAPSHOT.jar!/META-INF/spring/opensaml-config.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: com.sun.org.apache.xerces.internal.util.SecurityManager cannot be cast to org.apache.xerces.util.SecurityManager at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.run(FutureTask.java:262) 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) Caused by: java.lang.IllegalArgumentException: com.sun.org.apache.xerces.internal.util.SecurityManager cannot be cast to org.apache.xerces.util.SecurityManager at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(Unknown Source) at net.shibboleth.utilities.java.support.xml.BasicParserPool.doInitialize(BasicParserPool.java:570) at net.shibboleth.utilities.java.support.component.AbstractInitializableComponent.initialize(AbstractInitializableComponent.java:61) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1702) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1641) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ... 27 more
2015-05-15 04:52:30,018 INFO [org.jasig.cas.util.AutowiringSchedulerFactoryBean] - May 15, 2015 4:52:30 AM org.apache.catalina.core.StandardContext startInternal SEVERE: Error listenerStart May 15, 2015 4:52:30 AM org.apache.catalina.core.StandardContext startInternal SEVERE: Context [/cas] startup failed due to previous errors
- another `cas-server-support-saml` BUG (**hopefully tomcat specific**, and will work in jetty); `ala-cas-1.3.1` uses `org.jasig.cas.authentication.SamlAuthenticationMetaDataPopulator`, adding this to:
- `cas-4.0.1` makes `cas.war` to crash silently (no error details) on startup/deployment
- `cas-4.1.0-SNAPSHOT` makes `cas.war` to crash with the above error/exception (same error, simply because `cas-server-support-saml` is included in `pom.xml` as a dependency)
- some good news: https://github.com/leleuj/cas-pac4j-oauth-demo (**git branch 4.0.x**) delegated authentication to another cas server (i used https://auth.ala.org.au/cas/login) works! (see the [alternative deployment diagram](https://gist.github.com/mbohun/38fa53c5fd03ecfd9bbc#file-ala-cas-upgrade-01-png))
- **more good news**: https://github.com/leleuj/cas-pac4j-oauth-demo (**git branch master**) delegated authentication to another cas server (i used https://auth.ala.org.au/cas/login) **AND** delegated authentication to twitter (OAuth1.0) works! (see the [alternative deployment diagram](https://gist.github.com/mbohun/38fa53c5fd03ecfd9bbc#file-ala-cas-upgrade-01-png))
- **more good news**: managed to get `cas-4.0.1/pac4j-1.4.2-SNAPSHOT` working with both: existing ala-cas sql authentication **AND** delegated authentication (with Twitter, Facebook, etc.)
####refactoring
- cleanup: [**No resolver configured for ALAClientAuthenticationHandler**](https://github.com/Jasig/cas/blob/4.0.x/cas-server-core/src/main/java/org/jasig/cas/authentication/PolicyBasedAuthenticationManager.java#L214) check if we can split `ALAClientAuthenticationHandler` from the "resolver" (at the moment non-existent, could be called `ALADelegateAuthenticationResolver`), and register them in the `PolicyBasedAuthenticationManager.handlerResolverMap` **NOTE:** this seems to be at the moment **NOT** supported by `cas-4.0.1` where they seem to be assuming that the cas client does want to receive **only** the attributes Facebook/Google/GitHub/Twitter/LinkedIn/etc sent (**BUT** that is clearly not what we want/need for ALA); however it would be nice to have the authentication and resolver code separated.
2015-06-04 04:43:43,008 INFO [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] - <ALAClientAuthenticationHandler successfully authenticated org.jasig.cas.support.pac4j.authentication.principal.ClientCredential@63881288> 2015-06-04 04:43:43,017 DEBUG [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] - <No resolver configured for ALAClientAuthenticationHandler. Falling back to handler principal martin.bohun@gmail.com> 2015-06-04 04:43:43,018 INFO [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] - <Authenticated martin.bohun@gmail.com with credentials [org.jasig.cas.support.pac4j.authentication.principal.ClientCredential@63881288].> 2015-06-04 04:43:43,018 DEBUG [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] - <Attribute map for martin.bohun@gmail.com: {authority=ROLE_USER, email=martin.bohun@gmail.com, userid=2, lastname=Bohun, firstname=Martin}>
####resources
- [social buttons for Bootstrap](https://lipis.github.io/bootstrap-social), example:
![Alt text](https://lipis.github.io/bootstrap-social/assets/img/bootstrap-social.png "bootstrap social")
####misc
- connect to myslq db over a ssh tunnel:
- `ssh -f -i ~/.ssh/nci-key.pem ubuntu@nci-cas4.ala.org.au -L 3333:nci-cas4.ala.org.au:3306 -N`
- then point [MySQL Workbench](https://www.mysql.com/products/workbench) at `127.0.0.1:3333`
- test
```jsp
<a href="${FacebookClientUrl}">Authenticate with Facebook</a> <br />
<br />
<a href="${TwitterClientUrl}"><img src="images/sign-in-with-twitter-gray.png"></img></a><br />
<br />
<a href="${GitHubClientUrl}&scope=user:email">Authenticate with GitHub</a><br />
<br />
<a href="${Google2ClientUrl}">Authenticate with Google</a><br />
<br />
<a href="${LinkedIn2ClientUrl}">Authenticate with LinkedIn</a><br />
<br />
<!-- NOTE: in order to access the email address you need to request the OAuth scope 'wl.emails';
pac4j 1.4.2-SNAPSHOT has currently (as of 2015-06-13) hardcoded scope 'wl.basic'
-->
<a href="${WindowsLiveClientUrl}&scope=wl.emails">Authenticate with Windows Live</a><br />
<br />
###Live DEMO
130.56.244.15 nci-cas4.ala.org.au
to your /etc/hosts
file; (C:\Windows\System32\drivers\etc\hosts
in Windows)My profile
link under ALA accounts
Tested with the following versions of:
2015-05-08
, limited functionality because of pac4j-1.4.x)2015-06-13
, limited functionality because of pac4j-1.4.x)2015-07-10
, limited functionality because of pac4j-1.4.x)2015-07-16
cas-4.0.x is compatible with pac4j-1.7.x)UPDATE as of 2015-07-16 jasig cas-4.0.x
is compatible with pac4j-1.7 this is going to be released in jasig cas-4.0.4
NOTE about pac4j/cas compatibility: "pac4j 1.6 is not compatible with CAS server v4.0.0
, it will be with CAS server v4.1.0. In your case, you need to inherit a new FixedYahooClient from the current YahooClient and change the endpoint using HTTPS." by leleuj 2014-12-27 source
NOTE about pac4j 1.4.x
limited functionality (and implemented workarouds):
pac4j-saml
); pac4j-saml
was added only in later version of pac4j###howto
boilerplates created:
github repo/project | jasig cas version | pac4j version |
---|---|---|
jasig-cas-4.0.1-overlay-template | 4.0.1 | 1.4.2-SNAPSHOT |
jasig-cas-4.1.0-overlay-template | 4.1.0-SNAPSHOT | 1.7 |
notes/info:
org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler
(and passwordEncoder
(custom? default?)) - deploy and verify the loginorg.jasig.cas.support.pac4j.authentication.handler.support.ClientAuthenticationHandler
cas-4.1.0-SNAPSHOT
####clients pac4j
<=cas-4.0.3 / pac4j-1.4.x OLD
http://blog.takipi.com/tutorial-how-to-implement-java-oauth-2-0-to-sign-in-with-github-and-google
http://openid.net/specs/openid-connect-basic-1_0-28.html#StandardClaims
https://stackoverflow.com/questions/25153324/jasig-cas-4-0-0-google-oauth-exception
<bean id="google1" class="org.pac4j.oauth.client.Google2Client">
<property name="key" value="<key>" />
<property name="secret" value="<secret_value>" />
<property name="scope" value="EMAIL_AND_PROFILE" />
</bean>
login into the gmail account you want to use to create the OAuth app
from the pull down menu in the top left corner chose Create a project...
enter the new project's name (for example: "Atlas of Living Australia OAuth app") and click Create
from the sidebar menu on the left chose Consent screen
under APIs & auth
Save
buttonfrom the sidebar menu on the left chose Credentials
under APIs & auth
Create new Client ID
buttonApplication type
(Web application
for webapp; Installed application
for Android or iBad )Authorized JavaScript origins
(in our (ALA) case: https://auth.ala.org.au)Authorized redirect URIs
(in our (ALA) case: https://auth.ala.org.au/cas/login?client_name=Google2Client)>=cas-4.0.4 / pac4j-1.7.x NEW
Create New App
buttonPermissions
tab/screen an extra section called Additional permissions with a checkbox Request email addresses from users, in order to enable the checkbox and update your app's settings, you have to provide Privacy Policy URL and Terms of Service URL in the app's Settings
tab/screenGitHub
created official ALA OAuth app: https://github.com/organizations/AtlasOfLivingAustralia/settings/applications
login into the github account you want to use to create the OAuth app and go to the github organisation this app is for
go to: https://github.com/settings/developers and click the Register new application
button
fill in all the required details, set app icon, etc.
use user:email scope for a read-only access to user's deatils including email
My Apps
(or go directly to: https://www.linkedin.com/developer/apps)Create Application
buttonSubmit
buttonDefault Application Permissions
select r_basicprofile and r_emailaddressConsumer Key
for your app. (meaning that everytime you want/need to adjust the OAuth scope, you will re-generate the Consumer Key
and have to update/adjust all relevant config files accordingly, for example /etc/cas/cas.properties
)Windows Live
created official ALA Windows Live OAuth app:
atlasoflivingaustralia@hotmail.com
login into your windows (outlook or hotmail) account
go to: https://account.live.com/developers/applications/create
test
pac4j 1.4.x
has a hardcoded scope to wl.basic
, in order to get email one has to request scope wl.emails
https://msdn.microsoft.com/en-us/library/hh243646.aspx, however/luckily the different/or additional scope-s can be easily added into the URL in the casLoginView.jsp
:
<!-- NOTE: in order to access the email address you need to request the OAuth scope 'wl.emails';
pac4j 1.4.2-SNAPSHOT has currently (as of 2015-06-13) hardcoded scope 'wl.basic'
-->
<a href="${WindowsLiveClientUrl}&scope=wl.emails">Authenticate with Windows Live</a><br />
3.1 TODO: add & test OpenID Connect (google deprecated OpenID, replacing it with OpenID Connect in April 2015) - https://developers.google.com/identity/protocols/OpenIDConnect
3.2 TODO: Nick suggested adding support for a login/registration with Australian Access Federation credentials - - https://github.com/ausaccessfed - AAF login page - AAF attributes we are mainly after the email stored in mail AFF core attribute - https://wiki.oasis-open.org/security/Saml2TechOverview - http://blog.samlsecurity.com/search?q=opensaml - http://docs.spring.io/spring-security-saml/docs/1.0.x/reference/html/chapter-quick-start.html - https://github.com/onelogin/java-saml - https://wiki.shibboleth.net/confluence/display/OpenSAML/Home - https://technical.bestgrid.org/index.php/Vladimir's_general_Shibboleth_notes - http://blog.samlsecurity.com/ - SAML tracer for Firefox - https://www.testshib.org
https://wiki.jasig.org/pages/viewpage.action?pageId=57577635
https://wiki.jasig.org/pages/viewpage.action?pageId=56164890
cas-pac4j-oauth-client-demo twitter auth results:
git branch | cas | pac4j | servlet container | result |
---|---|---|---|---|
master | 4.1.0-SNAPSHOT | 1.7.0 | tomcat-7.0.52 | OK |
4.0.x | 4.0.1 | 1.4.1 | tomcat-7.0.52 | FAIL |
4.0.x | 4.0.1 | 1.4.2-SNAPSHOT | tomcat-7.0.52 | OK |
TODO | TODO | TODO | jetty |
diff --git a/src/main/java/org/jasig/cas/web/flow/LogoutAction.java b/src/main/java/org/jasig/cas/web/flow/LogoutAction.java
index 8db7372..2db089e 100644
--- a/src/main/java/org/jasig/cas/web/flow/LogoutAction.java
+++ b/src/main/java/org/jasig/cas/web/flow/LogoutAction.java
@@ -72,7 +72,7 @@ public final class LogoutAction extends AbstractLogoutAction {
}
}
- final String service = request.getParameter("service");
+ final String service = request.getParameter("url"); //NOTE: *ALL* the existing ALA apps (cas clients) do use parameter named "url"
if (this.followServiceRedirects && service != null) {
final RegisteredService rService = this.servicesManager.findServiceBy(new SimpleWebApplicationServiceImpl(service));
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 4f6a3b5..aa4d552 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -47,7 +47,7 @@
<filter-class>org.jasig.cas.security.RequestParameterPolicyEnforcementFilter</filter-class>
<init-param>
<param-name>parametersToCheck</param-name>
- <param-value>ticket service renew gateway warn target SAMLart pgtUrl pgt pgtId pgtIou targetService</param-value>
+ <param-value>ticket url renew gateway warn target SAMLart pgtUrl pgt pgtId pgtIou targetService</param-value>^M
</init-param>
<init-param>
<param-name>charactersToForbid</param-name>