blob: 59f915ea4c37b105fcf0fb85e46cd3021e685960 [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.apache.wiki.ui;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
import org.apache.wiki.WikiContext;
import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
import org.apache.wiki.auth.SessionMonitor;
import org.apache.wiki.auth.WikiSecurityException;
import org.apache.wiki.tags.WikiTagBase;
/**
* Filter that verifies that the {@link org.apache.wiki.WikiEngine} is running, and
* sets the authentication status for the user's WikiSession. Each HTTP request
* processed by this filter is wrapped by a {@link WikiRequestWrapper}. The wrapper's
* primary responsibility is to return the correct <code>userPrincipal</code> and
* <code>remoteUser</code> for authenticated JSPWiki users (whether
* authenticated by container or by JSPWiki's custom system).
* The wrapper's other responsibility is to incorporate JSPWiki built-in roles
* into the role-checking algorithm for {@link HttpServletRequest#isUserInRole(String)}.
* Just before the request is wrapped, the method {@link org.apache.wiki.auth.AuthenticationManager#login(HttpServletRequest)} executes;
* this method contains all of the logic needed to grab any user login credentials set
* by the container or by cookies.
*
*
*/
public class WikiServletFilter implements Filter
{
protected static final Logger log = Logger.getLogger( WikiServletFilter.class );
protected WikiEngine m_engine = null;
/**
* Creates a Wiki Servlet Filter.
*/
public WikiServletFilter()
{
super();
}
/**
* Initializes the WikiServletFilter.
*
* @param config The FilterConfig.
* @throws ServletException If a WikiEngine cannot be started.
*/
public void init( FilterConfig config ) throws ServletException
{
ServletContext context = config.getServletContext();
// TODO REMOVEME when resolving JSPWIKI-129
if( System.getSecurityManager() != null )
{
context.log( "== JSPWIKI WARNING == : This container is running with a security manager. JSPWiki does not yet really support that right now. See issue JSPWIKI-129 for details and information on how to proceed." );
}
m_engine = WikiEngine.getInstance( context, null );
}
/**
* Destroys the WikiServletFilter.
*/
public void destroy()
{
}
/**
* Checks that the WikiEngine is running ok, wraps the current
* HTTP request, and sets the correct authentication state for the users's
* WikiSession. First, the method {@link org.apache.wiki.auth.AuthenticationManager#login(HttpServletRequest)}
* executes, which sets the authentication state. Then, the request is wrapped with a
* {@link WikiRequestWrapper}.
* @param request the current HTTP request object
* @param response the current HTTP response object
* @param chain The Filter chain passed down.
* @throws ServletException if {@link org.apache.wiki.auth.AuthenticationManager#login(HttpServletRequest)} fails for any reason
* @throws IOException If writing to the servlet response fails.
*/
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException
{
//
// Sanity check; it might be true in some conditions, but we need to know where.
//
if( chain == null )
{
throw new ServletException("FilterChain is null, even if it should not be. Please report this to the jspwiki development team.");
}
if( m_engine == null )
{
PrintWriter out = response.getWriter();
out.print("<html><head><title>Fatal problem with JSPWiki</title></head>");
out.print("<body>");
out.print("<h1>JSPWiki has not been started</h1>");
out.print("<p>JSPWiki is not running. This is probably due to a configuration error in your jspwiki.properties file, ");
out.print("or a problem with your servlet container. Please double-check everything before issuing a bug report ");
out.print("at jspwiki.apache.org.</p>");
out.print("<p>We apologize for the inconvenience. No, really, we do. We're trying to ");
out.print("JSPWiki as easy as we can, but there is only so much we have time to test ");
out.print("platforms.</p>");
out.print( "<p>Please go to the <a href='Install.jsp'>installer</a> to continue.</p>" );
out.print("</body></html>");
return;
}
// If we haven't done so, wrap the request
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Set the character encoding
httpRequest.setCharacterEncoding( m_engine.getContentEncoding() );
if( m_engine.getBaseURL().length() == 0 && !httpRequest.getRequestURI().endsWith("Install.jsp") )
{
PrintWriter out = response.getWriter();
out.print( "<html><head><title>JSPWiki installation start</title></head>" );
out.print( "<body>" );
out.print( "<h1>JSPWiki installation</h1>" );
out.print( "<p>Hello! It appears that this is your first jspwiki installation." );
out.print( "Therefore, you will need to start the installation process. " );
out.print( "Please <a href='Install.jsp'>continue to the installer</a>." );
out.print( "</p>");
out.print( "<p>If you just used the installer, then please restart your servlet container to get rid of this message.</p>" );
out.print("</body></html>");
return;
}
if ( !isWrapped( request ) )
{
// Prepare the WikiSession
try
{
m_engine.getAuthenticationManager().login( httpRequest );
WikiSession wikiSession = SessionMonitor.getInstance( m_engine ).find( httpRequest.getSession() );
httpRequest = new WikiRequestWrapper( m_engine, httpRequest );
if ( log.isDebugEnabled() )
{
log.debug( "Executed security filters for user=" + wikiSession.getLoginPrincipal().getName() + ", path=" + httpRequest.getRequestURI() );
}
}
catch ( WikiSecurityException e )
{
throw new ServletException( e );
}
}
try
{
NDC.push( m_engine.getApplicationName()+":"+httpRequest.getRequestURL() );
chain.doFilter( httpRequest, response );
}
finally
{
NDC.pop();
NDC.remove();
}
}
/**
* Figures out the wiki context from the request. This method does not create the
* context if it does not exist.
*
* @param request The request to examine
* @return A valid WikiContext value (or null, if the context could not be located).
*/
protected WikiContext getWikiContext( ServletRequest request )
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
WikiContext ctx = (WikiContext) httpRequest.getAttribute( WikiTagBase.ATTR_CONTEXT );
return ctx;
}
/**
* Determines whether the request has been previously wrapped with a WikiRequestWrapper.
* We find the wrapper by recursively unwrapping successive request wrappers, if they have been supplied.
* @param request the current HTTP request
* @return <code>true</code> if the request has previously been wrapped;
* <code>false</code> otherwise
*/
private boolean isWrapped( ServletRequest request )
{
while ( !(request instanceof WikiRequestWrapper )
&& request != null
&& request instanceof HttpServletRequestWrapper )
{
request = ((HttpServletRequestWrapper) request).getRequest();
}
return request instanceof WikiRequestWrapper ? true : false;
}
}