Spring Security Multiple Authentication Filters - spring

In my project i have declared two authentication filters as mentioned below in spring-security-context.xml file
<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**" filters="authenticationProcessingFilterWithDB, authenticationProcessingFilterWithXML" />
</sec:filter-chain-map>
</beans:bean>
I have declared authentication manager for each filter in following way:
<beans:bean id="authenticationProcessingFilterWithDB" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManagerWithDB" />
<beans:property name="filterProcessesUrl" value="/j_spring_security_check_with_db" />
</beans:bean>
<beans:bean id="authenticationProcessingFilterWithXML" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManagerWithXML" />
<beans:property name="filterProcessesUrl" value="/j_spring_security_check_with_xml" />
</beans:bean>
but when i try to access /j_spring_security_check_with_xml from jsp then it is giving resource not found error. The same is working if give default '/j_spring_security_check' with single authentication manager. Please give the solution for adding multiple authentication manager in spring security as i should be able to verify login details against xml file (where username and password will be provided),against Data base

Related

JPA with Spring-security-ACL

is it possible use JPA in spring security ACL, I can see only jdbc implementation.
here is my JPA setup in beans:
<beans:bean id="producerService" class="cz.services.RepositoryProducerService" />
<jpa:repositories base-package="cz.repository" />
<beans:bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="cz.models" />
<beans:property name="jpaVendorAdapter">
<beans:bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="myEmf" />
</beans:bean>
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8" />
<beans:property name="username" value="root" />
<!--<property name="password" value="test" /> -->
<beans:property name="password" value="test1"></beans:property>
</beans:bean>
but I have a problem with Transaction manager, beacuse I use org.springframework.orm.jpa.JpaTransactionManager
instead of:
org.springframework.jdbc.datasource.DataSourceTransactionManager.
Main problem is when I start create acl, in first try I have exception transaction must be running, is second try (in broswer back and try it again) is it okay.
Here is error from first try:
java.lang.IllegalArgumentException: Transaction must be running
at org.springframework.util.Assert.isTrue(Assert.java:65)
at org.springframework.security.acls.jdbc.JdbcMutableAclService.createOrRetrieveSidPrimaryKey(JdbcMutableAclService.java:218)
at org.springframework.security.acls.jdbc.JdbcMutableAclService$1.setValues(JdbcMutableAclService.java:135)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:899)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:890)
can someone help me with this? Thanks
Problem solved! :)
I search that JPA transaction manager in spring
A snippet from Spring 3's JavaDoc:
This transaction manager also supports direct DataSource access within
a transaction (i.e. plain JDBC code working with the same DataSource).
This allows for mixing services which access JPA and services which
use plain JDBC (without being aware of JPA)!
but problem was in my cglib - I have to use
<tx:annotation-driven transaction-manager="transactionManager" />
and remove #Transactional from interface JPA repository.
I found solution here too : What transaction manager should I use for JBDC template When using JPA ?
hope someone help it.

Could not fetch messages from Webpshere MQ sometimes even though the application and websphere mq is up and running

