Proper injection of SessionFactory with Spring and Spring Security - java

i have this exception
java.lang.NullPointerException
cz.xkadle21.dip.dao.ADiHibernateGenericDAO.findByCriteria(ADiHibernateGenericDAO.java:116)
cz.xkadle21.dip.dao.impl.DiUserDAO.findUserByUsername(DiUserDAO.java:86)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:47)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:1)
I was following this tutorial Spring Security 3 database authentication with Hibernate
and got "No bean named ... is defined" error. So i moved beans from dispatcher-servlet.xml to applicationContext-common-business.xml and change loading in web.xml
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-common-business.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Beans in despatcher-servlet.xml are loading with component-scan and are injecting sessionFactory automaticaly and properly. But bean in applicationContext-common-business.xml not.
applicationContext-common-business.xml
<bean name="userDetailsService"
class="cz.xkadle21.dip.service.impl.DiUserContextSecurityService" >
<constructor-arg ref="userDAO" />
<constructor-arg ref="securityUserFactory" />
</bean>
<bean id="securityUserFactory" class="cz.xkadle21.dip.factory.impl.DiSecurityUserFactory" />
<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${hibernate.connection.driver_class}"
p:url="${hibernate.connection.url}" p:username="${hibernate.connection.username}"
p:password="${hibernate.connection.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
</props>
</property>
</bean>
UserDetailsService is injected via constructor, but how to inject sessionFactory to userDAO? SessionFactory is defined in ADiHibernateGenericDAO and all DAOs extend the abstract ADiHibernateGenericDAO.The exception above is thrown on SessionFactory, which is not injected.
Thanks for any response.

Mate, I don't see any Transaction Manager or
< tx:annotation-driven />
written anywhere in your bean configuration file. You should put it there if you already haven't. That might be the problem.

You haven't shown us your DiUserDAO class, but assuming you have a setter in it for setSessionFactory(), you could simply change your XML mapping to be like:
<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Alternatively you could modify your DiUserDAO class to mark the SessionFactory field as #Autowired.
The same solution applies to any other beans that need to access this bean.

Related

Error creating bean with name 'authenticationmanager' defined in ServletContext

I just started to learn Spring Security and have some trouble. I want to configure User login on page with password and username which stored in database. I use Hibernate and spring 4.3 along with MySQL to store data.i was trying to login using DAO Authentication using spring but i'm struck here. please help me out..
security-context.xml
<!-- custom login Authentication/form -->
<http use-expressions="true" auto-config="true" >
<intercept-url pattern="/index*" access="hasRole('ROLE_STUDENT')"/>
<intercept-url pattern="/resources/**" access="permitAll" />
<form-login login-page="/login"
username-parameter="email"
password-parameter="password"
default-target-url="/default"
authentication-failure-url="/loginfailed"/>
<logout logout-success-url="/index"/>
<csrf/>
</http>
<b:bean id="daoAuthenticationprovider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider" >
<b:property name="userDetailService" ref="userDetailService"></b:property>
</b:bean>
<b:bean id="authenticationmanager" class="org.springframework.security.authentication.ProviderManager">
<b:property name="providers">
<b:list>
<b:ref bean="daoAuthenticationprovider"/>
</b:list>
</b:property>
</b:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailService">
<!-- <password-encoder hash="md5"></password-encoder> -->
</authentication-provider>
</authentication-manager>
Spring-servlet
<context:annotation-config />
<context:component-scan base-package="com.internbridge" />
<!-- to prevent browser back button on displaying secure resource after logout -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="cacheSeconds" value="0"></property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Spring Internationalizations -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="tl" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
web.xml
<display-name>InternBridge</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Spring initialization -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/security-context.xml,
/WEB-INF/spring-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring security configuration -->
<!-- filter to use spring security, be sure to use suggested name "springSecurityFilterchain"-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring MVC or Servlet Mapping -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
console
ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationmanager' defined in ServletContext resource [/WEB-INF/security-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.ProviderManager]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.security.authentication.ProviderManager.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4853)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.ProviderManager]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.security.authentication.ProviderManager.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147)
... 22 more
Caused by: java.lang.NoSuchMethodException: org.springframework.security.authentication.ProviderManager.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 23 more
As per the stack trace, the org.springframework.security.authentication.ProviderManager class does not have a default constructor. You will need to specify the providers when defining the bean. Here is an example.
How to set-up and configure a ProviderManager using Spring Security namespace?

Mystery around Spring Integration and prototype scope

