2016-11-18 2 views
0

Я пробовал в течение как минимум 2 дней, чтобы запустить приложение, но без каких-либо успехов.
Я не знаю, почему, например, класс JwtAuthenticationProvider не распознается как Bean и поэтому успешно автоповорачивается в классе MasterprojectSecurityConfiguration.Отсутствует подходящий бит типа [PATHTOCLASS], найденный для зависимости: ожидается как минимум 1 компонент, который квалифицируется как кандидат на автоподключение для этой зависимости

Я использую конфигурацию на основе Java с Spring 4.3.0 и Java 1.8. Проблема в том, что каждый попытаться Autowire Класса (@Component) в MasterprojectSecurityConfiguration приводит к следующему Exception, а Tomcat развертывает войны-файл:

18-Nov-2016 10:45:16.099 INFO [localhost-startStop-4] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath 
18-Nov-2016 10:45:16.267 INFO [localhost-startStop-4] org.apache.catalina.core.ApplicationContext.log Initializing log4j from [/var/lib/tomcat8-masterproject/webapps/masterproject/WEB-INF/classes/_dev/log4j.xml] 
18-Nov-2016 10:45:16.325 INFO [localhost-startStop-4] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext 
18-Nov-2016 10:45:22.559 SEVERE [localhost-startStop-4] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'masterprojectSecurityConfiguration': Unsatisfied dependency expressed through field 'jwtAuthenticationProvider': No qualifying bean of type [at.oase.masterproject.security.jwt.JwtAuthenticationProvider] found for dependency [at.oase.masterproject.security.jwt.JwtAuthenticationProvider]: 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 [at.oase.masterproject.security.jwt.JwtAuthenticationProvider] found for dependency [at.oase.masterproject.security.jwt.JwtAuthenticationProvider]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) 
     at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:350) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) 
     at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444) 
     at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326) 
     at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) 
     at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4795) 
     at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221) 
     at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
     at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724) 
     at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700) 
     at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714) 
     at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:919) 
     at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1703) 
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [at.oase.masterproject.security.jwt.JwtAuthenticationProvider] found for dependency [at.oase.masterproject.security.jwt.JwtAuthenticationProvider]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1398) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1051) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1018) 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:570) 
     ... 28 more 

Также у меня есть следующие, на мой взгляд, соответствующие файлы ,

MasterprojectWebAppInitializer.java

package at.oase.masterproject.config; 

import javax.servlet.Filter; 
import javax.servlet.ServletContext; 
import javax.servlet.ServletException; 

import org.springframework.web.WebApplicationInitializer; 
import org.springframework.web.filter.CharacterEncodingFilter; 
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 
import org.springframework.web.util.Log4jConfigListener; 

import at.oase.masterproject.listener.MasterprojectContextLoaderListener; 

