简体   繁体   English

@Autowired在Spring Security中不起作用

[英]@Autowired not working in Spring Security

I'm implementing Spring Security using Java configuration in my Spring Web MVC project, and for some reason the @Autowired annotation is not injecting fields in my security config class. 我正在Spring Web MVC项目中使用Java配置来实现Spring Security,由于某种原因,@ @Autowired注释未在我的安全配置类中注入字段。 I found this very similar question on SO, but my setup is much simpler and the accepted answer doesn't apply at all in my case. 我在SO上发现了一个非常相似的问题,但我的设置简单得多,并且可接受的答案根本不适用于我的情况。

For reference, I followed the first three chapters of Spring's own security documentation ( here ) and got in-memory authentication working pretty quickly. 作为参考,我遵循了Spring自己的安全性文档的前三章( 在此处 ),并使内存内身份验证工作很快。 I then wanted to switch to JDBC authentication and inject a DataSource with the @Autowired annotation (as shown in this example ). 然后,我想切换到JDBC身份验证,并注入带有@Autowired批注的DataSource (如本示例所示)。 However, I get this error: 但是,我收到此错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.tyedart.web.config.security.SecurityConfig.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)}

Here is my security config class. 这是我的安全配置类。 As you can see I'm working around the problem by explicitly looking up my data source: 如您所见,我通过显式查找数据源来解决此问题:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

//  @Autowired
//  private DataSource dataSource;

//  @Autowired
//  public PasswordEncoder passwordEncoder;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        InitialContext ctx = new InitialContext();
        DataSource dataSource = (DataSource) ctx.lookup("java:/comp/env/jdbc/TyedArtDB");

        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        auth
            .jdbcAuthentication()
                .dataSource(dataSource)
                .passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/manage/**").hasRole("ADMIN")
                .and()  
            .formLogin();
    }
}

And here is my very simple root-context.xml: 这是我非常简单的root-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       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
                           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">

       <!-- Root Context: defines shared resources visible to all other web components -->

       <jee:jndi-lookup id="dataSource" jndi-name="jdbc/TyedArtDB"/>

       <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

</beans>

What am I doing wrong? 我究竟做错了什么?

Add <context:component-scan base-package="your.package.where.your.bean.is"/> in root-context.xml 在root-context.xml中添加<context:component-scan base-package="your.package.where.your.bean.is"/>

You can uncomment the @Autowired in field declaration and remove it from the constractor. 您可以在字段声明中取消注释@Autowired并将其从承包商中删除。 You can find more info here 您可以在这里找到更多信息

If you @Autowired a bean, don't forget to remove the initialization using new . 如果@Autowired一个bean,请不要忘记使用new删除初始化。

I'm not 100% sure, but it looks like the problem is you are trying to Autowire DataSource, which has not actually been defined as a Spring bean: 我不确定100%,但是看来问题出在您要尝试自动装配DataSource,而实际上尚未将其定义为Spring bean:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/TyedArtDB"/>

Creates an object that can be referenced in XML, but don't think it actually creates a bean? 创建一个可以用XML引用的对象,但是不认为它实际上创建了一个bean? (could be wrong, don't really do much with JNDI lookups in spring). (可能是错误的,实际上在春季对JNDI查找没有做太多事情)。

Is it possible to switch over to pure java config and drop the XML references? 是否可以切换到纯Java配置并删除XML引用?

@Bean
public DataSource dataSource() throws Exception {
    Context ctx = new InitialContext();
    return (DataSource) ctx.lookup("jdbc/TyedArtDB");
}

(taken from this answer: https://stackoverflow.com/a/15440797/258813 ) (摘自此答案: https : //stackoverflow.com/a/15440797/258813

And you can move the password encoder like this: 您可以这样移动密码编码器:

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

taken from: http://automateddeveloper.blogspot.co.uk/2014/02/spring-4-xml-to-annotation-configuration.html 摘自: http : //automateddeveloper.blogspot.co.uk/2014/02/spring-4-xml-to-annotation-configuration.html

Here's an example I used to autowire BCryptPasswordEncoder: 这是我用来自动连接BCryptPasswordEncoder的示例:

UserServiceImpl.java UserServiceImpl.java

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public User findUserByEmail(String email) {
        return null;
    }
}

WebMvcConfig.java WebMvcConfig.java

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }
}

If you notice, WebMvcConfig.java has @Bean annotation just before passwordEncoder() method. 如果您注意到,WebMvcConfig.java在passwordEncoder()方法之前具有@Bean批注。 It indicates that a method produces a bean to be managed by the Spring container. 它指示一个方法产生一个由Spring容器管理的bean。

https://docs.spring.io/autorepo/docs/spring/4.2.4.RELEASE/javadoc-api/org/springframework/context/annotation/Bean.html https://docs.spring.io/autorepo/docs/spring/4.2.4.RELEASE/javadoc-api/org/springframework/context/annotation/Bean.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM