org.wicketstuff.wicket.servlet3.auth.ServletContainerAuthenticatedWebApplication Maven / Gradle / Ivy
/*
* Copyright 2014 WicketStuff.
*
* Licensed 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.wicketstuff.wicket.servlet3.auth;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.core.request.handler.IPageClassRequestHandler;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.wicket.mount.core.AutoMounter;
import org.wicketstuff.wicket.mount.core.annotation.MountPath;
import org.wicketstuff.wicket.servlet3.auth.annotation.SecureAutoMount;
/**
* A web application subclass that does role-based authentication. This class
* requires authentication to be configured using the Servlet Container.
*
* @author jsarman
*/
@SecureAutoMount
public abstract class ServletContainerAuthenticatedWebApplication extends AuthenticatedWebApplication
{
private final static Logger LOG = LoggerFactory.getLogger(ServletContainerAuthenticatedWebApplication.class);
/**
* @see org.apache.wicket.protocol.http.WebApplication#init()
*/
@Override
protected void init()
{
super.init();
// Add overrides for bookmarkable and nonbookmarkable page creations to allow servlet container
// authorization mechanism to handle redirect to login page.
final ContainerSecurityInterceptorListener listener = new ContainerSecurityInterceptorListener();
getSecuritySettings().setUnauthorizedComponentInstantiationListener(listener);
getRequestCycleListeners().add(listener);
autoMountPages();
}
protected boolean autoMountPages()
{
final boolean mountOk = AutoMounter.mountAll(this);
if (!mountOk)
{
LOG.warn("Unable to Automount pages.");
}
final Class extends WebPage> authPage = getSignInPageClass();
if (authPage != null)
{
final MountPath mp = authPage.getAnnotation(MountPath.class);
if (mp == null)
{
final SecureAutoMount annot = getClass().getAnnotation(SecureAutoMount.class);
String root = annot.defaultRoot().trim();
if (!root.isEmpty() && !root.endsWith("/"))
{
root = root + "/";
}
String mime = annot.defaultMimeExtension().trim();
if (!mime.isEmpty() && !mime.startsWith("."))
{
mime = "." + mime;
}
final String loginPagePath = root + "login" + mime;
LOG.info("Mounting SignInPageClass: {} to path {}", authPage, loginPagePath);
mountPage(loginPagePath, authPage);
}
}
return mountOk;
}
@Override
protected final Class extends AbstractAuthenticatedWebSession> getWebSessionClass()
{
return getContainerManagedWebSessionClass();
}
protected abstract Class extends ServletContainerAuthenticatedWebSession> getContainerManagedWebSessionClass();
/**
* ContainerSecurityInterceptorListener forces all pages requiring
* authentication to use servlet containers authentication strategy. In
* cases where a bookmarkable page is requested the class redirects to itself
* forcing an instantiation. When a page requiring authentication is
* instantiated, the page is unauthorized for Rendering. If the mount path
* is configured such that the servlet container will intercept the request
* then the container will apply the auth required. If the pages url isn't
* matched by a security-constraint then wicket will respond with
* unauthorized access.
*/
private class ContainerSecurityInterceptorListener extends AbstractRequestCycleListener
implements IUnauthorizedComponentInstantiationListener
{
@Override
public void onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler)
{
if (handler instanceof IPageClassRequestHandler)
{
final IPageClassRequestHandler classHandler = (IPageClassRequestHandler) handler;
final Class pgClass = (Class) classHandler.getPageClass();
final boolean authorized = getSecuritySettings().getAuthorizationStrategy().isInstantiationAuthorized(pgClass);
if (!authorized)
{
if (!ServletContainerAuthenticatedWebSession.get().isSignedIn())
{
// A secure Page is scheduled that is not authenticated.
// Setting the RestartResponse to the class forces a request with a URL
// that the servlet container intercepts and redirects to the login page.
// If a wicket login page is used then continueToOriginalDestination will
// redirect to the page. If a non wicket page is used then the servlet container
// will redirect to the page using its mechanism.
// If the page is not mounted to a path that matches a security-constraint in web.xml
// then unauthorized page will result.
final PageParameters pp = classHandler.getPageParameters();
throw new RestartResponseAtInterceptPageException(pgClass, pp);
}
}
}
}
@Override
public void onUnauthorizedInstantiation(Component component)
{
if (!AbstractAuthenticatedWebSession.get().isSignedIn())
{
// If a component is not authenticated unauthorize it for Rendering.
// If the page is properly mounted such that the servlet container will intercept
// the request and redirect to login page then authentication will occur normally.
// If page is not mounted properly ie mount path does not match a security-constraint
// then unauthorized page will be returned.
MetaDataRoleAuthorizationStrategy.unauthorizeAll(component, Component.RENDER);
} else
{
//Use Default implementation if authenticated.
ServletContainerAuthenticatedWebApplication.this.onUnauthorizedInstantiation(component);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy