I'm trying to create a custom filter to take care of authentication, since I'm forced to use a combination of an AD and local database (arg!) to determine access rights. I'm using the official docs, for this particular issue mostly this part.
However, when I run my server it is complaining about the AuthenticationManager being null, while I believe I am setting it in XML as covered in this SO question. What am I missing here?
The exception:
SEVERE: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myUsernamePasswordAuthenticationFilter' defined in file [*snip*]:
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: authenticationManager must be specified
...
Caused by: java.lang.IllegalArgumentException: authenticationManager must be specified
at org.springframework.util.Assert.notNull(Assert.java:112)
The XML: (with some simplified class names)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties" />
<context:spring-configured />
<context:component-scan base-package="myapp" />
<!-- Spring Security Configuration. -->
<sec:http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint"
access-denied-page="/denied.jsp">
<sec:custom-filter position="FORM_LOGIN_FILTER" ref="myAuthenticationFilter" />
<sec:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/404.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
<sec:logout logout-url="/logout" logout-success-url="/login" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="myAuthenticationProvider" />
</sec:authentication-manager>
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login" />
</bean>
<bean id="myAuthenticationFilter" class="myapp.MyUsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="myAuthenticationProvider" class="myapp.MyAuthenticationProvider" />
The Filter:
@Component
public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public AdminUsernamePasswordAuthenticationFilter() {
super("/login");
}
@Override
public Authentication attemptAuthentication(final HttpServletRequest request,
final HttpServletResponse response) throws AuthenticationException {
// stuff and:
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(
login, request.getParameter("password")));
}
}
The AuthenticationProvider:
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
// all the funky AD+DB code
return null;
}
@Override
public boolean supports(final Class<?> clazz) {
return true;
}
}
I am running Java 6, the latest Spring Security (3.1.4.RELEASE) and Spring (3.2.3.RELEASE) versions, running on a Tomcat v6 server. Different Spring versions do not appear to be a problem (related SO question). And if it would be a problem, having to run Spring 3.1.4 if you want to use Spring Security is just meh...
Some additional things I tried to no avail:
- I tried ditching the
<sec:authentication-manager />in favour of a normal bean, as mentioned here (bottom answer). - I tried adding bean id's, names, authentication-manager-refs in all sorts of combinations.