|
Glassfish example source code file (WebPermissionUtil.java)
The Glassfish WebPermissionUtil.java source code/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.enterprise.security.web.integration; import com.sun.enterprise.security.web.*; import java.util.*; import javax.security.jacc.PolicyConfiguration; import javax.security.jacc.WebResourcePermission; import javax.security.jacc.WebRoleRefPermission; import javax.security.jacc.WebUserDataPermission; import java.util.logging.*; import com.sun.logging.LogDomains; import java.security.Permission; import java.security.Permissions; import com.sun.enterprise.deployment.*; import com.sun.enterprise.deployment.web.*; /** * This class is used for generating Web permissions based on the * deployment descriptor. * @author Harpreet Singh * @author Jean-Francois Arcand * @author Ron Monzillo */ public class WebPermissionUtil { static Logger logger = Logger.getLogger(LogDomains.SECURITY_LOGGER); public WebPermissionUtil() { } /* changed to order default pattern / below extension */ private static final int PT_DEFAULT = 0; private static final int PT_EXTENSION = 1; private static final int PT_PREFIX = 2; private static final int PT_EXACT = 3; static int patternType(Object urlPattern) { String pattern = urlPattern.toString(); if (pattern.startsWith("*.")) return PT_EXTENSION; else if (pattern.startsWith("/") && pattern.endsWith("/*")) return PT_PREFIX; else if (pattern.equals("/")) return PT_DEFAULT; else return PT_EXACT; } static boolean implies(String pattern, String path) { // Check for exact match if (pattern.equals(path)) return (true); // Check for path prefix matching if (pattern.startsWith("/") && pattern.endsWith("/*")) { pattern = pattern.substring(0, pattern.length() - 2); int length = pattern.length(); if (length == 0) return (true); // "/*" is the same as "/" return (path.startsWith(pattern) && (path.length() == length || path.substring(length).startsWith("/"))); } // Check for suffix matching if (pattern.startsWith("*.")) { int slash = path.lastIndexOf('/'); int period = path.lastIndexOf('.'); if ((slash >= 0) && (period > slash) && path.endsWith(pattern.substring(1))) { return (true); } return (false); } // Check for universal mapping if (pattern.equals("/")) return (true); return (false); } public static HashMap parseConstraints(WebBundleDescriptor wbd) { if (logger.isLoggable(Level.FINE)){ logger.entering("WebPermissionUtil", "parseConstraints"); } Set<Role> roleSet = wbd.getRoles(); HashMap<String, MapValue> qpMap = new HashMap(); // bootstrap the map with the default pattern; qpMap.put("/", new MapValue("/")); //Enumerate over security constraints Enumeration<SecurityConstraint> esc = wbd.getSecurityConstraints(); while (esc.hasMoreElements()) { if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: begin parsing security constraint"); } SecurityConstraint sc = esc.nextElement(); AuthorizationConstraint ac = sc.getAuthorizationConstraint(); UserDataConstraint udc = sc.getUserDataConstraint(); // Enumerate over collections of URLPatterns within constraint for (WebResourceCollection wrc: sc.getWebResourceCollections()) { if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: begin parsing web resource collection"); } // Enumerate over URLPatterns within collection for (String url: wrc.getUrlPatterns()) { if (url != null) { // FIX TO BE CONFIRMED: encode all colons url = url.replaceAll(":","%3A"); } if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: process url: "+url); } // determine if pattern is already in map MapValue mValue = qpMap.get(url); // apply new patterns to map if (mValue == null) { mValue = new MapValue(url); //Iterate over patterns in map for(Map.Entry<String, MapValue> qpVal:qpMap.entrySet()) { String otherUrl = qpVal.getKey(); int otherUrlType = patternType(otherUrl); switch(patternType(url)) { // if the new url/pattern is a path-prefix // pattern, it must be qualified by every // different (from it) path-prefix pattern // (in the map) that is implied by the new // pattern, and every exact pattern (in the map) // that is implied by the new url. // Also, the new pattern must be added as a // qualifier of the default pattern, and every // extension pattern (existing in the map), and // of every different path-prefix pattern that // implies the new pattern. // Note that we know that the new pattern does // not exist in the map, thus we know that the // new pattern is different from any existing // path prefix pattern. case PT_PREFIX: if ((otherUrlType == PT_PREFIX || otherUrlType == PT_EXACT) && implies(url,otherUrl)) mValue.addQualifier(otherUrl); else if (otherUrlType == PT_PREFIX && implies(otherUrl,url)) qpVal.getValue().addQualifier(url); else if (otherUrlType == PT_EXTENSION || otherUrlType == PT_DEFAULT) qpVal.getValue().addQualifier(url); break; // if the new pattern is an extension pattern, // it must be qualified by every path-prefix // pattern (in the map), and every exact // pattern (in the map) that is implied by // the new pattern. // Also, it must be added as a qualifier of // the defualt pattern, if it exists in the // map. case PT_EXTENSION: if (otherUrlType == PT_PREFIX || (otherUrlType == PT_EXACT && implies(url,otherUrl))) mValue.addQualifier(otherUrl); else if (otherUrlType == PT_DEFAULT) qpVal.getValue().addQualifier(url); break; // if the new pattern is the default pattern // it must be qualified by every other pattern // in the map. case PT_DEFAULT: if (otherUrlType != PT_DEFAULT) mValue.addQualifier(otherUrl); break; // if the new pattern is an exact pattern, it // is not be qualified, but it must be added as // as a qualifier to the default pattern, and to // every path-prefix or extension pattern (in // the map) that implies the new pattern. case PT_EXACT: if ((otherUrlType == PT_PREFIX || otherUrlType == PT_EXTENSION) && implies(otherUrl,url)) qpVal.getValue().addQualifier(url); else if (otherUrlType == PT_DEFAULT) qpVal.getValue().addQualifier(url); break; } } // add the new pattern and its pattern spec to the map qpMap.put(url, mValue); } String[] methodNames = wrc.getHttpMethodsAsArray(); BitSet methods = MethodValue.methodArrayToSet(methodNames); BitSet omittedMethods = null; if (methods.isEmpty()) { String[] omittedNames = wrc.getHttpMethodOmissionsAsArray(); omittedMethods = MethodValue.methodArrayToSet(omittedNames); } // note that an empty omitted method set is used to represent // the set of all http methods mValue.setMethodOutcomes(roleSet,ac,udc,methods,omittedMethods); if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: end processing url: "+url); } } if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: end parsing web resource collection"); } } if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint translation: end parsing security constraint"); } } if (logger.isLoggable(Level.FINE)){ logger.exiting("WebPermissionUtil","parseConstraints"); } return qpMap; } static void handleExcluded(Permissions collection, MapValue m, String name) { String actions = null; BitSet excludedMethods = m.getExcludedMethods(); if (m.otherConstraint.isExcluded()) { BitSet methods = m.getMethodSet(); methods.andNot(excludedMethods); if (!methods.isEmpty()) { actions = "!" + MethodValue.getActions(methods); } } else if (!excludedMethods.isEmpty()) { actions = MethodValue.getActions(excludedMethods); } else { return; } collection.add(new WebResourcePermission(name,actions)); collection.add(new WebUserDataPermission(name,actions)); if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint capture: adding excluded methods: "+ actions); } } static Permissions addToRoleMap(HashMap<String, Permissions> map, String roleName, Permission p) { Permissions collection = map.get(roleName); if (collection == null) { collection = new Permissions(); map.put(roleName,collection); } collection.add(p); if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint capture: adding methods to role: "+ roleName+" methods: " + p.getActions()); } return collection; } static void handleRoles(HashMap<String,Permissions> map, MapValue m, String name) { HashMap<String,BitSet> rMap = m.getRoleMap(); List<String> roleList = null; // handle the roles for the omitted methods if (!m.otherConstraint.isExcluded() && m.otherConstraint.isAuthConstrained()) { roleList = m.otherConstraint.roleList; for (String roleName : roleList) { BitSet methods = m.getMethodSet(); //reduce ommissions for explicit methods granted to role BitSet roleMethods = rMap.get(roleName); if (roleMethods != null) { methods.andNot(roleMethods); } String actions = null; if (!methods.isEmpty()) { actions = "!" + MethodValue.getActions(methods); } addToRoleMap(map,roleName,new WebResourcePermission(name,actions)); } } //handle explicit methods, skip roles that were handled above BitSet methods = m.getMethodSet(); if (!methods.isEmpty()) { for (Map.Entry<String,BitSet> rval:rMap.entrySet()) { String roleName = rval.getKey(); if (roleList == null || !roleList.contains(roleName)) { BitSet roleMethods = rval.getValue(); if (!roleMethods.isEmpty()) { String actions = MethodValue.getActions(roleMethods); addToRoleMap(map,roleName,new WebResourcePermission(name,actions)); } } } } } static void handleNoAuth(Permissions collection, MapValue m, String name) { String actions = null; BitSet noAuthMethods = m.getNoAuthMethods(); if (!m.otherConstraint.isAuthConstrained()) { BitSet methods = m.getMethodSet(); methods.andNot(noAuthMethods); if (!methods.isEmpty()) { actions = "!" + MethodValue.getActions(methods); } } else if (!noAuthMethods.isEmpty()) { actions = MethodValue.getActions(noAuthMethods); } else { return; } collection.add(new WebResourcePermission(name,actions)); if (logger.isLoggable(Level.FINE)){ logger.log(Level.FINE,"JACC: constraint capture: adding unchecked (for authorization) methods: "+ actions); } } static void handleConnections(Permissions collection, MapValue m, String name) { BitSet allConnectMethods = null; boolean allConnectAtOther = m.otherConstraint.isConnectAllowed (ConstraintValue.ConnectTypeNone); for (int i=0; i<ConstraintValue.connectKeys.length; i++) { String actions = null; String transport = ConstraintValue.connectKeys[i]; BitSet connectMethods = m.getConnectMap(1<(); static { for (int i=0; i<connectKeys.length; i++) connectHash.put(connectKeys[i], Integer.valueOf(1<(); int connectSet; ConstraintValue() { excluded = false; ignoreRoleList = false; //roleList = new ArrayList<String>(); connectSet = 0; } static boolean bitIsSet(int map , int bit) { return (map & bit) == bit ? true : false; } void setRole(String role) { synchronized(roleList) { if (!roleList.contains(role)) { roleList.add(role); } } } void setPredefinedOutcome(boolean outcome) { if (!outcome) { excluded = true; } else { ignoreRoleList = true; } } void addConnectType(String guarantee) { int b = ConnectTypeNone; if (guarantee != null) { Integer bit = connectHash.get(guarantee); if (bit == null) throw new IllegalArgumentException ("constraint translation error-illegal trx guarantee"); b = bit.intValue(); } connectSet |= b; } boolean isExcluded() { return excluded; } /* ignoreRoleList is true if there was a security-constraint * without an auth-constraint; such a constraint combines to * allow access without authentication. */ boolean isAuthConstrained() { if (excluded) { return true; } else if (ignoreRoleList || roleList.isEmpty()) { return false; } return true; } boolean isTransportConstrained() { if (excluded || (connectSet != 0 && !bitIsSet(connectSet,ConnectTypeNone))) { return true; } return false; } boolean isConnectAllowed(int cType) { if (!excluded && (connectSet == 0 || bitIsSet(connectSet,ConnectTypeNone) || bitIsSet(connectSet,cType))) { return true; } return false; } void setOutcome(Set<Role> roleSet, AuthorizationConstraint ac, UserDataConstraint udc) { if (ac == null) { setPredefinedOutcome(true); } else { Enumeration eroles = ac.getSecurityRoles(); if (!eroles.hasMoreElements()) { setPredefinedOutcome(false); } else while (eroles.hasMoreElements()) { SecurityRoleDescriptor srd = (SecurityRoleDescriptor)eroles.nextElement(); String roleName = srd.getName(); if ("*".equals(roleName)) { Iterator it = roleSet.iterator(); while(it.hasNext()) { setRole(((Role)it.next()).getName()); } } else { setRole(roleName); } } } addConnectType(udc == null? null : udc.getTransportGuarantee()); if (WebPermissionUtil.logger.isLoggable(Level.FINE)){ WebPermissionUtil.logger.log (Level.FINE,"JACC: setOutcome yields: " + toString()); } } void setValue(ConstraintValue constraint) { excluded = constraint.excluded; ignoreRoleList = constraint.ignoreRoleList; roleList.clear(); Iterator rit = constraint.roleList.iterator(); while(rit.hasNext()) { String role = (String) rit.next(); roleList.add(role); } connectSet = constraint.connectSet; } public String toString() { StringBuilder roles =new StringBuilder(" roles: "); Iterator rit = roleList.iterator(); while(rit.hasNext()) { roles.append(" ").append((String) rit.next()); } StringBuilder transports = new StringBuilder("transports: "); for (int i=0; i<connectKeys.length; i++) { if (isConnectAllowed(1<(); synchronized (methodValues) { Collection<MethodValue> values = methodValues.values(); for (MethodValue v : values) { if (!v.isExcluded() && v.isAuthConstrained()) { for (String role : v.roleList) { BitSet methodSet = roleMap.get(role); if (methodSet == null) { methodSet = new BitSet(); roleMap.put(role, methodSet); } methodSet.set(v.index); } } } } return roleMap; } BitSet getConnectMap(int cType) { BitSet methodSet = new BitSet(); synchronized (methodValues) { Collection<MethodValue> values = methodValues.values(); for (MethodValue v : values) { /* * NOTE WELL: prior version of this method * could not be called during constraint parsing * because it finalized the connectSet when its * value was 0 (indicating any connection, until * some specific bit is set) * if (v.connectSet == 0) { v.connectSet = MethodValue.connectTypeNone; } */ if (v.isConnectAllowed(cType)) { methodSet.set(v.index); } } } return methodSet; } BitSet getMethodSet() { BitSet methodSet = new BitSet(); synchronized (methodValues) { Collection<MethodValue> values = methodValues.values(); for (MethodValue v : values) { methodSet.set(v.index); } } return methodSet; } void setMethodOutcomes(Set<Role> roleSet, AuthorizationConstraint ac, UserDataConstraint udc, BitSet methods,BitSet omittedMethods) { if (omittedMethods != null) { // get the ommitted methodSet BitSet methodsInMap = getMethodSet(); BitSet saved = (BitSet) omittedMethods.clone(); // determine methods being newly omitted omittedMethods.andNot(methodsInMap); // create values for newly omitted, init from otherConstraint for (int i = omittedMethods.nextSetBit(0); i >= 0; i = omittedMethods.nextSetBit(i+1)) { getMethodValue(i); } //combine this constraint into constraint on all other methods otherConstraint.setOutcome(roleSet,ac,udc); methodsInMap.andNot(saved); // recursive call to combine constraint into prior omitted methods setMethodOutcomes(roleSet,ac,udc,methodsInMap,null); } else { for (int i = methods.nextSetBit(0); i >= 0; i = methods.nextSetBit(i+1)){ // create values (and init from otherConstraint) if not in map // then combine with this constraint. getMethodValue(i).setOutcome(roleSet,ac,udc); } } } } Other Glassfish examples (source code examples)Here is a short list of links related to this Glassfish WebPermissionUtil.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.