Spring Security cannot reach custom userDetailsService Bean in Service layer - spring

Edit: I just realized that the issue does not come from spring-security not being able to instantiate userDetailsServiceImpl that is referenced in the spring-security.xml file, it is the addUserFormController that cannot be instantiated because it cannot autowire the UserDetailsServiceImpl. So the problem comes from the fact that this Controller cannot reach, for whatever reasons, this Service bean UserDetailsServiceImpl. I think I did properly made my component scan, by only scanning the controllers in mvc-dispatcher-servlet.xml, and all the other one except controller in the applicationContext.
I am using Spring MVC and Hibernate and I am trying to integrate Spring Security with a custom UserDetailsService and an Assembler.
It looks like my spring security cannot access the beans that are supposed to be scanned by the applicationContext.xml.
When loading my application I am running into the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'addUserFormController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.controller.AddUserFormController.setUserDetailsService(com.service.UserDetailsServiceImpl); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.service.UserDetailsServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
Here is my spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config='true' use-expressions='true'>
<intercept-url pattern="/login*" access="isAnonymous()" />
<intercept-url pattern="/secure/**" access="hasRole('ROLE_Admin')" />
<logout logout-success-url="/listing.htm" />
<form-login login-page="/login.htm" login-processing-url="/j_spring_security_check"
authentication-failure-url="/login_error.htm" default-target-url="/listing.htm"
always-use-default-target="true" />
</http>
<beans:bean id="com.daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="com.daoAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>
</beans:beans>
Here is my web.xml:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<!-- Spring MVC -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- This listener creates the root application Context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security -->
<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>
</web-app>
Here is my applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<!-- Load everything except #Controllers -->
<context:component-scan base-package="com">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- <property name="packagesToScan">
<list>
<value>com.service</value>
<value>com.dao</value>
</list>
</property> -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/tutospringsource" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>mymessages</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" />
<tx:method name="*" read-only="false" />
</tx:attributes>
</tx:advice>
And finally, my mvc-dispatcher-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<context:property-placeholder location="classpath:hibernate.properties" />
<!-- Load #Controllers only -->
<context:component-scan base-package="com.controller"
use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
</beans>
My AddUserFormController:
#Controller
#RequestMapping("/register.htm")
public class AddUserFormController {
private UserDetailsServiceImpl userDetailsService;
#Autowired
public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
My UserDetailsServiceImpl:
package com.service;
#Service("userDetailsService")
#Transactional
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserEntityDAO dao;
#Autowired
private Assembler assembler;

I have been able to fix that issue.
In my AddUserFormController, I had this:
#Controller
#RequestMapping("/register.htm")
public class AddUserFormController {
private UserDetailsService userDetailsService;
#Autowired
public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
Here is how it looks now:
#Controller
#RequestMapping("/register.htm")
public class AddUserFormController {
#Autowired
private UserDetailsService userDetailsService;
public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
I moved the #Autowired from the setter directly to the attribute, AND most important, I changed the type of userDetailsService to UserDetailsService, rather than UserDetailsServiceImpl.

Related

Don't work #autowire in Spring

I want to autowire my userService, but I'm getting an error. I have:
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<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>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<context:annotation-config/>
<context:component-scan base-package="com.andrylat.rgz.ocean.controllers" />
<context:component-scan base-package="com.andrylat.rgz.ocean.services" />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/"/>
<tx:annotation-driven />
application-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<!-- DataAccess -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:#localhost:1521:XE"/>
<property name="user" value="rgz1002"/>
<property name="password" value="aqweds"/>
</bean>
<context:component-scan base-package="com.andrylat.rgz.ocean.dao"/>
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.andrylat.rgz.ocean.domains</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<context:component-scan base-package="com.andrylat.rgz.ocean.domains"/>
<bean id="userDAO" class="com.andrylat.rgz.ocean.dao.UserDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="userService"
class="com.andrylat.rgz.ocean.services.UserService">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="userServiceForSecurity"
class="com.andrylat.rgz.ocean.services.UserService">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userServicePointCut"
expression="execution(* com.andrylat.rgz.ocean.services.*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointCut" />
</aop:config>
<!-- Spring Security -->
<bean id="passwordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</bean>
<sec:http auto-config="true" use-expressions="true">
<!--access-denied-handler error-page="/403" /-->
<sec:logout logout-success-url="/index.htm" />
<sec:form-login login-page="/login.htm"
default-target-url="/Ocean/test/testpage.htm"
authentication-failure-url="/login.htm?error=1" />
<sec:intercept-url pattern="/test/*"
access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />
<sec:intercept-url pattern="/*"
access="permitAll" />
<sec:intercept-url pattern="/resources/**"
access="permitAll" />
<sec:csrf />
</sec:http>
<!--sec:authentication-manager>
<sec:authentication-provider>
<sec:jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select login, password, enabled from users where login =? "
authorities-by-username-query=
"select login, userrole from userroles where login =? " />
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager-->
<sec:authentication-manager>
<sec:authentication-provider user-service-ref="userServiceForSecurity" >
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
UserService.java
#Service("userService") public class UserService implements UserDetailsService {
#Autowired
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
#Transactional(readOnly = true)
#Override
public UserDetails loadUserByUsername(final String username)
throws UsernameNotFoundException {
com.andrylat.rgz.ocean.domains.User user = userDAO.findByUserName(username);
List<GrantedAuthority> authorities
= new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(user.getRole ()));
return buildUserForAuthentication(user, authorities);
}
private User buildUserForAuthentication(com.andrylat.rgz.ocean.domains.User user,
List<GrantedAuthority> authorities) {
return new User(user.getLogin(), user.getPassword(),
user.getEnabled(), true, true, true, authorities);
}}
IndexController.java
#Controller public class IndexController {
//#Autowired
//#Qualifier("userService")
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
#Autowired
private SessionFactory sessionFactory;
#RequestMapping (value="/index", method=RequestMethod.GET)
private ModelAndView getIndexPage (){
if (sessionFactory==null) {
System.err.println("sessionFactory is null!");
} else {
System.err.println("sessionFactory OK!");
}
return new ModelAndView ("index");
}
#RequestMapping (value="/login", method=RequestMethod.GET)
private ModelAndView getLoginPage (){
return new ModelAndView ("login");
} }
Problem: my UserService in IndexController.java don't autowired! And i was added "sessionFactory" and it don't autowired too. "SessionFactory" is only null and when i write annotation to UserService i have next stacktrace (from jsp):
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping#0' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.andrylat.rgz.ocean.services.UserService com.andrylat.rgz.ocean.controllers.IndexController.userService; nested exception is java.lang.IllegalArgumentException: **Can not set com.andrylat.rgz.ocean.services.UserService field com.andrylat.rgz.ocean.controllers.IndexController.userService to com.sun.proxy.$Proxy158**
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
I don't understand why I can't get this UserService and my sessionFactory is null.
Seems like the problem with the application-context.xml naming.
So, Ensure that the file applicationContext.xml exists with proper name (should not be application-context.xml) in the WEB-INF folder so that the sessionFactory bean will be loaded. Otherwise, the sessionFactory bean object will be null.
Error was in
private UserService userService;
UserService is class and not interface. I create interface UserServiceI (UserService is implement UserServiceI) and write in IndexController
#Autowire
private UserServiceI userService;
All works!