/** 
* Ersatz für die web.xml 
* @author djanesch 
* @version %I%, %G% 
* Createdate 17.11.2016 08:42:27 
* 
*/ 
@SuppressWarnings("deprecation") 
public class MasterprojectWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(final ServletContext servletContext) throws ServletException { 
    final String log4jConfigLocationParam = "log4jConfigLocation"; 
    servletContext.setInitParameter(log4jConfigLocationParam, "/WEB-INF/classes/${environment}/log4j.xml"); 
    servletContext.setInitParameter("log4jExposeWebAppRoot", "false"); 
    servletContext.addListener(Log4jConfigListener.class); 
    super.onStartup(servletContext); 
    } 

    /** 
    * Wird typischerweise root oder parent configuration genannt und kann keine Beans von Klassen welche in getServletConfigClasses definiert wurden sehen! 
    * HINWEIS: return null, if you don't use both root and servlet context 
    * Any configuration within getRootConfigClasses is typically called the root or parent configuration and cannot view beans defined in getServletConfigClasses. 
    * Spring Security protects your application defined in the getRootConfigClasses with a Filter named springSecurityFilterChain that is created by the @EnableWebSecurity annotation. 
    * This means it is generally best to place Spring Security's configuration in the getRootConfigClasses. 
    * There are some exceptions to this, like if you want to do method security on your Spring MVC Controllers. 
    */ 
    @Override 
    protected Class<?>[] getRootConfigClasses() { 
    return new Class[] { MasterprojectDatabaseConfiguration.class, MasterprojectSecurityConfiguration.class }; 
    } 

    /** 
    * Wird typischerweise child configuration genannt und kann Beans von Klassen welche in getRootConfigClasses definiert wurden sehen! 
    * HINWEIS: return null, if you don't use both root and servlet context 
    * Any configuration within getServletConfigClasses is typically called the child configuration and can view beans defined in the getRootConfigClasses. 
    * The getServletConfigClasses configures the DispatcherServlet and must contain beans for Spring MVC (i.e. Controllers, ViewResovlers, etc). 
    * Any Spring MVC beans defined in getRootConfigClasses are visible but not used. 
    */ 
    @Override 
    protected Class<?>[] getServletConfigClasses() { 
    return new Class[] { MasterprojectMVCConfiguration.class }; 
    } 

    /** 
    * map dispatcherServlet to "/" 
    */ 
    @Override 
    protected String[] getServletMappings() { 
    return new String[] { "/" }; 
    } 

    /** 
    * returned filters will be register to dispatcherServlet 
    */ 
    @Override 
    protected Filter[] getServletFilters() { 
    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 
    characterEncodingFilter.setEncoding("UTF-8"); 
    characterEncodingFilter.setForceEncoding(true); 
    return new Filter[] { characterEncodingFilter }; 
    } 

    @Override 
    protected void registerDispatcherServlet(ServletContext servletContext) { 
    super.registerDispatcherServlet(servletContext); 
    servletContext.addListener(new MasterprojectContextLoaderListener()); 
    } 
} 

MasterprojectSecurityConfiguration.java

package at.oase.masterproject.config; 

import javax.sql.DataSource; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.annotation.Order; 
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.config.http.SessionCreationPolicy; 
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 

import at.oase.masterproject.security.jwt.JwtAuthenticationProvider; 


