Spring Security 3.0.5自定义筛选器问题

时间:2011-03-27 07:30:04

标签: spring spring-security

当我尝试使用spring security 3.0.5配置新的自定义身份验证过滤器时,它会在服务器启动时调用自定义过滤器(XMLAuthenticationFilter)构造函数并抱怨没有指定authenticationManager,请参阅下面的例外。目标是使用基于表单和基于自定义的身份验证... XMLAuthenticationFilter.java如何挂钩到AuthenticationManager并且应该在服务器启动时调用构造函数?

security-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
    xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config />
    <context:component-scan base-package="dc" />
    <global-method-security />
    <http access-denied-page="/auth/denied.html">
         <intercept-url filters="none" pattern="/javax.faces.resource/**" />
         <intercept-url filters="none" pattern="/services/rest-api/1.0/**" />
         <intercept-url filters="none" pattern="/preregistered/*"/>
         <intercept-url
            pattern="/**/*.xhtml"
            access="ROLE_NONE_GETS_ACCESS" />
        <intercept-url
            pattern="/auth/**"
            access="ROLE_ANONYMOUS,ROLE_USER" />
         <intercept-url
            pattern="/auth/*"
            access="ROLE_ANONYMOUS" />
         <intercept-url
            pattern="/registered/*"
            access="ROLE_USER" />
          <intercept-url
            pattern="/*"
           access="ROLE_ANONYMOUS" />
        <form-login
            login-processing-url="/j_spring_security_check.html"
            login-page="/auth/login.html"
            default-target-url="/registered/home.html"
            authentication-failure-url="/auth/login.html" />
         <logout invalidate-session="true" 
              logout-success-url="/" 
              logout-url="/auth/logout.html"/>
        <anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
        <remember-me user-service-ref="userManager" key="ddddd"/>
        <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
    </http>
    <!-- Configure the authentication provider -->
    <authentication-manager alias="am">
        <authentication-provider user-service-ref="userManager">
                <password-encoder ref="passwordEncoder" />
        </authentication-provider>
        <authentication-provider ref="xmlAuthenticationProvider" />
    </authentication-manager>
 <bean id="xmlAuthenticationFilter" class="com.dc.api.service.impl.XMLAuthenticationFilter"/>
    <bean id="xmlAuthenticationProvider" class="com.dc.api.service.impl.XMLAuthenticationProvider"/>
</beans:beans>

自定义身份验证提供者:

   import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.core.userdetails.UserDetails;

    public class XMLAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{

        @Override
        protected void additionalAuthenticationChecks(UserDetails arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException {
            // TODO Auto-generated method stub

        }

        @Override
        protected UserDetails retrieveUser(String arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException {
            // TODO Auto-generated method stub
            return null;
        }
    }

自定义过滤器(AbstractAuthenticationProcessingFilter):

import java.io.IOException;    
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

public class XMLAuthenticationFilter extends AbstractAuthenticationProcessingFilter{
    public XMLAuthenticationFilter() {
        super("/xml_security_check");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest arg0,
            HttpServletResponse arg1) throws AuthenticationException,
            IOException, ServletException {
        // TODO Auto-generated method stub
        return null;
    }

} 

异常

SEVERE: Exception sending context initialized event to listener instance of class org.jboss.resteasy.plugins.spring.SpringContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xmlAuthenticationFilter' defined in ServletContext resource [/WEB-INF/dc-context-api.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: authenticationManager must be specified
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
        at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
        at org.jboss.resteasy.plugins.spring.SpringContextLoaderListener.contextInitialized(SpringContextLoaderListener.java:44)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4521)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5004)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:4999)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:680)
    Caused by: java.lang.IllegalArgumentException: authenticationManager must be specified

1 个答案:

答案 0 :(得分:6)

您有一个别名为“am”的身份验证管理器,您在哪里设置过滤器中的authenticationmanager-property?也许 XMLAuthenticationFilter 的xml配置应该是这样的:

<bean id="xmlAuthenticationFilter" class="com.dc.api.service.impl.XMLAuthenticationFilter">
    <property name="authenticationManager" ref="am"/>
</bean>

我认为AbstractAuthenticationProcessingFilter从它的afterPropertiesSet方法抛出异常(它应该在行之后的嵌套堆栈跟踪中可见:引起:java.lang.IllegalArgumentException:必须指定authenticationManager )。 AbstractAuthenticationProcessingFilters的文档说必须设置管理器:

  

身份验证流程

     

过滤器   要求你设置    authenticationManager 属性。一个   AuthenticationManager是必需的   处理身份验证请求   通过实施创建的令牌   类。