【问题标题】:Autowired Service is null when trying to Autowire into custom Authentication Provider尝试自动装配到自定义身份验证提供程序时,自动装配服务为空
【发布时间】:2015-05-05 05:25:08
【问题描述】:

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

java-config(尝试):

@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 有任何见解,请告诉我(它在构建时不会失败,只有在身份验证提供程序中调用它时才会失败)。 任何帮助表示赞赏!

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

【问题讨论】:

  • 你的意思是在CustomAuthenticationProvider中,@Autowired private UserInterface authService;是造成问题的原因吗?
  • 是的,这就是问题所在。我尝试为它创建一个接口并将其传递给它,但这并没有帮助。在这种情况下,UserInterface 应该是 UserService。我会解决问题
  • 您是否尝试将 UserService 添加到您的 spring-context.xml 中? &lt;beans:bean id="userService" class="pathTo:UserService" /&gt;
  • 我可以看到,在自动接线时,您使用的是不同的名称,即 authService 而不是 userService,您可以尝试使用 @Autowired @Qualifier("userService") private UserService authService;
  • @EpicPandaForce 我尝试将其添加到我的安全上下文中,但遇到了同样的问题。

标签: java spring spring-mvc spring-security autowired


【解决方案1】:

这是因为我的 security-context.xml 中没有包含以下内容

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

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

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2014-09-28
    • 2011-04-04
    • 2012-04-05
    • 1970-01-01
    • 2012-11-09
    相关资源
    最近更新 更多