001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.authroles.authentication; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.Page; 021import org.apache.wicket.RestartResponseAtInterceptPageException; 022import org.apache.wicket.Session; 023import org.apache.wicket.WicketRuntimeException; 024import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener; 025import org.apache.wicket.authorization.UnauthorizedInstantiationException; 026import org.apache.wicket.authroles.authorization.strategies.role.IRoleCheckingStrategy; 027import org.apache.wicket.authroles.authorization.strategies.role.RoleAuthorizationStrategy; 028import org.apache.wicket.authroles.authorization.strategies.role.Roles; 029import org.apache.wicket.markup.html.WebPage; 030import org.apache.wicket.protocol.http.WebApplication; 031import org.apache.wicket.request.Request; 032import org.apache.wicket.request.Response; 033 034 035/** 036 * A web application subclass that does role-based authentication. 037 * 038 * @author Jonathan Locke 039 */ 040public abstract class AuthenticatedWebApplication extends WebApplication 041 implements 042 IRoleCheckingStrategy, 043 IUnauthorizedComponentInstantiationListener 044{ 045 @Override 046 protected void init() 047 { 048 super.init(); 049 050 // Set authorization strategy and unauthorized instantiation listener 051 getSecuritySettings().setAuthorizationStrategy(new RoleAuthorizationStrategy(this)); 052 getSecuritySettings().setUnauthorizedComponentInstantiationListener(this); 053 } 054 055 @Override 056 public final boolean hasAnyRole(final Roles roles) 057 { 058 final Roles sessionRoles = AbstractAuthenticatedWebSession.get().getRoles(); 059 return (sessionRoles != null) && sessionRoles.hasAnyRole(roles); 060 } 061 062 @Override 063 public final void onUnauthorizedInstantiation(final Component component) 064 { 065 // If there is a sign in page class declared, and the unauthorized 066 // component is a page, but it's not the sign in page 067 if (component instanceof Page) 068 { 069 if (!AbstractAuthenticatedWebSession.get().isSignedIn()) 070 { 071 // Redirect to intercept page to let the user sign in 072 restartResponseAtSignInPage(); 073 } 074 else 075 { 076 onUnauthorizedPage(component); 077 } 078 } 079 else 080 { 081 // The component was not a page, so throw an exception 082 throw new UnauthorizedInstantiationException(component.getClass()); 083 } 084 } 085 086 /** 087 * Restarts response at sign in page. 088 * 089 * NOTE: this method internally throws a restart response exception, so no code after a call to 090 * this method will be executed 091 */ 092 public void restartResponseAtSignInPage() 093 { 094 throw new RestartResponseAtInterceptPageException(getSignInPageClass()); 095 } 096 097 /** 098 * {@inheritDoc} 099 */ 100 @Override 101 public Session newSession(final Request request, final Response response) 102 { 103 Class<? extends AbstractAuthenticatedWebSession> webSessionClass = getWebSessionClass(); 104 try 105 { 106 return webSessionClass 107 .getDeclaredConstructor(Request.class) 108 .newInstance(request); 109 } 110 catch (Exception e) 111 { 112 throw new WicketRuntimeException("Unable to instantiate web session " + 113 webSessionClass, e); 114 } 115 } 116 117 /** 118 * @return BaseAuthenticatedWebSession subclass to use in this authenticated web application. 119 */ 120 protected abstract Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass(); 121 122 /** 123 * @return Subclass of sign-in page 124 */ 125 protected abstract Class<? extends WebPage> getSignInPageClass(); 126 127 /** 128 * Called when an AUTHENTICATED user tries to navigate to a page that they are not authorized to 129 * access. You might want to override this to navigate to some explanatory page or to the 130 * application's home page. 131 * 132 * @param page 133 * The partially constructed page (only the component id is guaranteed to be valid). 134 */ 135 protected void onUnauthorizedPage(final Component page) 136 { 137 throw new UnauthorizedInstantiationException(page.getClass()); 138 } 139}