org.jamwiki.authentication.JAMWikiPostAuthenticationFilter.java Source code

Java tutorial

Introduction

Here is the source code for org.jamwiki.authentication.JAMWikiPostAuthenticationFilter.java

Source

/**
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the latest version of the GNU Lesser General
 * Public License as published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program (LICENSE.txt); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.jamwiki.authentication;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.jamwiki.DataAccessException;
import org.jamwiki.WikiBase;
import org.jamwiki.WikiException;
import org.jamwiki.model.WikiUser;
import org.jamwiki.utils.WikiLogger;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * Provide processing of a successfully authenticated user.  This filter will examine
 * the authentication credentails for systems using LDAP or other external
 * authentication systems, and verify that the authenticated user has valid records in
 * the jam_wiki_user and similar tables; if no such records exist they will be created to
 * allow tracking of edit history and user contributions.  Additionally, this filter
 * provides capabilities for adding anonymous group permissions to anonymous users.
 */
public class JAMWikiPostAuthenticationFilter implements Filter {

    /** Standard logger. */
    private static final WikiLogger logger = WikiLogger.getLogger(JAMWikiPostAuthenticationFilter.class.getName());
    private String key;
    private boolean useJAMWikiAnonymousRoles;

    /**
     *
     */
    public void destroy() {
    }

    /**
     *
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (!(request instanceof HttpServletRequest)) {
            throw new ServletException("HttpServletRequest required");
        }
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth instanceof AnonymousAuthenticationToken) {
            // anonymous user
            this.handleAnonymousUser(auth);
        } else if (auth != null && auth.isAuthenticated()) {
            // registered user
            this.handleRegisteredUser(auth);
        }
        chain.doFilter(request, response);
    }

    /**
     *
     */
    private void handleAnonymousUser(Authentication auth) {
        if (!this.getUseJAMWikiAnonymousRoles()) {
            // the configuration file indicates that JAMWiki anonymous roles should not be 
            // used, so assume that an external system is providing this information.
            return;
        }
        // get arrays of existing Spring Security roles and JAMWiki anonymous user roles
        Collection<GrantedAuthority> springSecurityAnonymousAuthorities = auth.getAuthorities();
        Collection<GrantedAuthority> jamwikiAnonymousAuthorities = JAMWikiAuthenticationConfiguration
                .getJamwikiAnonymousAuthorities();
        if (springSecurityAnonymousAuthorities == null || jamwikiAnonymousAuthorities == null) {
            return;
        }
        List<GrantedAuthority> anonymousAuthorities = new ArrayList<GrantedAuthority>();
        anonymousAuthorities.addAll(springSecurityAnonymousAuthorities);
        anonymousAuthorities.addAll(jamwikiAnonymousAuthorities);
        // replace the existing anonymous authentication object with the new authentication array
        AnonymousAuthenticationToken jamwikiAuth = new AnonymousAuthenticationToken(this.getKey(),
                auth.getPrincipal(), anonymousAuthorities);
        jamwikiAuth.setDetails(auth.getDetails());
        jamwikiAuth.setAuthenticated(auth.isAuthenticated());
        SecurityContextHolder.getContext().setAuthentication(jamwikiAuth);
    }

    /**
     *
     */
    private void handleRegisteredUser(Authentication auth) throws ServletException {
        Object principal = auth.getPrincipal();
        // Check if Authentication returns a known principal
        if (principal instanceof WikiUserDetails) {
            // user has gone through the normal authentication path, no need to process further
            return;
        }
        // find out authenticated username
        String username;
        if (principal instanceof UserDetails) {
            // using custom authentication with Spring Security UserDetail service
            username = ((UserDetails) principal).getUsername();
        } else if (principal instanceof String) {
            // external authentication returns only username
            username = String.valueOf(principal);
        } else {
            // no known principal was found
            logger.warning("Unknown principal type: " + principal);
            username = null;
            return;
        }
        if (StringUtils.isBlank(username)) {
            logger.warning("Null or empty username found for authenticated principal");
            return;
        }
        // for LDAP and other authentication methods, verify that JAMWiki database records exist
        try {
            if (WikiBase.getDataHandler().lookupWikiUser(username) == null) {
                // if there is a valid security credential & no JAMWiki record for the user, create one
                WikiUser user = new WikiUser(username);
                // default the password empty so that the user cannot login directly
                String encryptedPassword = "";
                WikiBase.getDataHandler().writeWikiUser(user, username, encryptedPassword);
            }
        } catch (DataAccessException e) {
            logger.severe("Failure while processing user credentials for " + username, e);
            throw new ServletException(e);
        } catch (WikiException e) {
            logger.severe("Failure while processing user credentials for " + username, e);
            throw new ServletException(e);
        }
    }

    /**
     *
     */
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    /**
     * Standard get method to return the anonymous authentication token key configured
     * for anonymous users.  This value is set from the configuration file and MUST match
     * the value used when creating anonymous authentication credentials.
     */
    public String getKey() {
        return key;
    }

    /**
     *
     */
    public void setKey(String key) {
        this.key = key;
    }

    /**
     * Provide a flag to disable the addition of JAMWiki GROUP_ANONYMOUS permissions to
     * all anonymous users.
     */
    public boolean getUseJAMWikiAnonymousRoles() {
        return useJAMWikiAnonymousRoles;
    }

    /**
     * Provide a flag to disable the addition of JAMWiki GROUP_ANONYMOUS permissions to
     * all anonymous users.
     */
    public void setUseJAMWikiAnonymousRoles(boolean useJAMWikiAnonymousRoles) {
        this.useJAMWikiAnonymousRoles = useJAMWikiAnonymousRoles;
    }
}