尝试自动装配到自定义身份验证提供程序时,自动装配服务为空

Autowired Service is null when trying to Autowire into custom Authentication Provider

我正在尝试使用自定义身份验证提供程序配置 spring 安全性。但是我想在服务中自动装配以处理实际的数据库身份验证。我已经验证它可以在没有这个自动装配的 bean 的情况下工作(只是在提供者中进行硬编码)。我也将 SpringMVC 与休眠结合使用。我目前正在使用根配置(hibernate 等)和 webMVC 使用 java 注释和 spring 使用 xml 进行混合方法。我知道这是不受欢迎的,但我正处于时间紧迫的状态,不想花时间更改为 java 配置。

我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/security-context.xml
        </param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <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>

</web-app>

我的安全上下文:

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

    <security:http 
            realm="Protected API"
            use-expressions="true"
            auto-config="false"
            create-session="stateless"
            entry-point-ref="unauthorizedEntryPoint">
        <security:intercept-url pattern="/User/sign_up/*" access="permitAll" />
        <security:intercept-url pattern="/User/authenticate/**" access="permitAll" />
        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        <security:custom-filter ref="authenticationTokenFilter" position="FORM_LOGIN_FILTER" />
    </security:http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="customAuthenticationProvider" />
    </authentication-manager>

    <beans:bean id="customAuthenticationProvider" class="pathTo:CustomAuthenticationProvider" />

    <beans:bean id="unauthorizedEntryPoint" class="pathTo:UnauthorizedEntryPoint" />

     <beans:bean id="mySuccessHandler" class="pathTo:SuccessHandler" />

    <beans:bean
        class="com.cheersuniversity.cheers.security.AuthenticationTokenFilter"
        id="authenticationTokenFilter">
        <beans:property name="authenticationManager" ref="authenticationManager" />
        <beans:property name="postOnly" value="false" />
        <beans:property name="authenticationSuccessHandler" ref="mySuccessHandler" />
    </beans:bean>

    <!-- <context:component-scan base-package="com.cheersuniversity.cheers" />
    <context:annotation-config /> -->


</beans:beans>

CustomAuthenticationProvider:这是 Autowired UserService 在 authProvider.isValidLogin 行

上返回 null 的地方
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService authService;

    @Override
    public Authentication authenticate(Authentication auth)
            throws AuthenticationException {
        String username = auth.getName();
        String password = auth.getCredentials().toString();
        List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
        System.out.println(authService == null);
        if (authService.isValidLogin(username, password)) { 
            AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

用户服务:

@Service
@Transactional
public class UserService {
//Auth code

}

如果我应该提供更多代码,请告诉我。我发现有些人有必须扫描包裹的问题。当我将该行添加到我的 security.xml 时,它在构建时失败,因为没有找到 filterChain 的 bean。根据我的研究,这似乎是一个 maven 问题,但无法按照其他人修复它的方式进行修复。然后我尝试使用下面的 java 配置来获得 spring 安全性,它仍然有空指针异常

java-配置(尝试):

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages ="correct base package")
@EnableTransactionManagement
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.authenticationProvider(authenticationProvider);
    }
}

如果您对为什么这会自动装配为 null 有任何见解,请告诉我(它在构建时不会失败,只有在身份验证提供程序中调用时才会失败)。 感谢您的帮助!

UPDATE 看起来它是自动装配的,但不是正确的版本(实际的自动装配版本)。为什么会这样? (我通过在 xml 文件中设置的 UserService 的 属性 值来解决这个问题,然后我检查它不为空。但是,在验证行仍然有一个空指针。这对我来说非常奇怪。

这是因为我没有在我的安全中加入以下内容-context.xml

<context:component-scan base-package="com.cheersuniversity.cheers" />
<context:annotation-config />

我最终意识到另一个错误(FilterBean 没有自动装配)是一个单独的问题。一旦我解决了这个问题:请参阅

感谢大家的帮助!