【问题标题】:@Autowire is not working in Spring security Custom Authentication provider@Autowire 在 Spring 安全自定义身份验证提供程序中不起作用
【发布时间】:2011-10-24 20:04:25
【问题描述】:

我们有 Spring MVC 应用程序。我们正在尝试将 Spring 安全性集成到其中。

我们已经编写了我们的自定义身份验证提供程序,它将完成身份验证工作。

以下是我的自定义身份验证提供程序的代码。

    public class CustomAuthenticationProvider extends DaoAuthenticationProvider {

    @Autowired
    private AuthenticationService authenticationService;

    @Override
    public Authentication authenticate(Authentication authentication) {

        CustomAuthenticationToken auth = (CustomAuthenticationToken) authentication;

        String username = String.valueOf(auth.getPrincipal());
        String password = String.valueOf(auth.getCredentials());

        try {

            Users user = new User();
            user.setUsername(username);
            user.setPassword(PasswordUtil.encrypt(password));

            user = authenticationService.validateLogin(user);

            return auth;
        } catch (Exception e) {
            throw new BadCredentialsException("Username/Password does not match for " + username);
        }
    }

    @Override
    public boolean supports(Class<? extends Object> authentication) {
        return (CustomAuthenticationToken.class.isAssignableFrom(authentication));

    }
}

在这里,我在下一行得到 NullpointerException

user = authenticationService.validateLogin(user);

authenticationService 未在自定义身份验证提供程序中自动装配。虽然相同的服务 authenticationService 在我的 MVC 控制器中以相同的方式自动装配。

这是因为身份验证提供程序是 Spring 安全组件吗?

下面是我的 web.xml

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/myApp-security.xml
    </param-value>
</context-param>

<servlet>
    <servlet-name>myApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/myApp-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>myApp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

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

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

编辑 1:-

我在我的 spring 安全配置文件中添加了以下几行。

<beans:bean id="customAuthenticationProvider" class="com.myApp.security.provider.CustomAuthenticationProvider">
    <beans:property name="userDetailsService" ref="userDetailsService"/>   
</beans:bean>

请帮助如何在 Spring 安全组件中自动装配我的服务类?

【问题讨论】:

  • 您是否有报告任何有用的日志文件?

标签: spring-mvc spring-security autowired


【解决方案1】:

如果您使用的是 Spring MVC,那么您必须在 contextConfigLocation 中添加 spring-security.xml 和 dispatcher-servlet.xml

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml
            /WEB-INF/dispatcher-servlet.xml
        </param-value>
    </context-param>

【讨论】:

    【解决方案2】:

    我遇到了同样的问题并修复了它。

    即使您为服务类设置了@Autowired 注释,解决方案也是如此。

     @Autowired
     private AuthenticationService authenticationService;
    

    删除了 dispatcher-servlet.xml 中的 bean 定义,它将起作用。

     <!--
     <beans:bean id="customAuthenticationProvider" class="com.myApp.security.provider.CustomAuthenticationProvider">
     <beans:property name="userDetailsService" ref="userDetailsService"/>   
     </beans:bean>
     -->
    

    并将其添加到安全上下文文件中

    【讨论】:

      【解决方案3】:

      你应该使用 您不能使用,因为您的 myApp-security.xml 正在创建另一个 ApplicationContext,它看不到 myApp-servlet.xml 创建的上下文中的所有自动装配

      【讨论】:

        【解决方案4】:

        我遇到了这个问题并得出结论,在进行自动装配时,spring security 正在使用完全不同的类实例运行。为了解决这个问题,我将安全配置导入到 spring mvc 配置中,如下所示。

        这允许 Spring security 与我的 spring mvc 共享上下文。

        <import resource="myapp-security.xml" />
        

        【讨论】:

          【解决方案5】:

          您使用的是&lt;debug/&gt; 元素吗?如果是这样,请尝试删除以查看它是否可以解决您的问题,因为 SEC-1885 会阻止 @Autowired 在使用 &lt;debug/&gt; 时工作。

          【讨论】:

          • 好!我花了 4 个小时弄清楚为什么它不起作用,甚至创建了这个帖子 stackoverflow.com/questions/23437738/…。谢谢,罗伯!!这就是我的问题。(我仍然使用 3.1.0)
          【解决方案6】:

          可能在根应用程序上下文中未启用自动装配后处理器(但在 DispatcherServlet 的上下文中启用作为&lt;mvc:annotation-driven&gt;&lt;context:component-scan&gt; 的副作用)。

          您可以通过将&lt;context:annotation-config&gt; 添加到myApp-security.xml 来启用它。

          【讨论】:

          • 我试过了,但它不起作用。事实上,在我的 myApp-security.xml 中添加这一行之后,应用程序甚至都没有被部署。
          • @Ashish:您是否也将相应的context 架构定义添加到 xml 标头中?
          • 如果没有运气,你为什么把它标记为正确答案?!
          • 它是如何被标记为正确答案的。完全没有运气。投反对票以节省其他人的时间。
          • 投反对票,因为这不是正确的答案,请参阅 Rob Winch 的答案。
          【解决方案7】:

          您需要将您的 CustomAuthenticationProvider 定义为 spring bean(通常在 applicationContext.xml 或 applicationContext-security.xml 中,如果有的话)

          【讨论】:

          • C 感谢您的回答。我在 spring security xml 中定义了我的自定义身份验证提供程序。请参阅我已经更新了我的问题。我还需要做什么吗?
          • 我在您的 bean 配置文件中没有看到您的 AuthenticationService。 AuthenticationService 也必须定义为一个 bean。您的 CustomAuthenticationProvider 是否也在您尝试使用它的地方自动装配?因为如果你自己实例化它,spring 无法将它包装在代理中
          • AuthenticationService 没有在 bean 配置文件中定义,因为我在这里使用了 @Service 注解。
          猜你喜欢
          • 1970-01-01
          • 2011-02-25
          • 1970-01-01
          • 1970-01-01
          • 2017-11-21
          • 2011-02-09
          • 1970-01-01
          • 2013-05-03
          • 1970-01-01
          相关资源
          最近更新 更多