Spring ldap multiple group bases in authoritiespopulator - spring

Is there any way in Spring to set it up such that an authoritiespopulator will look in more than one location?
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="CN=Users" />
<property name="groupRoleAttribute" value="CN" />
<property name="searchSubtree" value="true" />
<property name="rolePrefix" value="" />
<property name="convertToUpperCase" value="false" />
</bean>
This is the general idea, but there are also groups in CN=OtherGroups, and right now they don't get loaded (obviously). However, setting the groupsearchbase (the 2nd constructor arg) to value="" results in an error:
Unprocessed Continuation Reference(s); remaining name ''
Any ideas?

Answer: set referral to follow.
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
....
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.referral" value="follow" />
</map>
</property>
</bean>

Related

How to custom Spring Batch DelimitedLineTokenizer

I have two file types to insert in database.
Format are : aa;bb;cc and aa;bb;cc;dd;ee
This is my FlatFileItemReader :
<bean name="readerContractToAddIntoPRV" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="comments" value="#" />
<property name="linesToSkip" value="1" />
<property name="strict" value="false" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="fieldSetMapper">
<bean class="net.wl.batchs.fieldSetMapper.LineToCreateIntoPrvFieldSetMapper" />
</property>
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";"/>
<property name="names" value="aa,bb,cc,dd,ee" />
</bean>
</property>
</bean>
</property>
</bean>
I want a setup that works for both types of files.
For the moment, I have this :
org.springframework.batch.item.file.transform.IncorrectTokenCountException:
Incorrect number of tokens found in record: expected 3 actual 5
Do you have any ideas?
Thank you.
Edit : After correction :
<bean name="readerContractToAddIntoPRV" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="comments" value="#" />
<property name="linesToSkip" value="1" />
<property name="strict" value="false" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper" p:lineTokenizer-ref="multilineFileTokenizer">
<property name="fieldSetMapper">
<bean class="net.wl.batchs.fieldSetMapper.LineToCreateIntoPrvFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="multilineFileTokenizer" class="org.springframework.batch.item.file.transform.PatternMatchingCompositeLineTokenizer">
<property name="tokenizers">
<map>
<entry key="*;*;*;*;*" value-ref="NSCE_ICCID_MSISDN_LOGIN_PWD"/>
<entry key="*;*;*" value-ref="NSCE_ICCID_MSISDN"/>
<entry key="*" value-ref="headerDefault"/>
</map>
</property>
</bean>
<bean id="parentLineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" abstract="true">
<property name="delimiter" value=";"/>
</bean>
<bean id="NSCE_ICCID_MSISDN_LOGIN_PWD" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn,login,pwd" />
</bean>
<bean id="NSCE_ICCID_MSISDN" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn" />
</bean>
<bean id="headerDefault" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn" />
</bean>
The issue isn't your tokenizer. What you'll have to do is use the PatternMatchingCompositeLineMapper (http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/file/mapping/PatternMatchingCompositeLineMapper.html). This will allow you to create a pattern for each line type you have and associate it with the appropriate LineTokenizer.
You can see this LineMapper in action in our samples here: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-samples/src/main/resources/jobs/multilineOrderInputTokenizers.xml

Release the attribute from CAS to Spring security