Differents application Context in Spring 4

I have a login service in my application implementing UserDetailsService:
#Service
#Transactional
public class LoginService implements UserDetailsService {
#Autowired
UserService userService;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Assert.notNull(username);
UserDetails result = userService.loadUserDetailsByUsername(username);
Assert.notNull(result);
// WARNING: The following sentences prevent lazy initialisation problems!
Assert.notNull(result.getAuthorities());
result.getAuthorities().size();
return result;
}
}
The app dies with the error Exception encountered during context initialization. The start of the trace is:
Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0] ...
The end is:
Cannot resolve reference to bean 'loginService' while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'loginService' is defined
So it cannot find the loginService.
My web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>SimpleSpringProject</display-name>
<description>All you need!</description>
<!-- Loads Spring Security config file -->
<!--
contextConfigLocation is the context parameter where we provide the spring security beans configuration file name.
It is used by ContextLoaderListener to configure authentication in our application
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-*.xml</param-value>
</context-param>
<!-- Spring Security -->
<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>
<!-- Creates the Spring Container shared by all Servlet and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Handles Spring requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/webmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
In the contextConfigLocation I am loading 3 files: spring-security.xml, spring-datasource.xml and spring-jpa.xml.
spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/user/**" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/role/**" access="hasRole('ROLE_ADMIN')" />
<security:form-login
login-processing-url="/login"
login-page="/loginForm"
default-target-url="/"
authentication-failure-url="/loginForm?error"
username-parameter="username"
password-parameter="password" />
<security:logout logout-url="/logout" logout-success-url="/" delete-cookies="JSESSIONID" />
<security:csrf />
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="loginService"></security:authentication-provider>
</security:authentication-manager>
</beans>
spring-jpa.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.ssp" />
</beans>
spring-datasource.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Enable #Transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- MySQL Datasource with Commons DBCP connection pooling -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/simplesp" />
<property name="username" value="root" />
<property name="password" value="betis000" />
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<!-- EntityManagerFactory -->
<bean
id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Transaction Manager -->
<bean
id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
In the DispatcherServlet I am loading webmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Enable annotation-based Spring MVC controllers (eg: #Controller annotation) -->
<mvc:annotation-driven />
<!-- Classpath scanning of #Component, #Service, etc annotated class -->
<context:component-scan base-package="com.ssp" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
<!-- Register "global" interceptor beans to apply to all registered HandlerMappings -->
<mvc:interceptors>
<!-- Set the language in variable lang -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
p:paramName="lang" />
</mvc:interceptors>
<!-- Resolve view name into jsp file located on /WEB-INF -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Tiles -->
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/tiles-definitions.xml</value>
</list>
</property>
</bean>
<!-- Resolves localized messages*.properties and application.properties
files in the application to allow for internationalization. The messages*.properties
files translate messages which are part of the admin interface, the application.properties
resource bundle localizes all application specific messages such as entity
names and menu items. -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basenames="i18n/messages,i18n/application" />
<!-- Store preferred language configuration in a cookie -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
p:cookieName="locale" p:defaultLocale="en" />
</beans>
I am thinking that I have a problem with applicationContext because if I remove the #Service annotation and define the bean LoginService in the spring-security.xml:
<bean id="loginService" class="com.ssp.service.LoginService" />
then the applications starts and when I submit a login its UserService is null, so it seems that the context of LoginService is different to the context of the beans with:
<context:component-scan base-package="com.ssp" />
If anyone wants to see the full code of the app is in https://github.com/pedrogonzalezgutierrez/simplespringproject
I think you will need wrap your loginService with userDetailsServiceWrapper, try this:
<bean id="loginService" class="path.to.LoginService" />
<bean id="preAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="loginService" />
</bean>
</property>
</bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="preAuthenticationProvider" />
</authentication-manager>
After research more and more I am sure that it was a problem with the application context. It seems that I had two differents context in my app. One of them was loaded by the contextConfigLocation and another one by the DispatcherServlet.
Just leave the param-value of the DispatcherServlet empty and load all the configurations by contextConfigLocation.
Also I updated the beans definitions to the version 3.2 except for Spring Security that requires 4.0

Spring autowired Exception (NoSuchBeanDefinitionException)

After a long research and lost a day I decided to write here to find an answer of the autowired error below.
I didn't find the problem. I got error below when I run the application
ERROR: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.donguk.condo.service.MemberService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util">
<context:property-placeholder location="classpath*:*.properties" />
<context:component-scan base-package="com.donguk.condo">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- iBatis -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/SqlMapConfig.xml" />
</bean>
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<constructor-arg name="sqlMapClient" ref="sqlMapClient" />
</bean>
</beans>
spring-config.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<context:component-scan base-package="com.donguk.condo" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml" />
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
MemberController
package com.donguk.condo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.donguk.condo.service.MemberService;
#Controller
#RequestMapping("/member")
public class MemberController {
#Autowired
MemberService memberService;
#RequestMapping("/list")
public void list(Model model){
model.addAttribute("list", memberService.list());
}
}
MemberServiceImpl
package com.donguk.condo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.donguk.condo.dao.MemberDao;
import com.donguk.condo.vo.Member;
#Service
public class MemberServiceImpl implements MemberService {
#Autowired MemberDao dao;
#Override
public List<Member> list() {
return dao.list();
}
}
You disabled the component scan default filter, so auto scanning will only search for Components, as you have configured. Add Service to that filter list for component scanning.

unable to integrate spring security in existing application

I am not able to find out my problem in spring security integration. I have spent 2-3 days already.So, please help me.
below is my web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>cdl</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>startUpServlet</servlet-name>
<servlet-class>com.qait.cdl.commons.startup.StartUpServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>startUpServlet</servlet-name>
<url-pattern>/startUpServlet.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>CDL_ENV</param-name>
<param-value>staging</param-value>
</context-param>
<listener>
<listener-class>com.qait.cdl.commons.startup.CdlContextListner</listener-class>
</listener>
<!-- Session timeout -->
<session-config>
<session-timeout>600</session-timeout>
</session-config>
<!-- <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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/applicationContext.xml
WEB-INF/dispatcher-servlet.xml
</param-value>
</context-param>
</web-app>
Below is my applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="classapth*:spring/SpringSecurityConfig.xml" />
<!-- <bean name="springSecurityFilterChain" class="org.springframework.web.filter.OncePerRequestFilter"/> -->
</beans>
Below is my SpringSecurityConfig.xml
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/displayAdminPage.htm" access="hasRole('ROLE_ADMIN')" />
<security:form-login login-page="/login.htm" authentication-failure-url="/login.htm"/>
<security:logout logout-url="/logout.htm" logout-success-url="/login.htm"/>
<security:access-denied-handler error-page="/login.htm" />
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService" >
</security:authentication-provider>
</security:authentication-manager>
below is my dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Message resource -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
<value>error</value>
</list>
</property>
</bean>
<!-- Imports all configuration files -->
<import resource="classpath*:spring/*.xml" />
<import resource="classpath*:spring/*/*.xml" />
<!-- Interceptor mapping -->
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<!-- <property name="interceptors" ref="cdlInterceptor" /> -->
<property name="interceptors" ref="cdlSessionInterceptor"></property>
</bean>
<!-- Tiles view resolver and configuration -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles2.TilesView" />
<property name="order" value="1" />
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-defs.xml</value>
</list>
</property>
</bean>
<!-- XmlView Resolver -->
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="/WEB-INF/spring-Xmlviews.xml" />
<property name="order" value="0" />
</bean>
<!-- MultipartResolver for file upload -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<bean id="rssViewer" class="com.qait.cdl.rssfeed.view.CustomRssViewer" />
<!-- Default view resolver mapping <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property
name="suffix"> <value>.jsp</value> </property> <property name="order" value="1"
/> </bean> -->
</beans>
I have following queries.
Is it necessary to give "filter" tag in web.xml, if yes than why?
In my application, I have two application context(one for spring security and other for dispatcher-servlet), is it possible for springSecurityConfig.xml to access bean definition which is defined in dispatcher-servlet.xml?
what is the flow of spring-security configuration.Upto my knowledge, i have understood that intercept-url tag intercept the request and check appropriate role using expression language.I am not able to understand how it looks appropriate role in DB via authentication-manager i've provided.
below is my userService bean definition in service.xml
<bean name="userService" class="com.qait.cdl.services.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
below is userService interface
public interface UserService extends UserDetailsService{
}
this UserDetailsService is from springframework
below is UserServiceimpl class
public class UserServiceImpl implements UserService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = null;
if(username != null && !"".equals(username)){
User user = userDao.get(username);
if(user != null){
UserGroupAuthority groupAuthority = userDao.getUserAuthority(user);
if(groupAuthority != null){
Collection<GrantedAuthority> grantedAuthorities = getGrantedAuthorities(groupAuthority.getAuthority());
userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
true, true, true, true, grantedAuthorities);
}
}
}
return userDetails;
}
#Override
public Collection<GrantedAuthority> getGrantedAuthorities(String authority) {
List<GrantedAuthority> grantedAuthorities = new LinkedList<GrantedAuthority>();
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
return grantedAuthorities;
}
#Override
public UserGroupAuthority getUserAuthority(User user) {
return userDao.getUserAuthority(user);
}
}
Simply the problem is , it is not validating the given intercept-url. Where I am doing mistake?
Activate springSecurityFilterChain in your web.xml. It's an entry point of Spring Security. If springSecurityFilterChain is deactivated then Spring Security will never work.

