2017-08-30 115 views
0

這是我的安全xml配置。從xml配置到java config的彈簧安全性

<?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" 
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security.xsd"> 

    <http auto-config="true"> 
     <csrf disabled="true"/> 
     <intercept-url pattern="/" access="hasRole('ROLE_USER')"/> 
     <intercept-url pattern="/welcome" access="hasRole('ROLE_USER')"/> 
     <form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error" 
        username-parameter="username" password-parameter="password"/> 
     <logout logout-success-url="/login?logout"/> 
    </http> 

    <authentication-manager alias="authenticationManager"> 
     <authentication-provider user-service-ref="userDetailsServiceImpl"> 
      <password-encoder ref="encoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <beans:bean id="userDetailsServiceImpl" class="com.egs.account.service.user.UserDetailsServiceImpl"/> 

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
     <beans:constructor-arg name="strength" value="11"/> 
    </beans:bean> 
</beans:beans> 

而這一個是我的web.xml文件。

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
     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>Account Registration Web Application</display-name> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/resources/appconfig-root.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> 


    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value/> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
</web-app> 

現在我已切換到Java配置,並且這些配置類是我的web.xml和security.xml文件的等效版本。

@Configuration 
@EnableWebSecurity 
@ComponentScan("com.egs.account.*") 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(authProvider()) 
       .inMemoryAuthentication() 
       .withUser("user").password("password").roles("USER"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.authorizeRequests() 
       .antMatchers("/").permitAll() 
       .antMatchers("/welcome**").access("hasRole('USER')") 
       .and().formLogin() 
       .loginPage("/login") 
       .defaultSuccessUrl("/welcome") 
       .failureUrl("/login?error"); 

     http.csrf().disable(); 
    } 

    @Autowired 
    public DaoAuthenticationProvider authProvider() { 
     DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); 
     authProvider.setUserDetailsService(userDetailsServiceImpl()); 
     authProvider.setPasswordEncoder(bCryptPasswordEncoder()); 

     return authProvider; 
    } 

    @Bean 
    public PasswordEncoder bCryptPasswordEncoder() { 
     return new BCryptPasswordEncoder(11); 
    } 

    @Autowired 
    public UserDetailsService userDetailsServiceImpl() { 
     return new UserDetailsServiceImpl(); 
    } 
} 

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { 

    public SecurityWebApplicationInitializer() { 
     super(SecurityConfiguration.class); 
    } 

} 


@Configuration 
@PropertySource(value = "classpath:application.properties") 
@ComponentScan(basePackages = {"com.egs.account.*"}) 
@Import({SecurityConfiguration.class, MvcConfig.class}) 
public class SpringWebAppInitializer implements WebApplicationInitializer { 

    @Autowired 
    Environment env; 

    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); 
     appContext.register(MvcConfig.class); 
     appContext.setServletContext(servletContext); 
     ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
       "dispatcher", new DispatcherServlet(appContext)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 
    } 

    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 

而當我運行應用程序,我得到這樣的例外。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'securityService': Error creating bean with name 'securityServiceImpl': Unsatisfied dependency expressed through field 'authenticationManager': No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityServiceImpl': Unsatisfied dependency expressed through field 'authenticationManager': No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

這部分我的UserController。

@Controller 
public class UserController { 

    private UserService userService; 

    @Autowired 
    private CatalogService catalogService; 

    @Autowired 
    private SecurityService securityService; 
} 

而這一次是我SecurityServiceImpl

@Service("securityServiceImpl") 
public class SecurityServiceImpl implements SecurityService { 

    @Autowired 
    private AuthenticationManager authenticationManager; 

    @Autowired 
    private UserDetailsService userDetailsService; 

    private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); 

    @Override 
    public String findLoggedInUsername() { 
     Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails(); 
     if (userDetails instanceof UserDetails) { 
      return ((UserDetails) userDetails).getUsername(); 
     } 

     return null; 
    } 

    @Override 
    public void autoLogin(String username, String password) { 
     UserDetails userDetails = userDetailsService.loadUserByUsername(username); 
     UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = 
       new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); 

     authenticationManager.authenticate(usernamePasswordAuthenticationToken); 

     if (usernamePasswordAuthenticationToken.isAuthenticated()) { 
      SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); 
      logger.debug(String.format("Auto login %s successfully!", username)); 
     } 
    } 
} 

誰能告訴我還有什麼我忘了補充,因爲我得到了這樣的可怕異常。

+1

可以格式化堆棧跟蹤? :p這是很難看,因爲它是^^ – Nathan

+0

我檢查它,它執行。 –

回答

-1

與@Bean取代@Autowired對

public DaoAuthenticationProvider authProvider() 

頂部SecurityConfiguration.java

因爲沒有豆爲AuthenticationManager會說你有例外的。

-1

問題看起來像 -

 auth.authenticationProvider(authProvider()) 
      .inMemoryAuthentication() 
      .withUser("user").password("password").roles("USER"); 

你是混合memoryRealm與authProvider() - 但不要在你的XML使用memoryRealm?你可以試試這個剝回用memoryRealm以確認您可以創建一個認證管理

我希望它是這樣的 -

auth.authenticationProvider(authProvider())