I am using a Spring security 3.X on the client side and CAS 4.0 on the server.
When i am doing CAS+Spring security integration, I am able to reach the level of ticket validation success and able to get the proper roles at the client side.
But I have added the following lines in my casServiceValidationSuccess.jsp to iterate and send the attributes in my response as my attributes are not released properly:
<cas:attributes>
<cas:user>${fn:escapeXml(assertion.primaryAuthentication.principal.id)}</cas:user>
<c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
So wants to know is there any other alternative changes to do in deployerConfigContext.xml in the CAS server side to release particular attribute-"authorities" in my case and to get the same in SPRING client side.
Find the snippets of existing deployerConfigContext.xml where trying to release "authorities" attributes:
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
<constructor-arg>
<map>
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
</map>
</constructor-arg>
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT EMAIL FROM USER_DATA WHERE UserID = ?" />
</bean>
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1" value="SELECT UserID, UserROLES FROM USER_DATA WHERE {0}" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="UserID" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="UserID" value="username" />
<entry key="UserROLES" value="UserROLES" />
</map>
</property>
</bean>
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="0"></property>
<property name="name" value="HTTP"></property>
<property name="description" value="Only Allows HTTP Urls"></property>
<property name="serviceId" value="http://**" />
<property name="usernameAttribute" value="username" />
<property name="ignoreAttributes" value="false" />
<property name="allowedAttributes">
<list>
<value>UserROLES</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
Also find the security-context.xml at the spring client side:
<security:http use-expressions="true" entry-point-ref="casAuthenticationEntryPoint"
auto-config="true">
<security:custom-filter position="CAS_FILTER"
ref="casAuthenticationFilter"></security:custom-filter>
<security:intercept-url pattern="/home" access="hasRole('ROLE_TEST')"></security:intercept-url>
<security:intercept-url pattern="/**" access="hasRole('ROLE_ANONYMOUS')"></security:intercept-url>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="casAuthenticationProvider"></security:authentication-provider>
</security:authentication-manager>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="http://localhost:7080/test/j_spring_cas_security_check"></property>
<property name="sendRenew" value="false"></property>
</bean>
<bean id="casAuthenticationFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"></property>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="http://localhost:8090/cas-server-webapp-4.0.0/login"/>
</bean>
</property>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/home.jsp"/>
</bean>
</property>
</bean>
<bean id="casAuthenticationEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl"
value="http://localhost:8090/cas-server-webapp-4.0.0/login"></property>
<property name="serviceProperties" ref="serviceProperties"></property>
</bean>
<!-- Handles the CAS ticket processing. -->
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<!-- <property name="userDetailsService" ref="userService"></property> -->
<property name="authenticationUserDetailsService" ref="authenticationUserDetailsService" />
<property name="serviceProperties" ref="serviceProperties"></property>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0"
value="http://localhost:8090/cas-server-webapp-4.0.0">
</constructor-arg>
</bean>
</property>
<property name="key" value="cas"></property>
</bean>
<bean id="authenticationUserDetailsService"
class="org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService">
<constructor-arg>
<list>
<value>UserROLES</value>
</list>
</constructor-arg>
</bean>
</beans>
Disclaimer: I'm the Chairman of CAS and founder of CAS in the cloud (https://www.casinthecloud.com).
Is your attribute person DAO referenced by your authentication handler? Does it work without Spring security doing a manual service ticket validation?

spring batch admin showing jobs as not launchable