Spring MVC + Hibernate 4 + Spring Security

I have been struggling to make all of this work since days now and don't know what to do. I believe I went through every single post on the subject here on SO and went through douzens of tutorials...
Here is the message I am having at this time:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fruitController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.controller.FruitController.setFruitManager(com.service.FruitManager); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.service.FruitManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
I have been able to solve this error in the past, but only to have a new one "No session found for current thread". When not having this one, I got some problem with my Assembler and UserDetailsServiceImpl bean not being recognized in my spring-security.xml file...
I do not think the problem(s) come from my code, I just can't get to set my config files properly and I am probably missing something here.
Here are the config files:
web.xml:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<!-- Spring MVC -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security -->
<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>
</web-app>
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<!-- Load everything except #Controllers -->
<context:component-scan base-package="com">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" />
<tx:method name="*" read-only="false" />
</tx:attributes>
</tx:advice>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.dao.HibernateFruitDAO</value>
</list>
</property>
<property name="packagesToScan">
<list>
<value>com.service</value>
<value>com.controller</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/basename" />
<property name="username" value="xxx" />
<property name="password" value="yyy" />
</bean>
</beans>
mvc-dispatcher-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<context:property-placeholder location="classpath:hibernate.properties" />
<!-- Load #Controllers only -->
<context:component-scan base-package="com.controller"
use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>mymessages</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
</beans>
spring-security.xml
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<beans:bean id="userDetailsService" class="com.service.UserDetailsServiceImpl">
</beans:bean>
<beans:bean id="assembler" class="com.service.Assembler">
</beans:bean>
<http auto-config='true' use-expressions='true'>
<intercept-url pattern="/login*" access="isAnonymous()" />
<intercept-url pattern="/secure/**" access="hasRole('ROLE_Admin')" />
<logout logout-success-url="/listing.htm" />
<form-login login-page="/login.htm" login-processing-url="/j_spring_security_check"
authentication-failure-url="/login_error.htm" default-target-url="/listing.htm"
always-use-default-target="true" />
</http>
<beans:bean id="com.daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="com.daoAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>
</beans:beans>
FruitController:
package com.controller;
#Controller
public class FruitController{
protected final Log logger = LogFactory.getLog(getClass());
private FruitManager fruitManager;
#Autowired
public void setFruitManager(FruitManager FruitManager) {
this.fruitManager = fruitManager;
}
#RequestMapping(value = "/listing", method = RequestMethod.GET)
public String getFruits(ModelMap model) {
model.addAttribute("fruits", this.fruitManager.getFruits());
return "listing";
}
}
FruitDAO:
public interface FruitDAO {
public List<Fruit> getFruitList();
public List<Fruit> getFruitListByUserId(String userId);
public void saveFruit(Fruitprod);
public void updateFruit(Fruitprod);
public void deleteFruit(int id);
public Fruit getFruitById(int id);
}
HibernateFruitDAO
package com.dao;
#Repository("fruitDao")
public class HibernateFruitDAO implements FruitDAO {
private SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public List<Fruit> getList() {
return (List<Fruit>) getSession().createCriteria ( Fruit.class ).list();
}
public List<Fruit> getFruitListByUserId(String userId) {
return (List<Fruit>)sessionFactory.getCurrentSession().createCriteria("from Fruit where userId =?", userId).list();
}
public void saveFruit(Fruit fruit) {
sessionFactory.getCurrentSession().save(fruit);
}
public void updateFruit(Fruit fruit) {
sessionFactory.getCurrentSession().update(fruit);
}
public void deleteFruit(int id) {
Fruit fruit = (Fruit) sessionFactory.getCurrentSession().load(Fruit.class, id);
if (null != fruit) {
sessionFactory.getCurrentSession().delete(fruit);
}
}
public Fruit getFruitById(int id) {
return (Fruit)sessionFactory.getCurrentSession().load(Fruit.class, id);
}
private Session getSession(){
return sessionFactory.getCurrentSession();
}
}
Interface FruitManager:
package com.service;
import java.io.Serializable;
import java.util.List;
import com.domain.Fruit;
public interface FruitManager extends Serializable{
public List<Fruit> getFruits();
public List<Fruit> getFruitsByUserId(String userId);
public void addFruit(Fruit fruit);
public void removeFruit(int id);
public Fruit getFruitById(int id);
public void updateFruit(Fruit fruit);
}
Implementation of FruitManager:
package com.service;
#Repository("fruitManager")
#Transactional
public class SimpleFruitManager implements FruitManager {
/**
*
*/
private static final long serialVersionUID = ...;
#Autowired
private FruitDAO fruitDao;
public List<Fruit> getFruits() {
return fruitDao.getFruitList();
}
public List<Fruit> getFruitsByUserId(String userId){
return fruitDao.getFruitListByUserId(userId);
}
public void setFruitDao(FruitDAO fruitDao) {
this.fruitDao = fruitDao;
}
public void addFruit(Fruit fruit) {
fruitDao.saveFruit(fruit);
}
public void removeFruit(int id) {
fruitDao.deleteFruit(id);
}
public getFruitById(int id) {
return fruitDao.getFruitById(id);
}
public void updateFruit(Fruit fruit) {
fruitDao.updateFruit(fruit);
}
}
At a glance, it seems you're suffering from a common problem of not understanding how Spring ApplicationContexts fit together to make a web application. See my other answer to exactly the same problem to see if it clears things up:
Declaring Spring Bean in Parent Context vs Child Context
You may also be enlightened by this answer on a similar topic, which links to my previously mentioned answer as well as one other:
Spring XML file configuration hierarchy help/explanation
A couple brief tips to get you headed in the right direction...
By convention, Spring's ContextLoaderListener loads beans from WEB-INF/applicationContext.xml to create the root application context. When you override the default, as you're doing, that file is no longer loaded.
Tip #1: stick with the conventional behavior. It'll make your life simpler.
Also by convention, starting up a Spring DispatcherServlet loads beans from WEB-INF/<servlet name>-context.xml to create the context used to configure the dispatcher servlet. This context becomes a child of the root context.
Tip #2: see tip #1
So you see, you're presently over-configuring things. Read the linked answers and the reference materials linked therein. Learn to work with Spring instead of against it.
In your web.xml file, the applicationContext.xml is never get loaded. You should put it location in context-param. Put the location of mvc-dispatcher-servlet.xml (containing controller related bean) as init-param for DispatcherServlet instead:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</init-param>
I think you must to use this in the DaoImpl to get the session:
#Autowired
private SessionFactory sessionFactory;

Resources