I have encountered a problem in fetching the messages from Websphere MQ.
We have a application running in spring TC server.
Application is using spring integrator JMS adaptor to receive the messages from Websphere MQ server.
Following is the spring configuration we used.
Problem we are facing is, sometime even though the websphere mq is up and running and application is up and running, the application is not able to fetch the messages so that messages are falling to websphere mq dead letter queue
Is there any possibility for the above scenario? We are not able to reproduce this scenario
<beans:bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<beans:property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
</beans:property>
<beans:property name="queueManager" value="queueManager" />
<beans:property name="hostName" value="hostName" />
<beans:property name="channel" value="channel" />
<beans:property name="port" value="port" />
<beans:property name="clientReconnectOptions">
<util:constant static-field="com.ibm.msg.client.wmq.WMQConstants.WMQ_CLIENT_RECONNECT"/>
</beans:property>
</beans:bean>
<beans:bean id="mqSeriesConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<beans:property name="username" value="username"/>
<beans:property name="password" value="password"/>
<beans:property name="targetConnectionFactory" ref="connectionFactory"/>
</beans:bean>
<beans:bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
<beans:property name="connectionFactory" ref="mqSeriesConnectionFactory" />
</beans:bean>
<beans:bean id="mqQueueG3Receive" class="com.ibm.mq.jms.MQQueue">
<beans:constructor-arg value="receivequeue" />
<beans:property name="targetClient" value="1"/>
</beans:bean>
<beans:bean id="mqQueueG3Send" class="com.ibm.mq.jms.MQQueue">
<beans:constructor-arg value="sendqueue" />
<beans:property name="targetClient" value="1"/>
</beans:bean>
<jms:message-driven-channel-adapter id="MessageManagerJmsAdapter"
connection-factory="mqSeriesConnectionFactory"
destination="mqQueueG3Send"
concurrent-consumers="7"
max-concurrent-consumers="40"
transaction-manager="jmsTransactionManager"
message-converter="resultMessageConverter"
channel="MessageManagerIncomingChannel" />
<channel id="g3MessageManagerIncomingChannel" />
<service-activator id="MessageManagerActivator"
input-channel="MessageManagerIncomingChannel"
ref="MessageManager"
method="manageMessage" />
Thanks
WebSphere MQ is a little finicky when it comes to Spring Integration JMS. instead of building up the message-driven-channel-adapter with connection settings, you may want to try configuring your own DefaultMessageListenerContainer and using that. things to look out for include;
sessionTransacted = true
transactionManager = [ref]
so this would look like;
<int-jms:message-driven-channel-adapter channel="myChannel" container="myContainer"/>
<bean id="myContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="myConnectionFactory"/>
<property name="destination" ref="myQueue"/>
<property name="sessionTransacted" value="true"/>
<property name="transactionManager" ref="myTransactionManager"/>
</bean>
If they are going to the DLQ it means delivery failed, not that the app could not "fetch the message". I would expect there to be an error logged.
Another thing to look for is if the container's threads (7) are blocked somewhere in your MessageManager bean. Take a thread dump (jstack or visualVM) to find out what the container threads are doing.
Finally, trace logging will show the container thread activity when idle.

How do I get Spring security to generate the same password as what the Jasypt command line tool generates?

I'm using Jasypt 1.9.0, Spring 3.1.1.RELEASE, and Maven 3.0.3. Using the Jasypt command line tool, I generate passwords like so …
./digest.sh input=admin providerClassName=org.bouncycastle.jce.provider.BouncyCastleProvider algorithm=SHA-256 saltGeneratorClassName=org.jasypt.salt.ZeroSaltGenerator
However, when I configure Spring security to attempt to match a password someone entered at the login screen …
<beans:bean id="bcProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider" />
<beans:bean id="jasyptStringDigester" class="org.jasypt.digest.StandardStringDigester">
<beans:property name="algorithm">
<beans:value>SHA-256</beans:value>
</beans:property>
<beans:property name="provider">
<beans:ref bean="bcProvider" />
</beans:property>
<beans:property name="saltGenerator">
<beans:bean id="saltGenerator" class="org.jasypt.salt.ZeroSaltGenerator"/>
</beans:property>
</beans:bean>
<!-- This Spring Security-friendly PasswordEncoder implementation will -->
<!-- wrap the StringDigester instance so that it can be used from -->
<!-- the security framework. -->
<beans:bean id="passwordEncoder" class="org.jasypt.spring.security3.PasswordEncoder">
<property name="stringDigester">
<ref bean="jasyptStringDigester" />
</property>
</beans:bean>
<authentication-manager alias="authenticationManager" id="authenticationManager">
<authentication-provider user-service-ref="sbdUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
Spring is generating a different password than what is stored, and hence I'm not able to authenticate my user. Is there some configuration I'm missing? Why, during authentication, does SPring generate something different than what Jasypt has?
if you run digest.sh multiple times you will get different hashes for same input values. i assume Jasypt uses a timestamp or a random string as a salt.
to be able to generate same hash, you must know the salt, which is used or control the way it is generated. There is a cli parameter called saltGeneratorClassName. By providing a class, which implements the SaltGenerator interface you can control the salt generation.
UPDATE:
forget what i said about position of the salt. you just need to change the jasyptStringDigester a little bit:
<beans:bean id="jasyptStringDigester" class="org.jasypt.digest.StandardStringDigester">
<beans:property name="algorithm">
<beans:value>SHA-256</beans:value>
</beans:property>
<beans:property name="provider">
<beans:ref bean="bcProvider" />
</beans:property>
<beans:property name="saltGenerator">
<beans:ref bean="saltGenerator" />
</beans:property>
</beans:bean>
<beans:bean class="impl.of.your.SaltGenerator" id="saltGenerator" />
and then you need to provide impl.of.your.SaltGenerator to digest.sh:
./digest.sh input=admin \
providerClassName=org.bouncycastle.jce.provider.BouncyCastleProvider \
algorithm=SHA-256 \
saltGeneratorClassName=impl.of.your.SaltGenerator

