0

Using Spring MVC 3.2 with Spring Security 3.1

Target container is JBoss 4 (don't ask) so the servlet API is still 2.4. When testing the Spring security configuration it is written in XML and pulled into web.xml with a bunch of other stuff. Thought I would write a smaller JUnit test-bed that mocks a basic request and invokes Spring security check authentication. Idea was to help other developers test the security configuration before integrating it into the rest of the project.

Anyway if I don't define an authentication manager in the security XML I get:

 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.security.authenticationManager' is defined: Did you forget to add a gobal <authentication-manager> element to your configuration (with child <authentication-provider> elements)? Alternatively you can use the authentication-manager-ref attribute on your <http> and <global-method-security> elements.

My JUnit test class looks like this:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {LdapSecurityTest.WebAppConfig.class,
    LdapSecurityTest.WebSecurityConfig.class})
public class LdapSecurityTest {

    @Controller
    public static class DummyController {
        @RequestMapping(value = "/blankettservice/admin/test", method = RequestMethod.GET)
        @ResponseBody
        public String hello() {
            return "hello world";
        }
    }

    @EnableWebMvc
    @Configuration
    @ComponentScan("se.bolagsverket.insidan.web.common")
    public static class WebAppConfig {
    }

    @Configuration
    @ImportResource({"classpath:applicationContext-security.xml"})
    public static class WebSecurityConfig {
        @Autowired
        private List<AuthenticationProvider> providers;

        @Bean
        public AuthenticationManager authenticationManager() {
            return new ProviderManager(providers);
        }
    }

    public class SpringInitializer implements WebApplicationInitializer {

        @Override
        public void onStartup(ServletContext servletContext)
            throws ServletException {
            AnnotationConfigWebApplicationContext ctx =
                new AnnotationConfigWebApplicationContext();

            ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(
                    ctx));
            dispatcher.setLoadOnStartup(1);
            dispatcher.addMapping("/");

            servletContext.addFilter("springSecurityFilterChain",
                new DelegatingFilterProxy("springSecurityFilterChain"))
                .addMappingForUrlPatterns(null, false, "/*");
        }
    }

    @Resource
    private WebApplicationContext context;

    @Test
    public void initialize() throws Exception {

        SecurityContextHolder.getContext().setAuthentication(
            new UsernamePasswordAuthenticationToken("user", "password"));

        MockMvc mvc = webAppContextSetup(context).build();

        mvc.perform(get("/blankettservice/admin/test")).andExpect(status().isOk())
            .andExpect(content().string("hello world"));
        ;
    }
}

Just for clarity the applicationContext-security looks like:

    <http>
        <intercept-url pattern="/**/blankettservice/admin/**"
            access="ROLE_BLANKETTSERVICE_ADMIN" />
        <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <http-basic />
        <anonymous />
    </http>

    <beans:bean id="contextSource"
        class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <beans:constructor-arg value="ldap://server:port" />
        <beans:property name="userDn" value="..." />
        <beans:property name="password" value="..." />
    </beans:bean>

    <beans:bean id="bvLdapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider>
    ....
    </beans:bean>

The ProviderManager bean that is created is populated with the bvLdapAuthProvider provider.

Matthew Campbell
  • 1,864
  • 3
  • 24
  • 51
  • If I add the name "org.springframework.security.authenticationManager" to my AuthenticationManager bean then the error goes away. – Matthew Campbell Jan 29 '14 at 06:03
  • Never getting denied access. That is the problem now. See that my authorization provider is being run there is no connection to the HTTP intercept-url against "/blankettservice/admin/test". – Matthew Campbell Jan 29 '14 at 06:35
  • The Spring security filter is never initialized. Nor is my LDAP auth provider called (initialized yes but not called for authentication). – Matthew Campbell Jan 29 '14 at 08:42

1 Answers1

0

In our configuration (Spring Security 3) for LDAP we use this config :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-3.1.xsd
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">

...

<security:authentication-manager>
    <security:ldap-authentication-provider user-dn-pattern="uid={0},ou=people"/>
</security:authentication-manager>
<security:ldap-server url="ldap://localhost:10389/dc=example,dc=com" />

...

Hope it helps you.

Mannekenpix
  • 744
  • 7
  • 15