Well, very likely there isn't any mystery but I am just not smart enough to figure out what my problem is. However usually it is the mystery after all!
Sorry for the introduction, my problem is that the prototype scope doesn't seem to work for me. I have created a REST service with a Spring Integration flow (there is a http inbound gateway in the front of the flow). The scopes of most of the beans are prototype. I tested the flow by calling it ten times with threads. Also I logged the bean references (just print the 'this' in the object being called) and I saw the same reference ten times!
e.g. org.protneut.server.common.utils.XmlToMapConverter#755d7bc2
To my knowledge it means that no new instance is being created for the XmlToMapConverter but using the same instance ten times. Am I right?
Very likely I configured the Spring incorrectly but I just cannot find out what I missed.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SpringIntegration-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>SpringIntegration</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringIntegration</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
SpringIntegration-servlet.xml
<beans ...>
<mvc:annotation-driven/>
<context:component-scan base-package="org.protneut.server.controller, org.protneut.server.common.persistence.service" />
<jpa:repositories base-package="org.protneut.server.common.persistence.repository"/>
<!-- ********************* importing the mysql config ********************* -->
<import resource="/mysql-config-context.xml"/>
<!-- ********************* importing the message flow ********************* -->
<import resource="classpath:META-INF/spring/integration/processing_req_wokflow.xml"/>
<tx:annotation-driven />
<!-- ************************************************************************* -->
<!-- ******************************** for JPA ******************************** -->
<!-- ************************************************************************* -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.protneut.server.common.persistence.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- ********************* the used property files ********************* -->
<context:property-placeholder location="classpath:protneut-server-config.properties"/>
<!--
****************************************************************************************
********************** Beans used in the Spring Integration flow **********************
****************************************************************************************
-->
<!-- it has to be prototype, it cannot be request as it is in an async call so it is not in the request! -->
<bean id="logManager" class="org.protneut.server.log.LogManager" scope="prototype"></bean>
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype"/>
<bean id="xmlToMapConverter" class="org.protneut.server.common.utils.XmlToMapConverter" scope="prototype"/>
<bean id="serviceStorageManager" class="org.protneut.server.cache.ServiceStorageManager" scope="singleton">
<property name="cacheBeanDAO" ref="cacheBeanDAO"/>
</bean>
<bean id="serviceCall" class="org.protneut.server.call.ServiceCall" scope="prototype">
<property name="httpClient" ref="httpClient"/>
</bean>
<bean id="xmlResponseExtractor" class="org.protneut.server.extract.XmlResponseExtractor" scope="prototype">
<property name="xmlToMapConverter" ref="xmlToMapConverter"/>
</bean>
...
</beans>
flow configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans ..>
<task:executor id="async_executor" pool-size="50" />
<!-- ***************************************************************************************************** -->
<!-- ************************************* WORKFLOW STARTING ********************************************* -->
<!-- ***************************************************************************************************** -->
<int-http:inbound-gateway id="receivingRest-inboundGateway"
supported-methods="POST" path="/service/get"
request-payload-type="java.lang.String" reply-timeout="10000"
request-channel="arrivedRestReq_channel" auto-startup="true"
error-channel="error_channel" reply-channel="restResponse-channel" >
</int-http:inbound-gateway>
<int:channel id="arrivedRestReq_channel" scope="prototype"></int:channel>
<int:json-to-object-transformer type="java.util.Map"
input-channel="arrivedRestReq_channel"
output-channel="fromConvertToActivator-channel"
id="convertJsonToMap_">
</int:json-to-object-transformer>
<int:channel id="fromConvertToActivator-channel"></int:channel>
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
ref="convertRestToWorkflowBean" method="convert">
</int:service-activator>
<int:channel id="toCallChain-channel"></int:channel>
<int:chain input-channel="toCallChain-channel" id="call_chain">
<int:service-activator
id="serviceStorageManager-serviceActivator"
ref="serviceStorageManager" method="getServiceInfo">
</int:service-activator>
<int:service-activator id="serviceRequestCreator-serviceActivator" ref="serviceRequestCreator" method="create"/>
<int:service-activator id="call-serviceActivator"
ref="serviceCall" method="call">
</int:service-activator>
<int:router expression="payload.extractType.name()"
id="responseExtractor-router">
<int:mapping value="XPATH" channel="xmlResponse-channel"/>
<int:mapping value="JSONPATH" channel="jsonResponse-channel"/>
</int:router>
</int:chain>
...
<int:service-activator id="xmlResponseExtractor-serviceActivator"
ref="xmlResponseExtractor" method="extract" input-channel="xmlResponse-channel" output-channel="toRestResponseCreator_chain"></int:service-activator>
</beans>
So I defined the scope of XmlToMapConverter is prototype but still I can't have new object at a new request. The situation is the same for convertRestToWorkflowBean which is the first service call in the flow (service-activator).
Could you please explain to me where the problem is?
Thanks, V.
I don't see xmlToMapConverter usage, but I see this:
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
ref="convertRestToWorkflowBean" method="convert">
where you use this:
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype"/>
The issue you are facing is called scope impendance. That's because <int:service-activator> populates several singleton beans, hence the reference to your prototype becomes as singleton, too.
One way to overcome that to use SpEL from there:
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
expression="#convertRestToWorkflowBean.convert(payload)"/>
In this case your convertRestToWorkflowBean is retrieved from the BeanFactory on each call.
Another trick to go ahead looks like:
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype">
<aop:scoped-proxy/>
</bean>
In this case your bean will be wrapped to the ScopedProxyFactoryBean and all invocation will be delegated to your prototype on demand.
Prototype scoped beans will be created every time you call ApplicationContext.getBean(...)
You've included the bean definition but haven't shown how other services reference it. My guess is it's injected into a singleton service once during initialization hence there's only one. Perhaps you need to call ApplicationContext.getBean() each time to get a new instance.
There are other solutions involving dynamic proxies that ultimately invoke getBean(), I'm on my mobile at the moment so too hard to find a link for you.

