0

I am a newbie to spring-security.I have a issue with @Autowired annotation.

Below is my spring-security.xml file:

<http pattern="/login" security="none" />
<http pattern="/signup" security="none" />
<http pattern="/views/**" security="none" />
<http pattern="/createUser" security="none" />
<http pattern="/practice" security="none" />
<http use-expressions="true" authentication-manager-ref="authenticationManager">
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    <form-login login-page="/login" default-target-url="/home"
        authentication-failure-url="/login" username-parameter="username"
        password-parameter="password" login-processing-url="/j_spring_security_check" />
    <logout logout-success-url="/login" invalidate-session="true"
        logout-url="/j_spring_security_logout" delete-cookies="JSESSIONID" />
    <session-management invalid-session-url="/login">
        <concurrency-control max-sessions="1"
            expired-url="/login" />
    </session-management>
</http>
<authentication-manager id="authenticationManager">
    <authentication-provider user-service-ref="userDetailsService" />
</authentication-manager>
<beans:bean id="userDetailsService" class="com.practice.service.UserDetailsServiceImpl" />

<beans:bean name="
    passwordEncoder "
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

This is my spring-servlet.xml configuration:

<context:annotation-config/>
<context:component-scan base-package="com.practice" />
<mvc:resources mapping="/views/**" location="/views/" />
<mvc:annotation-driven />

<bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations"
        value="classpath:com/practice/resources/database.properties"></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>

<bean id="dataSource" destroy-method="close"
    class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${database.driver}" />
    <property name="url" value="${database.url}" />
    <property name="username" value="${database.username}" />
    <property name="password" value="${database.password}" />
</bean>

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
        <value>classpath:com/practice/resources/hibernate.cfg.xml</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        </props>
    </property>
</bean>

<tx:annotation-driven />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean> 

I would request for signup page, and after filling the necessary details , it hits my controller , where i save the user in the database, then i authenticate the user, in the request against the one which i stored in the database. I followed this stackoverflow post for guidance.

The strange thing is the autowiring is not happening in the class, where i implement the UserDetailsService interface :

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
PasswordEncoder passwordEncoder;

@Autowired
UserService userService;

@Override
public UserDetails loadUserByUsername(String arg0)
        throws UsernameNotFoundException {
    System.out.println("ddfddd");
    return null;
}}

Whereas autowiring is taking place in other service classes , where i autowired the same fields as mentioned above !!

The same thing happens when i do a login , and when i debugged , the fields are null ! and also in the classes where i wrote my CustomAuthenticationProvider !

Any suggestion ?? If there is any mistake in my configuration do correct me.

Update

I am getting the following error,

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.practice.service.UserService] 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)}

when i remove @Service annotation and when i add context:annotation-config

Community
  • 1
  • 1
MdKamil
  • 41
  • 3
  • 10
  • Remove `@Service` from the `UserDetailsServiceImpl` and add `` to the `spring-security.xml` file. – M. Deinum May 07 '15 at 11:12
  • @Deinum ,I am getting the following error , Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.practice.service.UserService] 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)} – MdKamil May 07 '15 at 11:18
  • 1
    Please don't add errors, code etc. as comments, update your question. – M. Deinum May 07 '15 at 11:19
  • Well, you haven't defined any beans which implement the interface `UserService`, so add one bean and you should be fine. – dunni May 07 '15 at 12:30
  • If you have defined a `UserService` bean with an `@Component` annotation, which is picked up by the component scan in spring-servlet.xml, then the problem could be, that spring-servlet.xml is a child application context from spring-security.xml. In that case, beans from the security context aren't able to access any beans from the child context, only the other way round. – dunni May 07 '15 at 12:33
  • @dunni But the autowiring is happening in other service classes . For example i created a class Practice Service , which i annotated with Service annotation , autowiring the same fields as above , when i debugging , autowiring is happening fpor those fields ? I am confused , any suggestion – MdKamil May 07 '15 at 12:46
  • Yes, when those other classes are annotated and detected by component scan, they are assigned to the spring-servlet.xml context, not spring-security.xml context, so they have access to all beans from spring-servlet and spring-security. But beans in the spring-security context can't access beans from the spring-servlet context. – dunni May 07 '15 at 13:08
  • @dunni how to know a particular bean is in spring-context and spring-security-context.xml ? If that's the case , then we need to declare beans that are used in spring-security-context.xml explicitly ?? P.S : Even i have annotated this particular class with service annotataion – MdKamil May 07 '15 at 14:28
  • In your case it's quite simple. All beans, that are explicitly defined in spring-security.xml, are in that context (quite obviously). In your spring-servlet.xml you have the directives ` `, so all beans which are in that base package and annotated with Service, Component etc. are assigned to the spring-servlet context, because they are registered there. If you want a bean accessible in spring-security context, you have to define it there. – dunni May 07 '15 at 18:43
  • @dunni , thanks it cleared me :) .... Also i gone through other SO posts , regarding this issue , finally i created new context , a parent context (rot-context/xml ) and defined it in the , web/xml file under contextConfigLocation , i moved all bean definitions except few and finally it worked :) . Is it advisable what i did ? – MdKamil May 07 '15 at 19:19
  • Seems good to me. I will post my comment as answer, you can then accept it, if it solved your problem. – dunni May 07 '15 at 19:40

1 Answers1

0

If you have defined a UserService bean with an @Component annotation, which is picked up by the component scan in spring-servlet.xml, then the problem could be, that spring-servlet.xml is a child application context from spring-security.xml. In that case, beans from the security context aren't able to access any beans from the child context, only the other way round. So you have to make sure, that all required beans are accessible from the spring-security.xml context (e.g. by specifying all beans explicitly or by moving the annotation-config and component-scan elements in the spring-security.xml context).

dunni
  • 43,386
  • 10
  • 104
  • 99