Wednesday, May 28, 2014

Spring Security XML Configuration maven project


As a starting point for my application, I used the maven-archetype-webapp project template. I created an instance of the archetype with help from eclipse's (kepler's) maven plugin (if you have troubles, then go here). Shown here is a walk-through of the wizard's steps:








With the web application in place, I then changed the default web.xml to the following:

<web-app>
<display-name>Archetype Created Web Application</display-name>

<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext 
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>

<!-- Configuration locations must consist of one or more comma- or space-delimited 
fully-qualified @Configuration classes. Fully-qualified packages may also 
be specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.wmmnpr.mykrb.config</param-value>
</context-param>


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

<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

I used the AnnotationConfigWebApplicationContext configurator because I'm only interested in configuring the security via XML and not the rest. 

In the org.wmmnpr.mykrb.config package(because the archetype doesn't include such a package it  had to be created as part of a new "src" folder), I created the following @Configuration class that will be scanned by the AnnotationConfigWebApplicationContext  configurator. 

@Configuration
@ImportResource("classpath:applicationContext-security.xml")
public class BootConfiguration {

}

As one can see, this class contains a reference the XML file, which configures the application's security. 

Before the project can be run, the maven-tomcat-plugin must be added to the project's pom and then started using the maven7:run goal. My first start produced the following error:

You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema with Spring Security 3.2. Please update your schema declarations to the 3.2 schema.
Offending resource: class path resource [applicationContext-security.xml]

From the message, it's clear that the "schemaLocation" attribute's map entry for the XML namespace ("s") had to be changed: 
http://www.springframework.org/schema/security/spring-security-3.2.xsd

My complete security configuration is as follows:

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

            
    <s:http use-expressions="true" auto-config="true"  > 
        <s:intercept-url pattern="/**" access="isFullyAuthenticated()"/>                
    </s:http>
    
    <s:authentication-manager>
        <s:authentication-provider ref="ldapAuthenticationProvider"/>
    </s:authentication-manager>

    <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldap://192.168.48.30/dc=gft,dc=com" />
    </bean>

    <bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">

        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <constructor-arg ref="contextSource" />
                <property name="userSearch">
                    <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
                      <constructor-arg index="0" value="ou=users,ou=frankfurt,ou=gftobjects"/>
                      <constructor-arg index="1" value="cn={0}"/>
                      <constructor-arg index="2" ref="contextSource" />
                    </bean>
                </property>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/>
        </constructor-arg>

    </bean>

</beans>


The application now starts and the index.jsp is protected. When I log in, I get:

[ERROR] An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException: Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1 ]; remaining name 'ou=users,ou=frankfurt,ou=gftobjects'
        at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:191)

I modified the XML configuration file because various things were wrong and now it works. The attributes of the parent element are the same as those above.

<beans ... >
           
    <s:http use-expressions="true" auto-config="true"  > 
        <s:intercept-url pattern="/**" access="isFullyAuthenticated()"/>                
    </s:http>
    
    <s:authentication-manager>
        <s:authentication-provider ref="ldapAuthenticationProvider"/>
    </s:authentication-manager>

    <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldap://192.168.48.30/dc=gft,dc=com" />
    </bean>

    <bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">

        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <constructor-arg ref="contextSource" />
                <property name="userDnPatterns">
                <array>
                <value>cn={0},ou=users,ou=frankfurt,ou=gftobjects</value>                            
                </array>                
                </property>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/>
        </constructor-arg>

    </bean>
</beans>

If you still have problem, then you might want to look here.
















No comments:

Post a Comment