Configuration Hazelcast and Shiro

I am currently having trouble configuring Shiro and Hazelcast in conjunction:
web.xml:
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>hazelcastWebFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
[...]
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hazelcastWebFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ApplicationContext.xml:
<!-- Hazelcast configuration-->
<hz:hazelcast id="hazelcastInstance">
<hz:config>
<hz:instance-name>${hazelcast.instance}</hz:instance-name>
<hz:group name="${hazelcast.group}" password="${hazelcast.password}"/>
<hz:network port="${hazelcast.port}" port-auto-increment="${hazelcast.port.autoincrement}">
<hz:join>
<hz:multicast enabled="${hazelcast.multicast.enabled}"
multicast-group="${hazelcast.multicast.group}"
multicast-port="${hazelcast.multicast.port}"
multicast-time-to-live="${hazelcast.multicast.timetolive}"
multicast-timeout-seconds="${hazelcast.multicast.timeoutseconds}"></hz:multicast>
</hz:join>
</hz:network>
</hz:config>
</hz:hazelcast>
[...]
<bean id="hazelcastWebFilter" class="com.hazelcast.web.WebFilter" depends-on="hazelcastInstance">
<constructor-arg name="properties">
<props>
<prop key="map-name">shiro-activeSessionCache</prop>
<prop key="sticky-session">${hazelcast.webfilter.stickysession}</prop>
<prop key="instance-name">${hazelcast.instance}</prop>
</props>
</constructor-arg>
</bean>
<!-- Shiro -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/s/Login.app"/>
<property name="successUrl" value="/goMain.app"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="filters">
<util:map>
<entry key="authc" value-ref="auth"/>
<entry key="authcpda" value-ref="pdaAuth"/>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
HERE ARE PATHS onfigured
</value>
</property>
</bean>
<bean id="auth" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/s/Login.app"/>
</bean>
<bean id="pdaAuth" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/s/pda/login.app"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="PRODUCTRealm"/>
<property name="cacheManager" ref="shiroCacheManager"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"></bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!--<bean id="shiroCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>-->
<bean id="shiroCacheManager" class="de.logentis.Hazelcast.HazelcastCacheManager"/>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
<property name="sessionValidationSchedulerEnabled" value="false"/>
</bean>
<!-- Define the Shiro Realm implementation you want to use to connect to your back-end -->
<!-- security datasource: Netversys DB -->
<bean id="PRODUCTRealm" class="PRODUCTNAMEJdbcRealm">
<property name="dataSource" ref="dataSource"/>
<property name="schema" value="${PRODUCTdb.schema}"/>
</bean>
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
HazelcastCacheManager is from: https://github.com/stormpath/shiro-hazelcast-web-sample/blob/master/src/main/java/com/stormpath/samples/shiro/hazelcast/cache/HazelcastCacheManager.java
Problem 1: I can't log into the Application. I'm instantly logged out.
Problem 2: A JSESSIONID appears as query parameter (?). Was definitely never before
Problem 3: The hazelcastsession seems lost, although a Cookie exists
Problem 4: I have 3 Cookies: 2 JSESSIONID and 1 hazelcast.
Any help will be appreciated
As for the JSESSIONID issues, which may cause 1)
I don't know about hazelcast, but we had similar issues with using Vaadin and shiro. When the webapplication was using the JSESSION in the url, things got messy.
What helped for us is adding this to web.xml, telling the webserver to only use cookies for session id tracking:
<session-config>
<cookie-config>
<!-- this is so we also use it for https -->
<http-only>false</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>

