How to setup CAS with LDAP authentication - active-directory

I been trying to get CAS with LDAP working on tomcat all week. If I just move the cas.war file into the webapps of tomcat it runs but I need it to check LDAP for my user data.
I added dependencies like this :
<!-- Dependance support LDAP -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>cas-server-support-ldap</artifactId>
<version>${project.version}</version>
</dependency>
And I added this :
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"
p:filter="sAMAccountName=%u"
p:searchBase="cn=Users,dc=mathieu,dc=local"
p:contextSource-ref="contextSource"
p:ignorePartialResultException="true" />
</list>
</property>
</bean>
but once I update the deployerconfigcontext.xml everything stops working
.
Can you help me?

You should have an awesome thousand line stack trace from Spring failing. Taking a guess, I expect somewhere there will be a subtle mention of not finding a "contextSource" bean:
<bean id="contextSource"
class="org.springframework.ldap.core.support.LdapContextSource"
p:url="ldaps://XX" p:userDn="XX" p:password="XX">
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.security.authentication" value="simple" />
</map>
</property>
</bean>

Related

Database Configuration In Spring As Well As Hibernate config files

I am a newbie to Spring and Hibernate.And while browsing through projects, I found database details like connection-url, username, password in both hibernate and spring xml config files.
I need to understand why we do so ?
Yes. If you using both Hibernate and Spring then you can also try like that.
You need both hibernate.cfg.xml for hibernate and ApplicationContext.xml for spring.
do like this, at first create your hibernate.cfg.xml.
i.e
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/country</property>
<property name="connection.username">root</property>
<property name="connection.password">password</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">false</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="com.hibernate.test" />
</session-factory>
</hibernate-configuration>
now create your ApplictionContext.xml,and add your hibernate.cfg.xml as properties in sessionFactory bean.
i.e
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
//package to scan for Annotated classes
<context:component-scan base-package="com.hibernate.spring" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
//add and locate the hibernate.cfg.xml here
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
</beans>
by this you only need to call Application.xml,the hibernate.cfg.xml will automatically loaded.
You have two options.
You can have hibernate to manage your database connections or you can have Spring managing your connections.
When you have Hibernate managing your connections, you only need to tell Spring where hibernate configuration is. Sorry, I couldn't find very easily an example where Hibernate manages the connections and Spring only "using" hibernate.
The other option is to use Spring to manage your connections and hbm files/annotated entities.
Here is a snippet from Spring docs
<beans>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
</beans>
and here the full documentation
http://docs.spring.io/spring/docs/4.0.5.RELEASE/spring-framework-reference/htmlsingle/#orm-hibernate
Besides very specific problems, I can't a lot of differences on using either way but I would prefer to let Spring to manage my database connections and I can let Spring to deal transactions for example and have everything centralized in the same configuration file.

Datanucleus for google cloud sql, missing org.datanucleus.store.rdbms.RDBMSStoreManager

