0

I have a repository for the entity 'AppUser' as follows:

@Repository
public interface AppUserRepository extends CrudRepository<AppUser, Long>{

    public AppUser findByUserName(String username);
    public void delete(AppUser user);
}

It is autowired into my UserService class as:

@Service("userService")
public class UserService {

    @Autowired
    AppUserRepository repository;

public AppUser registerNewAppUser(AppUser user) {
    AppUser u = repository.findByUserName(user.getUsername());
    if (u!=null)
        return null;
    return repository.save(user);
}

The UserService is autowired into my CustomUserDetailsService as:

@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserService userService;

which is finally autowired to the WebSecurityConfiguration as:

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private DataSource datasource;

@Autowired
private CustomUserDetailsService customUserDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.jdbcAuthentication().dataSource(datasource)
                .and()
                .userDetailsService(customUserDetailsService);

        // @formatter:on
    }

UPDATE: I followed some of the suggestions here and have updated the error and the WebSecurityConfiguration file as shown above.

The error I now get is:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; 
nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: private javax.sql.DataSource showcase.WebSecurityConfiguration.datasource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [javax.sql.DataSource] 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)}

So, I assume I need to do somehow two things:

  1. Provide it a qualifying bean of type DataSource (I was thinking that the repo should qualify but it somehow isn't)

  2. Do the setFilterChainProxySecurityConfigurer. Not sure how to go about this. I followed a tutorial and created:

    public class WebMVCApplicationInitializer implements WebApplicationInitializer {
    
    public void onStartup(ServletContext container) {
    ServletRegistration.Dynamic registration =
            container.addServlet("dispatcher", new DispatcherServlet());
    registration.setLoadOnStartup(1);
    registration.addMapping("*.request");
    }
    }
    

    To add SpringSecurityFilterChain, I assume I need to call addFilter here but it needs a filter class. Do I need to create that? Also, is this initializer automatically picked up by the dispatcher servlet or do I need to configure that somehow?

doomguy
  • 401
  • 10
  • 26

1 Answers1

0

You just need to wire your DataSource in WebSecurityConfiguration like this:

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private Datasource datasource;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.dataSource(dataSource).userDetailsService(customUserDetailsService);
    }
}

And not sure if you are alreading doing it, but remember to add the SpringSecurityFilterChaint to your context.

David Moreno García
  • 4,423
  • 8
  • 49
  • 82
  • I added the `@Autowire private Datasource datasource;` and i assume you meant `auth.jdbcAuthentication().dataSource(datasource);` and by context do you mean in Application.java? – doomguy Dec 24 '14 at 21:52
  • Yeah, sorry for that. And by context I mean ServletContext. You have it in your WebApplicationInitializer. – David Moreno García Dec 24 '14 at 22:26
  • Sorry, but I followed your suggestions to some extent and have updated the question. Could you please take a look. – doomguy Dec 24 '14 at 23:16
  • Here you have a sample initializer https://github.com/davidmogar/Alsa/blob/master/src/main/java/com/davidmogar/alsa/infraestructure/config/WebApplicationInitializer.java I set the chain there. Hope this can help. – David Moreno García Dec 25 '14 at 00:50
  • I added the chain. Is the initializer supposed to be configured somehow so that it executes on startup? Also, the error says that it can't find a qualifying bean of type DataSource after I added the datasource member? I am not sure why the autowiring does not link the datasource to the repo – doomguy Dec 25 '14 at 02:49
  • You need to define it also. Check my other config classes ;) – David Moreno García Dec 25 '14 at 09:35
  • I see that classes like the WebMvcContext are imported in ApplicationContext. I don't see initializer listed here. I tried importing it this way but got a "Application failed to start with classpath" error. I also tried creating a WebMVCContext and importing it but with the same result. Is this the right track? Also is the fact that no qualifying bean of type datasource is being found related to this issue as well? – doomguy Dec 26 '14 at 00:45
  • The initializer is invoked automatically. Is where the magic begins. About the DataSource, I define it in the PersistenceContext.java file. – David Moreno García Dec 26 '14 at 01:03
  • Was wondering, how the properties in the environment variable are set. I am getting errors like `required key [hibernate.dialect] not found`. I am trying to create a DriverManagerDataSource. I have set the DriverClassName to java.sql.DriverManager and the entityManagerFactoryBean.setPackagesToScan to my base package name. – doomguy Dec 27 '14 at 19:18
  • There is a properties file (application.properties) in src/resources. – David Moreno García Dec 27 '14 at 19:42