Spring i18n Vs Spring security

I configured my project to be internation but now i am trying to change spring security custom messages without success... I already read and tried some things but without success. I can se usual messages, but not spring security messages.
here is my servlet-context.xml:
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Tiles -->
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
<beans:property
name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</beans:bean>
<context:component-scan base-package="com.company.projectMvc" />
<!-- default locale -->
<beans:bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver">
<beans:property name="defaultLocale" value="es"/>
</beans:bean>
<interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="language"/>
</beans:bean>
</interceptors>
<!-- Messages files -->
<beans:bean id="messageSource" name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basename" value="/resources/messages/messages" />
</beans:bean>
here is my spring-security.xml:
<http auto-config="true" use-expressions="true" >
<intercept-url pattern="/test" access="isAuthenticated()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<intercept-url pattern="/home" access="permitAll" />
<form-login default-target-url="/home"/>
<logout logout-success-url="/test" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username,password,enabled,fullname
from users where username=?"
authorities-by-username-query="
select u.username, ur.authority from users u, user_roles ur
where u.user_id = ur.user_id and u.username =? "
/>
</authentication-provider>
</authentication-manager>
UPDATE 1
I tried your solution, copying spring security files and change them without success..
After i read this thread Spring Security with AcceptHeaderLocaleResolver and i18n i tried that solution too without success
here is my updated servlet-context.xml file:
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Tiles -->
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
<beans:property
name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</beans:bean>
<context:component-scan base-package="com.company.projectMvc" />
<!-- default locale pt_PT -->
<beans:bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver">
<beans:property name="defaultLocale" value="pt_PT"/>
</beans:bean>
<!-- Messages files -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<beans:value>/resources/messages/messages</beans:value>
<beans:value>/resources/messages/securityMessages</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- com o parametro locale no URL conseguimos definir o locale que quisermos -->
<interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
</interceptors>
Here is my updated web.xml
part1
part2
Probably a little late answer, but someone else facing similar issue might find it useful:
Your problem is that security beans are in root web application context, but messageSource is in the servlet application context source. This means that security beans are unaware of your message source. Simply move your message source definition to the root web application context.
I do not know if you tried this,
Copy message files from org.springframework.security and change
them.
Configure your message source with these files.
By default Spring security uses org.springframework.security.core.SpringSecurityMessageSource This is from javadocs
All Spring Security classes requiring messge localization will by
default use this class. However, all such classes will also implement
MessageSourceAware so that the application context can inject an
alternative message source. Therefore this class is only used when the
deployment environment has not specified an alternative message
source.

Spring security 3 how to do change password

I used spring security to login option. Now i want to add a change password option.first time user login to the system change password option need to be appear or redirect to change password page.
this is my spring security file
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" />
</list>
</property>
</bean>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder ref="passwordEncoder">
<security:salt-source ref="saltSource"/>
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="saltSource" class="com.rcfi.lankaweb.linklk.support.service.SaltService"></bean>
<bean id="passwordEncoder" class="com.rcfi.lankaweb.linklk.support.service.PasswordVerifier"></bean>
<bean id="userDetailsService"
class="com.rcfi.lankaweb.linklk.support.service.UserDetailsServiceImpl">
</bean>
Create a change password method in your com.rcfi.lankaweb.linklk.support.service.UserDetailsServiceImpl
this will take the new String and save to database for the logged in user, via your user dao (probably)

Resources