用于自定义筛选器的Spring Security Java配置

时间:2014-06-20 17:32:26

标签: spring spring-security

我正在将spring应用程序从XML配置转换为基于java的配置。我的代码中需要一个帮助。

以前我的XML配置如下

<authentication-manager id="myAuthenticationManager">
    <authentication-provider user-service-ref="employeeImpl" />
</authentication-manager>

<beans:bean id="employeeImpl" class="com.my.employee.EmployeeImpl">
    <beans:property name="dataSource">
        <beans:ref bean="myDatasource" />
    </beans:property>
    <beans:property name="usersByUsernameQuery">
        <beans:value>
            SELECT client_id, client_secret, enabled FROM client WHERE client_id=?
        </beans:value>
    </beans:property>       

    <beans:property name="authoritiesByUsernameQuery">
        <beans:value>
            SELECT client_id, authority FROM authorities WHERE client_id = ?
        </beans:value>
    </beans:property>
</beans:bean>

<beans:bean id="myCredentialsTokenEndpointFilter" class="com.my.web.controller.MyCredentialsTokenEndpointFilter">
    <beans:property name="authenticationManager" ref="myAuthenticationManager" />
    <beans:property name="tokenMappingQuery">
        <beans:value>INSERT INTO TOKEN_MAPPING (TOKEN_D, TOKEN_G) VALUES(?,?)</beans:value>
    </beans:property>
    <beans:property name="dataSource" ref="myDatasource" />
</beans:bean>

我尝试的Java配置如下..

我尝试调试代码,所以首先加载这个类

public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{

    @Override
    protected Class<?>[] getRootConfigClasses()
    {
        return new Class[] { MyBeanConfiguration.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses()
    {
        return new Class[] { MyViewConfig.class };
    }

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

    @Override
    protected Filter[] getServletFilters()
    {
        return null;
    }

}

然后调试来到这个类

@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackageClasses = EmployeeImpl.class)
public class MyWebSecurityConfigurator extends WebSecurityConfigurerAdapter
{
    /*
     * @Autowired Employee userDetailService;
     */

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private EmployeeImpl employeeImpl;

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().headers().cacheControl().contentTypeOptions().httpStrictTransportSecurity().and()
                .requestMatchers().antMatchers("/myapp/auth").and().httpBasic().authenticationEntryPoint(getEntryPoint()).and()
                .addFilterBefore(getTokenFilter(), BasicAuthenticationFilter.class).authorizeRequests().anyRequest().access("hasRole('ROLE_USER')");
    }

    public BasicAuthenticationEntryPoint getEntryPoint()
    {
        BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
        entryPoint.setRealmName("My");
        return entryPoint;
    }

    public MyCredentialsTokenEndpointFilter getTokenFilter() throws Exception
    {
        MyCredentialsTokenEndpointFilter tokenFilter = new MyCredentialsTokenEndpointFilter();
        tokenFilter.setTokenMappingQuery("INSERT INTO TOKEN_MAPPING (TOKEN_D, TOKEN_G) VALUES(?,?)");
        tokenFilter.setDataSource(dataSource);
        tokenFilter.setAuthenticationManager(authenticationManager);
        return tokenFilter;
    }

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(employeeImpl);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception
    {
        return super.authenticationManagerBean();
    }
}

我的其他课程..

@Configuration
@ComponentScan
public class MyBeanConfiguration
{

    @Autowired
    private DataSource dataSource;

    @Bean
    public MyService myService()
    {
        return new myServiceImpl();
    }

    @Bean
    public UserDetailsService employeeImpl()
    {
        EmployeeImpl employee = new EmployeeImpl();
        employee.setDataSource(dataSource);
        employee.setUsersByUsernameQuery("SELECT client_id, client_secret, enabled FROM my_client WHERE client_id=?");
        employee.setAuthoritiesByUsernameQuery("SELECT client_id, authority FROM authorities WHERE client_id = ?");
        return employee;
    }

}

@Service
public class EmployeeImpl extends JdbcDaoImpl
{
    @Autowired
    private DataSource dataSource;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        System.out.println("Received UserName : " + username);

        UserDetails user = super.loadUserByUsername(username);
        MyUser myUser = new MyUser(username, user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(),
                user.getAuthorities());

        return myUser;
    }
}

问题是每次调试到达configure(AuthenticationManagerBuilder auth) of MyWebSecurityConfigurator类时,自动装配的变量employeeImpl总是为空,所以我得到的是异常......

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyWebSecurityConfigurator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.my.employee.EmployeeImpl com.my.config.security.MyWebSecurityConfigurator.employeeImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeImpl' defined in file [D:\EclipseWS\Alfresco Research Portal\Research Portal\Spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringSecurity\WEB-INF\classes\com\my\employee\EmployeeImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4959)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.my.employee.EmployeeImpl com.my.config.security.MyWebSecurityConfigurator.employeeImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeImpl' defined in file [D:\EclipseWS\Alfresco Research Portal\Research Portal\Spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringSecurity\WEB-INF\classes\com\my\employee\EmployeeImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 22 more

需要你的建议来了解我哪里出错了......不能理解我做错了什么..

0 个答案:

没有答案