I have a spring mvc webapp with spring batch built into it. I am having some issues getting my spring batch jobs to be launchable in the spring batch admin console. This is what I see when I go to the jobs page...
All of my jobs are coming up as launchable=false. I was wondering how I can fix this. I read some documentation about why this would be so and it said that I need to use a AutomaticJobRegistrar.
I tried this but it didn't change anything. I've put my spring batch job configuration below. Would appreciate it someone could tell me what is missing.
thanks
<beans profile="pre,prod">
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
parent="abstractCustDbJdbcDao">
<property name="transactionManager" ref="custDbTransactionManager" />
<property name="databaseType" value="db2" />
<property name="tablePrefix" value="REPMAN.BATCH_" />
</bean>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
parent="abstractCustDbJdbcDao" />
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<bean id="jobLoader" class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources" value="classpath*:/META-INF/spring/jobs/*.xml" />
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
</property>
</bean>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="dailyTranCountJobDetail" />
<ref bean="bulletinBarMsgUpdateJobDetail" />
<ref bean="updateLovCacheJobDetail" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyTranCountCronTrigger" />
<ref bean="bulletinBarMsgUpdateCronTrigger" />
<ref bean="updateLovCacheCronTrigger" />
</list>
</property>
</bean>
<!-- scheduling properties -->
<util:properties id="batchProps" location="classpath:batch.properties" />
<context:property-placeholder properties-ref="batchProps" />
<!-- triggers -->
<bean id="dailyTranCountCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dailyTranCountJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.dailyTranCounts']}" />
</bean>
<bean id="bulletinBarMsgUpdateCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="bulletinBarMsgUpdateJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.bulletinBarUpdateMsg']}" />
</bean>
<bean id="updateLovCacheCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="updateLovCacheJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.updateLovCache']}" />
</bean>
<!-- job detail -->
<bean id="dailyTranCountJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-daily-tran-counts" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="bulletinBarMsgUpdateJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-bulletin-bar-msg-update" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="updateLovCacheJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-update-lov-cache" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
</beans>
There are a few things this could be:
Where is the XML file you reference above located? It needs to be the META-INF/spring/batch/jobs directory in your WAR file (that's where Spring Batch Admin will look).
Don't configure common components in your XML file. That includes the jobLauncher, jobRepository, jobExplorer, jobLoader, or jobRegistry. That being said, I don't see an actual job defined in your XML file. The XML file needs one of those ;)
You can read more about adding your own job definitions to Spring Batch Admin: http://docs.spring.io/spring-batch-admin/reference/jobs.html#Add_your_Own_Jobs_For_Launching_in_the_UI

JdbcPagingItemReader endless loop

Why is it getting a endless loop? always return the ten records and doesn't continue with the next ones
<bean id="pagingItemReader1" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">
<property name="dataSource" ref="dataSource1" />
<property name="queryProvider">
<bean class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="selectClause" value="select id, image" />
<property name="fromClause" value="from squares" />
<property name="whereClause" value="where image like :value1 or image like :value2" />
<property name="sortKey" value="id" />
</bean>
</property>
<property name="parameterValues">
<map>
<entry key="value1" value="%/images/%" />
<entry key="value2" value="%/temp/%" />
</map>
</property>
<property name="pageSize" value="10" />
<property name="rowMapper">
<bean class="test.batch.ImagesRowMapper" />
</property>
</bean>
Using MySQL 5.1
Parentheses are missing.
Please change
"whereClause" value="where image like :value1 or image like :value2"
to
"whereClause" value="where (image like :value1 or image like :value2)"
I don't know why but I can share my solution with you.
Increase your pageSize over the total number of rows (of the current query of course).
This appears when I am using a 'OR' in whereClause
Someone can investigate ?

Spring Batch: Reading a File : if field is empty setting the default value

I am very new to spring batch. I have requirement in which i have to read a file having a header(Field Names) record and data records
i have to validate 1st record (check the field names matching against set of predefined names)- note that this record need to be skipped- i mean should not be part of items in processor)
read and store rest of the field values to a POJO
if the field 'date' is empty , i need to set the default value as 'xxxx-yy-zz'
i am unable to 1st and 3rd requirement with batch
here is the sample reader XML. please help
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="classpath:input/import" />
<property name="encoding" value="UTF-8" />
<property name="linesToSkip" value="1" />
<property name="lineMapper" ref="line.mapper"/>
</bean>
<bean id="line.mapper" class="org.springframework.batch.item.file.mapping .DefaultLineMapper">
<property name="lineTokenizer" ref="line.tokenizer"/>
<property name="fieldSetMapper" ref="fieldSet.enity.mapper"/>
</bean>
<bean id="line.tokenizer" class="org.springframework.batch.item.file.transfo rm.DelimitedLineTokenizer">
<property name="delimiter">
<util:constant static-field="org.springframework.batch.item.file.transfo rm.DelimitedLineTokenizer.DELIMITER_TAB"/>
</property>
<property name="names" value="id,date,age " />
<property name="strict" value="false"/>
</bean>
<bean id="fieldSet.enity.mapper" class="org.springframework.batch.item.file.mapping .BeanWrapperFieldSetMapper">
<property name="targetType" value="a.b.myPOJO"/>
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="org.springframework.beans.propertyeditors.C ustomDateEditor">
<constructor-arg>
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-mm-dd" />
</bean>
</constructor-arg>
<constructor-arg value="true" />
</bean>
</entry>
</map>
</property>
Create your own custom FieldSetMapper like below
CustomeFieldSetMapper implements FieldSetMapper<a.b.myPOJO> {
#Override
public a.b.myPOJO mapFieldSet(FieldSet fs) {
a.b.myPOJO myPOJO = new a.b.myPOJO();
if(fs.readString("date").isEmpty()){
myPOJO.setDate("xxxx-yy-zz");
}
return a.b.myPOJO;
}
}
You think you should do date set in ItemProcessor.
Also, if <property name="linesToSkip" value="1" /> not fill your requirements - extend FlatFileItemReader and validate first line manually in it.

Resources