Spring Security .DaoAuthenticationProvider: Cannot resolve reference to bean

I am implementing Spring Security in project. I have reached an impasse stuck here since hours.
I am getting this error
Error creating bean with name 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0': Cannot resolve reference to bean 'UserDAOImpl' while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myUserDetailService' is defined
The project setup is very simple
spring-security.xml
<authentication-manager>
<authentication-provider user-service-ref="myUserDetailService">
</authentication-provider>
</authentication-manager>
dispatcher-servlet.xml
<context:component-scan base-package="app.com,app.com.controller,app.com.dao,app.com.service,app.com.model"/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/view/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
ApplicationContext.xml
<context:annotation-config />
<!-- <context:property-placeholder> XML element automatically registers a new PropertyPlaceholderConfigurer
bean in the Spring Context. -->
<context:property-placeholder location="classpath:database.properties" />
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<!-- Creating DataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<!-- To persist the object to database, the instance of SessionFactory interface is created.
SessionFactory is a singleton instance which implements Factory design pattern.
SessionFactory loads hibernate.cfg.xml and with the help of TransactionFactory and ConnectionProvider
implements all the configuration settings on a database. -->
<!-- Configuring SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>app.com.model.User</value>
<value>app.com.model.Roles</value>
<value>app.com.BaseEntity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<!-- Configuring Hibernate Transaction Manager -->
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
CustomUserDetailsService.java
#Service("myUserDetailService")
#Transactional
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserDAO userDAO;
/*#Override
public UserDetails loadUserByUsername(String arg0)
throws UsernameNotFoundException, DataAccessException {
// TODO Auto-generated method stub
return null;
}
}
I also tried declaring the bean in both dispatcher-servlet.xml & application-context.xml it doesn't work
checked the context-component base package. It is scanning all the other classes present just fine. When I remove myUserDetailService from authentication provider the server starts just fine without any error.
I am really tired. Can anyone please help me in fixing this?
the reason why you got this working after moving the definitions to your context file is because in spring, the definitions inside the dispatcher servlet are only visible to mvc, and definitions inside context are global (to servlet and security), here is a page where its clearly explained https://weblogs.java.net/blog/sgdev-blog/archive/2014/07/05/common-mistakes-when-using-spring-mvc
phew... got it working.
Moved
<context:component-scan base-package="app.com,app.com.controller,app.com.dao,app.com.service,app.com.model"/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages"/>
from dispatcher-servlet to application-context.xml
Would anyone care to tell why it started working?

Right configuration for spring mvc app

I read this "It is a best practice to keep a clear separation between middle-tier services such as business logic components and data access classes (that are typically defined in the ApplicationContext) and web- related components such as controllers and view resolvers (that are defined in the WebApplicationContext per Dispatcher Servlet)."
And decide configure my application like that 4 separate xml file
applicationContext.xml
<context:component-scan base-package="appname">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
dao.xml
<!-- MySQL JDBC Data Source-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://#{mysqlDbCredentials.hostname}:#{mysqlDbCredentials.port}/#{mysqlDbCredentials.name}"/>
<property name="username" value="#{mysqlDbCredentials.username}"/>
<property name="password" value="#{mysqlDbCredentials.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="JpaPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.showSql">true</prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
and mvc-dispatcher-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="appname" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
web.xml(load spring context)
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/mvc-dispatcher-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<!-- Load spring beans definition files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/applicationContext.xml
/WEB-INF/spring/security.xml
/WEB-INF/spring/dao.xml
</param-value>
</context-param>
But I'm absolutly confused.
1)I don't understand how many context in this case I get.
2)I want easy replace tx mode on aspectj (which work just in ome context as I know). But when I replace I get error with transation.
Main problem that I want to have universal variant for both type of transaction
Here I add mode="aspectj" and I have annotation like #Service, #Resourse, on concrete classes
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" proxy-target-class="true"/>
All seems should work but I get next exception on flush
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1239)
at [internal classes]
at org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194)
at [internal classes]
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:993)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
Please, help me uderstand better
convention is you have one root context, normally applicationContext.xml. Then different servlet contexts (for different modules/functionality)... myapp-servlet.xml.
The servlet context can see everything in root context, but not the other way. Controllers and webby stuff(static resources) go in servlet context, everything else (eg service, and security) go in root context.
You can import different files as you please. But define those two contexts in your web.xml (or Java conf equivalent).
I still do it the old fashioned xml way, you don't have to use java conf.
Whats your actual error ?

Categories