I'm trying to have datanucleus manage my google cloud sql tables within a Google App Engine java application.
Sadly, I receive the following error message:
org.datanucleus.exceptions.ClassNotResolvedException: Class
"org.datanucleus.store.rdbms.RDBMSStoreManager" was not found
in the CLASSPATH. Please check your specification and your CLASSPATH.
But let's go with order. Here's my jdoconfig.xml
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig_3_0.xsd">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" />
<property name="javax.jdo.option.ConnectionURL" value="appengine" />
<property name="javax.jdo.option.NontransactionalRead"
value="true" />
<property name="javax.jdo.option.NontransactionalWrite"
value="true" />
<property name="javax.jdo.option.RetainValues" value="true" />
<property name="datanucleus.appengine.autoCreateDatastoreTxns"
value="false" />
<prop key="javax.jdo.option.Multithreaded">true</prop>
<property name="datanucleus.cache.level2" value="true" />
<property name="datanucleus.cache.level2.type" value="none"/>
<property name="datanucleus.cache.level1.type" value="soft"/>
<property name="datanucleus.appengine.storageVersion"
value="READ_OWNED_CHILD_KEYS_FROM_PARENTS"/>
</persistence-manager-factory>
<persistence-manager-factory name="cloud-sql">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" />
<property name="javax.jdo.option.ConnectionDriverName"
value="com.mysql.jdbc.GoogleDriver"/>
<property name="javax.jdo.option.ConnectionUserName" value="root"/>
<property name="datanucleus.autoCreateSchema" value="true"/>
</persistence-manager-factory>
</jdoconfig>
The two persistence-manager-factory declarations are one for the app engine non-relational datastore, one for google cloud sql.
The exception is thrown during construction of my SQLManager. The constructor states
#Inject
public SQLManager(final NamedQueryProvider queryProvider) {
super(queryProvider);
final Map<String, String> properties = new HashMap();
properties.put("javax.jdo.option.ConnectionURL", getConnectionUrl());
pmFactory = JDOHelper.getPersistenceManagerFactory(properties,
"cloud-sql");
}
You can say: you must miss a required jar from the classpath. However, in my pom.xml there is
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-accessplatform-jdo-rdbms</artifactId>
<version>3.3.4</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-rdbms</artifactId>
<version>3.2.8</version>
</dependency>
The second artifact is actually unneeded, since is thrown in by the first. I've put it as an initial workaround, but it isn't working.
Anyone has something like an idea? There seems to be no documentation on datanucleus+jdo+cloud sql, but since I'm using it for accessing GAE datastore, I would like to reuse the same for cloud sql.
EDIT
Here's the relevant part of stack trace. Unfortunately, I'm unable to see in log in which jars app engine is looking for.
Class "org.datanucleus.store.rdbms.RDBMSStoreManager" was not found in the CLASSPATH.
Please check your specification and your CLASSPATH.
org.datanucleus.exceptions.ClassNotResolvedException: Class
"org.datanucleus.store.rdbms.RDBMSStoreManager" was not found in the CLASSPATH. Please
check your specification and your CLASSPATH.
at org.datanucleus.JDOClassLoaderResolver.classForName(JDOClassLoaderResolver.java:245)
at org.datanucleus.plugin.NonManagedPluginRegistry.createExecutableExtension(NonManagedPluginRegistry.java:679)
at org.datanucleus.plugin.PluginManager.createExecutableExtension(PluginManager.java:290)
at org.datanucleus.NucleusContext.createStoreManagerForProperties(NucleusContext.java:410)
at org.datanucleus.NucleusContext.initialise(NucleusContext.java:280)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.freezeConfiguration(JDOPersistenceManagerFactory.java:591)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:326)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:256)
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:601)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at javax.jdo.JDOHelper$16.run(JDOHelper.java:1965)
at java.security.AccessController.doPrivileged(Native Method)
at javax.jdo.JDOHelper.invoke(JDOHelper.java:1960)
at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1128)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:808)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1093)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:960)
at com.mycompany.myproduct.mypackage.SQLManager.<init>(SQLManager.java:24)
The problem was a datanucleus jar versions mismatch.
I was using datanucleus-core, datanucleus-api-jdo etc at version 3.0.*, while datanucleus-rdbms 3.2. I've removed datanucleus-accessplatform-jdo-rdbms dependency, since I realized I didn't need all jars it brings in, and downgraded datanucleus-rdbms to 3.0.10 version. (Seems like datanucleus-appengine plugin is not yet supporting 3.2 series, that's why I preferred downgrade over upgrade).
Now I can connect to cloud sql fine.

Apache Camel message multiplexer integration pattern

I am trying to determine the best way to combine message streams from two hornetq broker instances into a single stream for processing, using Apache Camel and Spring. This is essentially the opposite of the Camel reciepient list pattern; but instead of one to many I need many to one. One idea is to implement this functionality with the direct component:
<?xml version="1.0" encoding="UTF-8"/>
<beans xmlns="..."
xmlns="...">
<!-- JMS Connection 1 -->
<bean id="jndiTemplate1" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
...Connection 1 Specific Information...
</props>
</property>
</bean>
<bean id="jmsTopicConnectionFactory1"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate1"/>
</property>
<property name="jndiName">
<value>java:jms/RemoteConnectionFactory</value>
</property>
</bean>
<bean id="jms1" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsTopicConnectionFactory1"/>
</bean>
<!-- JMS Connection 2 -->
<bean id="jndiTemplate2" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
...Connection 2 Specific Information...
</props>
</property>
</bean>
<bean id="jmsTopicConnectionFactory2"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate2"/>
</property>
<property name="jndiName">
<value>java:jms/RemoteConnectionFactory</value>
</property>
</bean>
<bean id="jms2" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsTopicConnectionFactory2"/>
</bean>
<!-- Camel route many to 1 using direct component -->
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="hornetQ_broker_1">
<from uri="jms1:topic:testTopic1">
<to uri="direct:process_message">
</route>
<route id="hornetQ_broker_2">
<from uri="jms2:topic:testTopic2">
<to uri="direct:process_message">
</route>
<route id="message_processor">
<from uri="direct:process_message">
<log message="message_processor received message">
</route>
</camelContext>
</beans>
Question: Is the above approach recommended when a many->1 integration pattern is required? If multiple Apache Camel solutions exist, what are the key performance impacts of each approach?
Runtime environment:
HornetQ brokers are JBoss EAP6.
Camel context deployed to FuseSource 4.4.1
Each entity exists on a seperate server/jvm.
Notes:
The hornetQ broker instances cannot be clustered.
The hornetQ broker instances do not contain duplicate data.
I think that your approach is valid for your scenario. However, maybe direct is not the component you need to use for this if you are running in different JVMs.
There are different components for internal queues: Direct, Direct-VM, SEDA, VM, Disruptor... but I believe all of them are if you are running in the JVM (and some of the if you just running in the same CamelContext). For more info: How do the direct, event, seda and vm endpoints compare
If you are going to have different CamelContexts across different JVM will need to use a different component.

JasperReports Server 5.2 Active Directory Integration

Apologies for yet another AD integration question :)
I've got a fresh install of JasperReports Server 5.2 on Windows Server 2008 R2 and I'm trying to configure AD authentication but logins always fail.
I've copied the sample applicationContext-externalAuth-LDAP.xml file into the WEB-INF folder and customised it:
<bean id="ldapAuthenticationProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg><ref local="ldapContextSource"/></constructor-arg>
<property name="userSearch" ref="userSearch"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg index="0"><ref local="ldapContextSource"/></constructor-arg>
<constructor-arg index="1"><value></value></constructor-arg>
<property name="groupRoleAttribute" value="cn"/>
<property name="groupSearchFilter" value="((member={0})(objectClass=group))"/>
<property name="searchSubtree" value="true"/>
<!-- Can setup additional external default roles here <property name="defaultRole" value="LDAP"/> -->
</bean>
</constructor-arg>
</bean>
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0">
<value></value>
</constructor-arg>
<constructor-arg index="1">
<value>((sAMAccountName={0})(objectClass=user))</value>
</constructor-arg>
<constructor-arg index="2">
<ref local="ldapContextSource" />
</constructor-arg>
<property name="searchSubtree">
<value>true</value>
</property>
</bean>
<bean id="ldapContextSource" class="com.jaspersoft.jasperserver.api.security.externalAuth.ldap.JSLdapContextSource">
<constructor-arg value="ldap://hostname:389/dc=domain,dc=local"/>
<!-- manager user name and password (may not be needed) -->
<property name="userDn" value="Administrator"/>
<property name="password" value="password"/>
</bean>
Actual Hostname, Domain name and Password have been removed in the above, our AD is set up a bit strangely in that users are spread across several OUs so I've left the branch DN properties empty and attempted to limit the search to entries with a certain objectClass (user or group).
I've enabled debug level logging for org.springframework.security and com.jaspersoft.jasperserver.api.security but I'm not getting anything particularly informative in the logs:
2013-09-03 10:12:32,882 DEBUG BaseAuthenticationProcessingFilter,http-bio-80-exec-6:252 - Request is to process authentication
2013-09-03 10:12:32,884 DEBUG ProviderManager,http-bio-80-exec-6:183 - Authentication attempt using org.springframework.security.providers.ldap.LdapAuthenticationProvider
2013-09-03 10:12:32,888 DEBUG FilterBasedLdapUserSearch,http-bio-80-exec-6:109 - Searching for user 'username', with user search [ searchFilter: '((sAMAccountName={0})(objectClass=user))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
2013-09-03 10:12:32,905 DEBUG SpringSecurityLdapTemplate,http-bio-80-exec-6:197 - Searching for entry in under DN 'dc=domain,dc=local', base = '', filter = '((sAMAccountName={0})(objectClass=user))'
2013-09-03 10:12:32,933 DEBUG ProviderManager,http-bio-80-exec-6:183 - Authentication attempt using com.jaspersoft.jasperserver.api.security.internalAuth.InternalDaoAuthenticationProvider
2013-09-03 10:12:32,940 WARN LoggerListener,http-bio-80-exec-6:60 - Authentication event AuthenticationFailureBadCredentialsEvent: username; details: org.springframework.security.ui.WebAuthenticationDetails#21a2c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: F8EA36A4CF952E3DE41E7211B4EB529D; exception: Bad credentials
2013-09-03 10:12:32,941 DEBUG BaseAuthenticationProcessingFilter,http-bio-80-exec-6:406 - Updated SecurityContextHolder to contain null Authentication
2013-09-03 10:12:32,941 DEBUG BaseAuthenticationProcessingFilter,http-bio-80-exec-6:412 - Authentication request failed: org.springframework.security.BadCredentialsException: Bad credentials
2013-09-03 10:12:32,943 DEBUG HttpSessionContextIntegrationFilter,http-bio-80-exec-6:255 - SecurityContextHolder now cleared, as request processing completed
Any suggestions gratefully received, I've played around with the settings in the externalAuth XML file but nothing seems to make a difference to the log or the login failures.
Cheers, Matt
Generally speaking when doing ldap searches on AD the only time a baseless search will work is when talking to the GC.
Try putting in the base of DC=domain,DC=local this should still search over your entire domain .
Also in your user and group searches it appears you are missing the & needed after the first (.
e.g.
<property name="groupSearchFilter" value="(&(member={0})(objectClass=group))"/>
and
<constructor-arg index="1">
<value>(&(sAMAccountName={0})(objectClass=user))</value>
</constructor-arg>
One last thing that I have seen that helps with the Spring LDAP is to use the DN for the bind account.
e.g.
HTH

LDAP authentication using Spring security 2.0.3

I am trying to do LDAP authentication using spring security 2.0.3
Here is my configuration
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://IP:3268"/>
<property name="base" value="dc=alliance",dc=com,OU=Users,OU=India"/>
<property name="userDn" value="sAMAccountName=username" />
<property name="password" value="password" />
</bean>
<bean id="ldapProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<sec:custom-authentication-provider/>
<constructor-arg>
<bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<!--<property name="userSearch" ref="ldapSearchBean"/>-->
<property name="userDnPatterns">
<list><value>sAMAccountName={0}</value></list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupSearchFilter" value="member={0}"/>
<property name="groupRoleAttribute" value="ou"/>
<property name="rolePrefix" value="ROLE_"/>
<property name="searchSubtree" value="true"/>
<property name="convertToUpperCase" value="true"/>
</bean>
</constructor-arg>
</bean>
Maven entry set is as below
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>2.0.3</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap</artifactId>
<version>1.2.1</version>
</dependency>
Exception I am getting is
[BindAuthenticator,2329165#qtp-24103634-0] - Failed to bind as sAMAccountName=csepena: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece
Where should i mention domain name?
If you search online for the error message, you will find something like this page of Active Directory errors, which lists your error at the top:
Common Active Directory LDAP bind errors:
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 525, v893
HEX: 0×525 – user not found
DEC: 1317 – ERROR_NO_SUCH_USER (The specified account does not exist.)
NOTE: Returns when username is invalid.
So according to AD, the user doesn't exist. You've tried to use sAMAccountName attribute as part of a DN pattern, which won't work as it is an LDAP attribute. You need to use a search to first locate a user by the value of this attribute. There are examples on how to do that elsewhere on this site and on the web. It looks like you already tried, since you commented out a search bean. If that didn't work you should have explained what went wrong in your question.
In fact, it seems likely that it failed because there are some things wrong with your context source. The value for the userDn property is wrong. It needs to be a valid distinguished name in the directory, which "sAMAccountName=username" is not. The "base" property also looks incorrect. It should generally be a tree where the root (dc=mycompany,dc=com is at the end). So it should probably be ou=mygroup,ou=mycountry,dc=mycompany,dc=com.
Finally, you shouldn't be using version 2.0.3. It has known security vulnerabilities. Always keep up to date with patches and new versions of libraries you are using - number 6 in the OWASP "top ten". It also makes sense to check the latest version in case you're encountering a bug which has been fixed.

Resources