Java – unable to automatically connect field: private org springframework. security. core. userdetails. UserDetailsService
I'm a new spring, so I've been on the safe side
I have passed a fine comb through my code, unable to determine the problem
Spring Framework version: 3.2 5. Release spring Security version: 3.2 0.M2
SecurityConfig. java
package com.entirety.app.config; import com.entirety.app.service.implement.UserDetailsServiceImplementation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import javax.sql.DataSource; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled=true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private DataSource dataSource; @Autowired private UserDetailsService userDetailsServiceImplementation; @Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource); } @Override protected void configure(HttpSecurity http) throws Exception { http.userDetailsService(userDetailsServiceImplementation) .authorizeUrls() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/sec/**").hasRole("MODERATOR") .antMatchers("/*").permitAll() .anyRequest().anonymous().and().exceptionHandling().accessDeniedPage("/denied").and() .formLogin() .loginProcessingUrl("/j_spring_security_check") .loginPage("/login") .failureUrl("/error-login") .and() .logout() .logoutUrl("/j_spring_security_logout") .logoutSuccessUrl("/"); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
CrmUserService. java
@Service("userService") @Transactional public class CrmUserService implements UserDetailsService { @Autowired private UserDAO userDAO; @Override public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException { com.entirety.app.domain.User domainUser = userDAO.getUser(login); boolean enabled = true; boolean accountNonExpired = true; boolean credentialsNonExpired = true; boolean accountNonLocked = true; return new User( domainUser.getLogin(),domainUser.getpassword(),enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,getAuthorities(domainUser.getAuthority().getId()) ); } public Collection<? extends GrantedAuthority> getAuthorities(Integer role) { List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role)); return authList; } public List<String> getRoles(Integer role) { List<String> roles = new ArrayList<String>(); if (role.intValue() == 1) { roles.add("ROLE_MODERATOR"); roles.add("ROLE_ADMIN"); } else if (role.intValue() == 2) { roles.add("ROLE_MODERATOR"); } return roles; } public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) { List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); for (String role : roles) { authorities.add(new SimpleGrantedAuthority(role)); } return authorities; } }
There is no logical reason why it should fail, but it is
be careful:
My ide can link auto connect (this is what it knows about its auto connect and everything), but the compilation failed
Edit 2: I have from securityconfig The following code has been deleted from the java file
@Autowired private UserDataService userDataService;
And add it to one of the POJOs and controllers I know, and call and include other services regularly In this case, paste the code into my basecontroller Java file, which points to the rendering home page The service is compiled correctly and can even be called within the controller
So the problem is just the configuration file, such as securityconfig Java, this is the only time it doesn't work
Edit 3: add additional files
SecurityInitializer. java
@Order(2) public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { }
WebInitializer. java
@Order(1) public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { PersistanceConfig.class,SecurityConfig.class }; //To change body of implemented methods use File | Settings | File Templates. } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] {"/"}; } // @Override // protected Filter[] getServletFilters() { // CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); // characterEncodingFilter.setEncoding("UTF-8"); // return new Filter[] { characterEncodingFilter}; // } }
MVC scheduling servlet In XML
<beans xmlns="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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.entirety.app"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
web. In XML
<web-app 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> <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> </web-app>
Solution
Update (after providing a complete example)
It seems that you have many problems
web. XML and abstractannotationconfigdispatcherservletinitializer
The application you created has a web. Net configuration with a dispatcher servlet named MVC dispatcher xml. MVC dispatcher has MVC dispatcher servlet XML, which loads com springapp. All beans in the sectest package This means that MVC dispatcher can find your userdetailsservice
The application also has an abstractannotationconfigdispatcherservletinitializer, which creates a dispatcherservlet that loads the webconfig Java configuration This dispatcher servlet cannot see any beans created by MVC dispatcher
In short, you should use web XML or abstractannotationconfigdispatcherservletinitializer configures dispatcherservlets instead of both
Getrootconfigclasses and getservletconfigclasses
Any configuration in getrootconfigclasses is usually called root configuration or parent configuration, and the beans defined in getservletconfigclasses cannot be viewed Spring security uses a filter named springsecurityfilterchain created by the @ enablewebsecurity annotation to protect the application defined in getrootconfigclasses This means that it is usually best to put the configuration of spring security in getrootconfigclasses There are some exceptions, like you want to perform method security on the spring MVC controller
Any configuration in getservletconfigclasses is often referred to as a sub configuration, and you can view the beans defined in getrootconfigclasses Getservletconfigclasses configures dispatcherservlet, and must contain the bean of spring MVC (i.e. controller, viewresovlers, etc.) Any spring MVC beans defined in getrootconfigclasses are visible but not used
Although this setting is a bit confusing, you can use multiple dispatcherservlet instances with isolation configuration In fact, there are few instances of dispatcherservlet
In view of the above information, you should move the userdetailsservice declaration and all its dependent beans to getrootconfigclasses This will ensure that securityconfig Java can find userdetailsservice
Pull request repair
I have submitted a PR to get your application so that it is never wrong https://github.com/worldcombined/AnnotateFailed/pull/1 Start A few notes
>The test doesn't use parent and child contexts, so it doesn't reflect running the application > I have to move the resource folder to be picked up correctly > I didn't do so, so you can actually authenticate No login JSP, the userdetailsservice you provided always returns null instead of trying to prove that the error here was answered
Original answer
Based on this comment:
It seems that you are configuring the service in the dispatcher configuration, not in the root context
Spring security is usually configured in the root context For example, you can extend abstractsecuritywebapplicationinitializer as follows:
import org.springframework.security.web.context.*; public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { }
How do you import security configuration? If spring security is configured in the root context, it will not see the beans defined in the dispatcher servlet context
The solution is to move the service configuration in the root context, or move the spring security configuration to the scheduler's ApplicationContext For example, if the scheduler servlet is named MVC, moving the spring security configuration to the scheduler context would look like this
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { protected String getDispatcherWebApplicationContextSuffix() { return "mvc"; } }