/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.portal.standard.security.control; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.deegree.enterprise.control.AbstractListener; import org.deegree.security.GeneralSecurityException; import org.deegree.security.UnauthorizedException; import org.deegree.security.drm.SecurityAccess; import org.deegree.security.drm.SecurityAccessManager; import org.deegree.security.drm.SecurityTransaction; import org.deegree.security.drm.model.RightType; import org.deegree.security.drm.model.Role; import org.deegree.security.drm.model.User; /** * Helper class that performs common security access tasks and checks used in * the <code>Listener</code> classes. * * @author <a href="mschneider@lat-lon.de">Markus Schneider </a> */ public class SecurityHelper { /** * Tries to acquire a <code>SecurityAccess</code> for the credentials * (username, password) stored in the associated <code>HttpSesssion</code> * of the given <code>AbstractListener</code>. * * @param listener * @throws GeneralSecurityException */ public static SecurityAccess acquireAccess(AbstractListener listener) throws GeneralSecurityException { // get USERNAME and PASSWORD from HttpSession HttpSession session = ((HttpServletRequest) listener.getRequest()).getSession(false); if (session == null) { throw new UnauthorizedException( "Sie sind nicht korrekt am System angemeldet (" + "wahrscheinlich ist der Timeout für Ihre Sitzung abgelaufen). Bitte melden Sie " + "sich erneut an.<BR/><BR/><p><a href='index.jsp'>--> zur Anmeldung</a></p>"); } String userName = (String) session.getAttribute(ClientHelper.KEY_USERNAME); String password = (String) session.getAttribute(ClientHelper.KEY_PASSWORD); // perform access check SecurityAccessManager manager = SecurityAccessManager.getInstance(); User user = manager.getUserByName(userName); user.authenticate(password); return manager.acquireAccess(user); } /** * Tries to acquire a <code>SecurityTransaction</code> for the credentials * (username, password) stored in the associated <code>HttpSesssion</code>. * * @param listener * @throws GeneralSecurityException */ public static SecurityTransaction acquireTransaction( AbstractListener listener) throws GeneralSecurityException { // get USERNAME and PASSWORD from HttpSession HttpSession session = ((HttpServletRequest) listener.getRequest()) .getSession(false); String userName = (String) session.getAttribute(ClientHelper.KEY_USERNAME); String password = (String) session.getAttribute(ClientHelper.KEY_PASSWORD); // perform access check SecurityAccessManager manager = SecurityAccessManager.getInstance(); User user = manager.getUserByName(userName); user.authenticate(password); return manager.acquireTransaction(user); } /** * Returns the administrator (the 'Administrator'- or a 'SUBADMIN:'-role) * for the given role. * * @param access * @param role * @throws GeneralSecurityException */ public static Role findAdminForRole(SecurityAccess access, Role role) throws GeneralSecurityException { Role[] allRoles = access.getAllRoles(); Role admin = access.getRoleById(Role.ID_SEC_ADMIN); for (int i = 0; i < allRoles.length; i++) { if (allRoles[i].getName().startsWith("SUBADMIN:")) { // if a subadmin-role has the update right, it is // considered to be administrative for the role if (allRoles[i].hasRight(access, RightType.UPDATE, role)) { admin = allRoles[i]; } } } return admin; } /** * Returns the associated 'Administrator'- or 'SUBADMIN:'-role of the token * holder. * * @param access * @throws GeneralSecurityException */ public static Role checkForAdminOrSubadminRole(SecurityAccess access) throws GeneralSecurityException { Role adminOrSubadminRole = null; Role[] roles = access.getUser().getRoles(access); for (int i = 0; i < roles.length; i++) { if (roles[i].getID() == Role.ID_SEC_ADMIN || roles[i].getName().startsWith("SUBADMIN:")) { if (adminOrSubadminRole == null) { adminOrSubadminRole = roles[i]; } else { throw new GeneralSecurityException( "Unzulässige Rollenvergabe: Benutzer '" + access.getUser().getTitle() + "' hat sowohl die Rolle '" + adminOrSubadminRole.getTitle() + "' als auch die Rolle '" + roles[i].getTitle() + "'."); } } } if (adminOrSubadminRole == null) { throw new UnauthorizedException( "Sie verfügen nicht über die für den Zugriff benötigte Administrator- " + "bzw. über eine Subadministrator-Rolle."); } return adminOrSubadminRole; } /** * Tests if the given token is associated with the 'Administrator'-role. * * @param token * @throws GeneralSecurityException, * this is an UnauthorizedException if the user does not have * the 'Administrator'-role */ public static void checkForAdminRole(SecurityAccess access) throws GeneralSecurityException { Role[] roles = access.getUser().getRoles(access); for (int i = 0; i < roles.length; i++) { if (roles[i].getID() == Role.ID_SEC_ADMIN) { return; } } throw new UnauthorizedException( "Sie verfügen nicht über die für den Zugriff benötigte Administrator-Rolle."); } /** * Tests if the 'SUBADMIN:' and 'Administrator'-roles are all disjoint (so * that there are no users that have more than 1 role). * * @param access * @throws GeneralSecurityException * if there is a user with more than one role */ public static void checkSubadminRoleValidity(SecurityAccess access) throws GeneralSecurityException { Role[] subadminRoles = access.getRolesByNS("SUBADMIN"); Set[] rolesAndUsers = new Set[subadminRoles.length + 1]; String[] roleNames = new String[subadminRoles.length + 1]; // admin role User[] users = access.getRoleById(Role.ID_SEC_ADMIN) .getAllUsers(access); rolesAndUsers[0] = new HashSet(); roleNames[0] = "Administrator"; for (int i = 0; i < users.length; i++) { rolesAndUsers[0].add(users[i]); } // subadmin roles for (int i = 1; i < rolesAndUsers.length; i++) { users = subadminRoles[i - 1].getAllUsers(access); rolesAndUsers[i] = new HashSet(); roleNames[i] = subadminRoles[i - 1].getTitle(); for (int j = 0; j < users.length; j++) { rolesAndUsers[i].add(users[j]); } } // now check if all usersets are disjoint for (int i = 0; i < rolesAndUsers.length - 1; i++) { Set userSet1 = rolesAndUsers[i]; for (int j = i + 1; j < rolesAndUsers.length; j++) { Set userSet2 = rolesAndUsers[j]; Iterator it = userSet2.iterator(); while (it.hasNext()) { User user = (User) it.next(); if (userSet1.contains(user)) { throw new GeneralSecurityException( "Ungültige Subadmin-Rollenvergabe. Benutzer '" + user.getTitle() + "' würde sowohl die Rolle '" + roleNames[i] + "' als auch die Rolle '" + roleNames[j] + "' erhalten."); } } } } } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: SecurityHelper.java,v $ Revision 1.5 2006/08/29 19:54:14 poth footer corrected Revision 1.4 2006/08/29 19:18:39 poth code formating / footer correction Revision 1.3 2006/07/13 08:10:56 poth file header added / references to Debug.XXXX removed Revision 1.2 2006/07/12 14:46:15 poth comment footer added ********************************************************************** */