@Configuration 
@EnableWebSecurity // erzeugt springSecurityFilterChain 
public class MasterprojectSecurityConfiguration extends WebSecurityConfigurerAdapter { 
    public static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization"; 
    public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/login"; 
    public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/**"; 
    public static final String TOKEN_REFRESH_ENTRY_POINT = "/token"; 

    @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider; 

    @Configuration 
    @Order(1) 
    public static class BackendSecurityAdapter extends WebSecurityConfigurerAdapter { 

     @Autowired 
     private DataSource dataSource; 

     @Autowired 
     public void configure(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(getAuthenticationProvider(dataSource)); 
     } 

     @Override 
     public void configure(WebSecurity web) throws Exception { 
      web.ignoring().antMatchers("/resources/**"); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests() 
        .antMatchers("/login", "/loginfailed", "/logout", "/sessioninvalid", 
          "/sessionexpired") 
        .permitAll().anyRequest().hasAuthority("recht.backend").and().formLogin().loginPage("/login") 
        .usernameParameter("j_username").passwordParameter("j_password").failureUrl("/login?error") 
        .defaultSuccessUrl("/home").and().exceptionHandling().and().csrf().disable(); 
     } 
    } 

    @Configuration 
    @Order(2) 
    public static class FehlerSecurityAdapter extends WebSecurityConfigurerAdapter { 
     @Autowired 
     private DataSource dataSource; 

     @Autowired 
     public void configure(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(getAuthenticationProvider(dataSource)); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests().antMatchers("/fehler/**").authenticated().and().httpBasic().and() 
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable(); 
     } 
    } 

    @Configuration 
    @Order(3) 
    public static class SchnittstelleSecurityAdapter extends WebSecurityConfigurerAdapter { 
     @Autowired 
     private DataSource dataSource; 

     @Autowired 
     public void configure(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(getAuthenticationProvider(dataSource)); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests().antMatchers("/schnittstelle/**").hasAuthority("recht.schnittstelle").and() 
        .httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() 
        .csrf().disable(); 
     } 
    } 

    public static String getUserQuery() { 
     return "SELECT b.login AS \"username\", b.passwort AS \"password\", b.aktiv AS \"enabled\" " 
       + "FROM kern_benutzer b " + "WHERE b.login=? " + "AND b.deleteuser IS NULL AND b.deletedate IS NULL"; 
    } 

    public static String getAuthoritiesQuery() { 
     return "SELECT g.id AS \"id\", g.sprachschluessel AS \"group_name\", r.sprachschluessel AS \"authority\" " 
       + "FROM kern_benutzer b " + "INNER JOIN kern_benutzer_gruppe bg ON (bg.fk_kern_benutzer=b.id) " 
       + "INNER JOIN kern_gruppe g ON (bg.fk_kern_gruppe=g.id) " 
       + "INNER JOIN kern_recht_gruppe rg ON (rg.fk_kern_gruppe=g.id) " 
       + "INNER JOIN kern_recht r ON (rg.fk_kern_recht=r.id) " + "WHERE b.login=? " 
       + "AND b.deleteuser IS NULL AND b.deletedate IS NULL " 
       + "AND bg.deleteuser IS NULL AND bg.deletedate IS NULL " 
       + "AND g.deleteuser IS NULL AND g.deletedate IS NULL " 
       + "AND rg.deleteuser IS NULL AND rg.deletedate IS NULL " 
       + "AND r.deleteuser IS NULL AND r.deletedate IS NULL"; 
    } 

    public static DaoAuthenticationProvider getAuthenticationProvider(DataSource dataSource){ 
     JdbcDaoImpl userDetailsService = new JdbcDaoImpl(); 
     userDetailsService.setDataSource(dataSource); 
     userDetailsService.setEnableAuthorities(false); 
     userDetailsService.setEnableGroups(true); 
     userDetailsService.setUsersByUsernameQuery(getUserQuery()); 
     userDetailsService.setGroupAuthoritiesByUsernameQuery(getAuthoritiesQuery()); 

     DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 
     authenticationProvider.setUserDetailsService(userDetailsService); 
     authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder()); 
     /** 
     * Es wird jetzt der neu PasswordEncoder "BCryptPasswordEncoder" verwendt, 
     * welcher automatisch dem Passwort ein Salt hinzufügt 
     * 
     ReflectionSaltSource saltSource = new ReflectionSaltSource(); 
     saltSource.setUserPropertyToUse("username"); 
     authenticationProvider.setSaltSource(saltSource);*/ 
     return authenticationProvider; 
    } 
} 

MasterprojectMVCConfiguration.java

package at.oase.masterproject.config; 

import java.util.Locale; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.support.ReloadableResourceBundleMessageSource; 
import org.springframework.web.multipart.commons.CommonsMultipartResolver; 
import org.springframework.web.servlet.ViewResolver; 
import org.springframework.web.servlet.config.annotation.CorsRegistry; 
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; 
import org.springframework.web.servlet.i18n.SessionLocaleResolver; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 
import org.springframework.web.servlet.view.JstlView; 

import at.oase.masterproject.interceptor.LayoutInterceptor; 
import dummiesmind.breadcrumb.springmvc.interceptor.BreadCrumbInterceptor; 

