I am trying to get a Single-signon solution working, which has previously worked with Novell eDirectory as an LDAP-provider. Now, I am trying to get it to work with OpenLDAP. In the signon-process, one of the steps is retrieving the actual user from the LDAP. This is done by Spring-security, but it seems to have a bug.
For getting the user, LdapUserDetailsService#loadUserByUsername is called. This uses a predefined LdapUserSearch to find a user with the given username. In my case, the configuration looks something like this:
base:ou=something,ou=somethingElse,dc=oh,dc=my,dc=god
filter:cn={0}
where {0} is replaced with the actual username. So far this works, and the user is retrieved, in the form of userdata returned by FilterBasedLdapUserSearch#searchForUser. But, the userdata does not separate between dn and base, so it has:
base: (empty)
dn:cn=someUsername,ou=something,ou=somethingElse,dc=oh,dc=my,dc=god
This userdata-object is in turn used to retrieve the authorities for the user, so it the tries to do another search with the base above, and the dn as filter. But, this query fails, since OpenLDAP does not allow any queries with an empty string as base.
I have tried with 3.1.3.RELEASE, 3.1.7.RELEASE and 3.2.7.RELEASE, all have the same issue.
Is this a bug in spring-security? Or am I doing something wrong here?
Managed to fix it, by moving away from the "template" way of defining the ldap user service:
Before:
<sec:ldap-user-service id="ldapUserDetailsService"
server-ref="contextSource"
user-search-filter="${my.ldap.filter}"
user-search-base="${my.ldap.base}"
user-context-mapper-ref="myUserDetailsContextMapper"/>
After:
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="${my.ldap.base}"/>
<constructor-arg index="1" value="${my.ldap.filter}"/>
<constructor-arg index="2" ref="contextSource"/>
</bean>
<bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="${my.ldap.usersearch.base}"/>
<property name="groupSearchFilter" value="${my.group.filter}" />
<property name="groupRoleAttribute" value="${my.group.attribute}" />
<property name="searchSubtree" value="true" />
</bean>
<bean id="ldapUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="userSearch"/>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
Don't ask me how or why this works..
Related
Right now I have this:
<bean id="hardcodedQuery"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
DELETE from GENERIC_TABLE
WHERE id = 999
]]>
</value>
</property>
<property name="itemSqlParameterSourceProvider">
<bean
class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
</bean>
But I keep getting the java.lang.IllegalArgumentException, saying that my SQL query is paramaterized. I know they want me to put some reference to the reader and have :randomVariable in the command, but I adamantly oppose this apparent requirement. Am I mistaken and is there a workaround? Or do I have to use a completely different class for my bean?
This is the error message:
Caused by: java.lang.IllegalArgumentException: Using SQL statement with '?' placeholders requires an ItemPreparedStatementSetter
Thanks!
The short answer is that this class isn't meant for what you're trying to do. The ItemWriter contract assumes item based processing which would mean that you need to parameterize the SQL for each item. If you want to run just a delete statement, use a Tasklet implementation that uses the JdbcTemplate.
I use spring and in my context I created bean:
<bean id="pageableResolver" class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
<constructor-arg ref="sortResolver" />
<property name="oneIndexedParameters" value="true"/>
</bean>
Also I use backbone framework as frontend.
When I generate request with page=1&size=10 when oneIndexedParameters is true then I expect to receive first page with 10 records. In current configuration I receive first page with nine records. It is right? How I can configure PageableHandlerMethodArgumentResolver to decrement only pageNumber, but not pageSize?
I filed and fixed DATACMNS-761 for you.
Is there any way to increase the number of times a proxy ticket can be used, when using the CAS server. Also, is there any way to increase the time before a ticket expires. I know about the ticketExpirationPolicies.xml file in CAS and I have tried changing the file as follows
<bean id="serviceTicketExpirationPolicy" class="org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy">
<!-- This argument is the number of times that a ticket can be used before its considered expired. -->
<constructor-arg
index="0"
value="10" />
<!-- This argument is the time a ticket can exist before its considered expired. -->
<constructor-arg
index="1"
value="7200000" />
</bean>
But this does not let me use the proxy ticket again. I get the message So, is there any other way to do it or am I doinig something wrong.
Thanks
I have a String value in a Spring configuration file that comes to be as the result of a JNDI lookup -- it happens to be a path name:
<jee:jndi-lookup id="myAppHomeDir" jndi-name="myAppHomeDir" />
Now I need to concatenate on to the end of this path another string and hand it off to another Spring bean as follows (which of course doesn't work):
<bean id="LogPath" class="org.mystuff.initBean">
<property name="logDirectory">
<jee:jndi-lookup id="myAppHomeDir"
jndi-name="myAppHomeDir" /> + "/logs"
</property>
</bean>
Is there a simple way to do this without me having to write a utility class in Java?
Try using Spring EL (expression language). I would try the following (not tested):
<jee:jndi-lookup id="myAppHomeDir" jndi-name="myAppHomeDir" />
<bean id="LogPath" class="org.mystuff.initBean">
<property name="logDirectory" value="#{myAppHomeDir+'/logs'}"/>
</bean>
Not quite sure if it would work. The thing that troubles me is the cast from File (I guess) to String when concatenating. So if the previous one didn't work, I would try:
#{myAppHomeDir.canonicalPath+'/logs'}
Let us know if it works.
I read the "Spring Security 3 database authentication with Hibernate"! But I don't know how I should implementate it into my project!
In which document I have to set the password/username/drivers/url for the database?
I have different column titles like OPERATOR_ID/USR_ID/PASSWORD
OPERATOR_ID should be the login name, USR_ID the role and the password for the login
Please, maybe you could post an example which implements my questions? Maybe for a checkout or a *.war file?
I dont think there is any configuration as such for doing this. You have to implement the UserDetailsService which has only one method loadUserByUsername to load the user and you have to implement the same to load your user information from your database using hibernate.
See here
You would need to configure a JDBCDaoImpl bean which takes a Datasource as a parameter. How you retrieve the Datasource is up to you, you may grab it from the app server or use something like Spring's DriverManagerDatasource Here is some (pseudo) config
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>your.driver.classname</value></property>
<property name="url"><value>yourDatabaseUrl</value></property>
<property name="username"><value>yourUsername</value></property>
<property name="password"><value>yourPassword</value></property>
</bean>
<bean id="dao" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="DataSource" ref="datasource" />
...
</bean>