Pages

March 2, 2011

Integrating Spring Security 3 with Wicket

In an older post I spoke about integrating Spring Security 3 with Extjs (here), now I will speak about integrating Spring Security 3 with Wicket.
Tools:
- Wicket 1.4.15
- Maven 3.0.2
- Spring Security 3.0.5
- IDE: Netbeans 6.9.1
- Server: Tomcat VI
How to start?
Just create a simple wicket application with maven and add the following dependencies for the Spring framework:


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>

The wicket application class should extends AuthenticatedWebApplication.
After that you should add the following code in web.xml:


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext-security.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

The Spring XML configuration file:



        
    <http create-session="never" auto-config="true" >
        <remember-me/>
        <intercept-url pattern="/**"/>
    </http>


    <!--
    Usernames/Passwords are
        moez/moez
        test/test
    -->
    <authentication-manager alias="authenticationManager" >
        <authentication-provider>
            <password-encoder hash="md5"/>
            <user-service>
                <user name="moez" password="f69471ca2c42621b8b8e731b2b4446e4" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
                <user name="test" password="098f6bcd4621d373cade4e832627b4f6" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    <global-method-security secured-annotations="enabled" />
</beans:beans>

The authenticated websession:

public class SpringWicketWebSession extends AuthenticatedWebSession {


    private static final Logger logger = Logger.getLogger(SpringWicketWebSession.class);

    @SpringBean(name = "authenticationManager")
    private AuthenticationManager authenticationManager;

    public SpringWicketWebSession(Request request) {
        super(request);
        injectDependencies();
        ensureDependenciesNotNull();
    }

    public static SpringWicketWebSession getSpringWicketWebSession() {
        return (SpringWicketWebSession) Session.get();
    }

    private void ensureDependenciesNotNull() {
        if (authenticationManager == null) {
            throw new IllegalStateException("Requires an authentication");
        }
    }

    private void injectDependencies() {
        InjectorHolder.getInjector().inject(this);
    }

    @Override
    public boolean authenticate(String username, String password) {
        boolean authenticated = false;
        try {
            Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            SecurityContextHolder.getContext().setAuthentication(authentication);
            authenticated = authentication.isAuthenticated();
        } catch (AuthenticationException e) {
            logger.warn("User "+username+" failed to login. Reason: ", e);
            authenticated = false;
        }
        return authenticated;
    }

    @Override
    public Roles getRoles() {
        Roles roles = new Roles();
        getRolesIfSignedIn(roles);
        return roles;
    }

    private void getRolesIfSignedIn(Roles roles) {
        if (isSignedIn()) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            addRolesFromAuthentication(roles, authentication);
        }
    }

    private void addRolesFromAuthentication(Roles roles, Authentication authentication) {
        for (GrantedAuthority authority : authentication.getAuthorities()) {
            roles.add(authority.getAuthority());
        }
    }

    

}

source code here