@Configuration 
@EnableWebMvc 
@ComponentScan("at.oase") // Durchsucht at.oase und alles darunter nach @Component (@Component, @Repository, @Service und @Controller) Klassen 
public class MasterprojectMVCConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
    configurer.enable(); 
    } 

    @Bean 
    public ViewResolver viewResolver() { 
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
    viewResolver.setViewClass(JstlView.class); 
    viewResolver.setPrefix("/WEB-INF/views/"); 
    viewResolver.setSuffix(".jsp"); 
    return viewResolver; 
    } 

    @Bean 
    public ReloadableResourceBundleMessageSource messageSource() { 
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); 
    messageSource.setDefaultEncoding("UTF-8"); 
    messageSource.setFallbackToSystemLocale(false); 
    messageSource.setUseCodeAsDefaultMessage(true); 
    messageSource.setBasename("classpath:i18n/nachrichten"); 
    return messageSource; 
    } 

    @Bean(name="localeResolver") 
    public SessionLocaleResolver sessionLocaleResolver() { 
    SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver(); 
    sessionLocaleResolver.setDefaultLocale(new Locale("de","DE")); 
    return sessionLocaleResolver; 
    } 

    @Bean 
    public CommonsMultipartResolver commonsMultipartResolver() { 
    CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); 
    commonsMultipartResolver.setDefaultEncoding("UTF-8"); 
    return commonsMultipartResolver; 
    } 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
    LayoutInterceptor lic = new LayoutInterceptor(); 
    lic.setLayoutLogin("layoutLogin"); 
    lic.setLayoutView("layout"); 
    registry.addInterceptor(lic); 
    LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor(); 
    interceptor.setParamName("sprache"); 
    registry.addInterceptor(interceptor); 
    BreadCrumbInterceptor bic = new BreadCrumbInterceptor(); 
    registry.addInterceptor(bic); 
    } 

    @Override 
    public void addResourceHandlers(final ResourceHandlerRegistry registry) { 
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); 
    } 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
    registry.addMapping("/**") 
     .allowedOrigins("http://localhost:4200") 
//  .allowedMethods("PUT", "DELETE") 
//  .allowedHeaders("header1", "header2", "header3") 
//  .exposedHeaders("header1", "header2") 
//  .allowCredentials(false).maxAge(3600) 
     ; 
    } 
} 

JwtAuthenticationProvider.java

package at.oase.masterproject.security.jwt; 

import java.util.List; 
import java.util.stream.Collectors; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.stereotype.Component; 

import at.oase.masterproject.config.MasterprojectConfig; 
import at.oase.masterproject.security.JwtAuthenticationToken; 
import at.oase.masterproject.security.UserContext; 
import at.oase.masterproject.security.token.JwtToken; 
import at.oase.masterproject.security.token.RawAccessJwtToken; 
import io.jsonwebtoken.Claims; 
import io.jsonwebtoken.Jws; 

/** 
* An {@link AuthenticationProvider} implementation that will use provided 
* instance of {@link JwtToken} to perform authentication. 
* 
* @author vladimir.stankovic 
* 
* Aug 5, 2016 
*/ 
@Component 
@SuppressWarnings("unchecked") 
public class JwtAuthenticationProvider implements AuthenticationProvider { 
    private final MasterprojectConfig config; 

    @Autowired 
    public JwtAuthenticationProvider(MasterprojectConfig config) { 
     this.config = config; 
    } 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    RawAccessJwtToken rawAccessToken = (RawAccessJwtToken) authentication.getCredentials(); 

    Jws<Claims> jwsClaims = rawAccessToken.parseClaims(config.getTokenSigningKey()); 
    String subject = jwsClaims.getBody().getSubject(); 
    List<String> scopes = jwsClaims.getBody().get("scopes", List.class); 
    List<GrantedAuthority> authorities = scopes.stream() 
     .map(authority -> new SimpleGrantedAuthority(authority)) 
     .collect(Collectors.toList()); 
    UserContext context = UserContext.create(subject, authorities); 

    return new JwtAuthenticationToken(context); 
    } 

    @Override 
    public boolean supports(Class<?> authentication) { 
    return (JwtAuthenticationToken.class.isAssignableFrom(authentication)); 
    } 
} 
+0

Возможно, ваш «JwtAuthenticationProvider» не будет сканироваться во время сканирования компонентов. –

ответ

-1

Вы автоматически проводке класс (JwtAuthenticationProvider), но он должен быть интерфейс, потому что Spring создает и использует прокси-объекты на основе интерфейсов. Создать что-то вроде этого:

@Component 
public interface JwtAuthenticationProviderService implements AuthenticationProvider { 

public Authentication authenticate(Authentication authentication) 

public boolean supports(Class<?> authentication) 
} 

Тогда ваш JwtAuthenticationProvider класса реализовать этот новый интерфейс, а затем @Autowire этот сервис интерфейса. Там может быть какая-то более глубокая проблема, но я предполагаю, что это должно исправить это.

Смежные вопросы

 Смежные вопросы