Source Code Cross Referenced for AuthorizationManager.java in  » Wiki-Engine » JSPWiki » com » ecyrd » jspwiki » auth » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Wiki Engine » JSPWiki » com.ecyrd.jspwiki.auth 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         JSPWiki - a JSP-based WikiWiki clone.
003:
004:         Copyright (C) 2001-2003 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006:         This program is free software; you can redistribute it and/or modify
007:         it under the terms of the GNU Lesser General Public License as published by
008:         the Free Software Foundation; either version 2.1 of the License, or
009:         (at your option) any later version.
010:
011:         This program is distributed in the hope that it will be useful,
012:         but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         GNU Lesser General Public License for more details.
015:
016:         You should have received a copy of the GNU Lesser General Public License
017:         along with this program; if not, write to the Free Software
018:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:        package com.ecyrd.jspwiki.auth;
021:
022:        import java.io.File;
023:        import java.net.URL;
024:        import java.security.*;
025:        import java.security.cert.Certificate;
026:        import java.util.Map;
027:        import java.util.Properties;
028:        import java.util.WeakHashMap;
029:
030:        import org.apache.log4j.Logger;
031:        import org.freshcookies.security.policy.LocalPolicy;
032:        import org.freshcookies.security.policy.PolicyException;
033:
034:        import com.ecyrd.jspwiki.NoRequiredPropertyException;
035:        import com.ecyrd.jspwiki.WikiEngine;
036:        import com.ecyrd.jspwiki.WikiException;
037:        import com.ecyrd.jspwiki.WikiPage;
038:        import com.ecyrd.jspwiki.WikiSession;
039:        import com.ecyrd.jspwiki.auth.acl.Acl;
040:        import com.ecyrd.jspwiki.auth.acl.AclEntry;
041:        import com.ecyrd.jspwiki.auth.acl.UnresolvedPrincipal;
042:        import com.ecyrd.jspwiki.auth.authorize.Role;
043:        import com.ecyrd.jspwiki.auth.permissions.AllPermission;
044:        import com.ecyrd.jspwiki.auth.permissions.PagePermission;
045:        import com.ecyrd.jspwiki.auth.user.UserDatabase;
046:        import com.ecyrd.jspwiki.auth.user.UserProfile;
047:        import com.ecyrd.jspwiki.event.WikiEventListener;
048:        import com.ecyrd.jspwiki.event.WikiEventManager;
049:        import com.ecyrd.jspwiki.event.WikiSecurityEvent;
050:        import com.ecyrd.jspwiki.util.ClassUtil;
051:
052:        /**
053:         * <p>Manages all access control and authorization; determines what authenticated
054:         * users are allowed to do.</p>
055:         * <p>Privileges in JSPWiki are expressed as Java-standard {@link java.security.Permission}
056:         * classes. There are two types of permissions:</p>
057:         * <ul>
058:         *   <li>{@link com.ecyrd.jspwiki.auth.permissions.WikiPermission} - privileges that apply
059:         *   to an entire wiki instance: <em>e.g.,</em> editing user profiles, creating pages, creating groups</li>
060:         *   <li>{@link com.ecyrd.jspwiki.auth.permissions.PagePermission} - privileges that apply
061:         *   to a single wiki page or range of pages: <em>e.g.,</em> reading, editing, renaming
062:         * </ul>
063:         * <p>Calling classes determine whether they are entitled to perform a particular action
064:         * by constructing the appropriate permission first, then passing it and the current
065:         * {@link com.ecyrd.jspwiki.WikiSession} to the
066:         * {@link #checkPermission(WikiSession, Permission)} method. If the session's
067:         * Subject possesses the permission, the action is allowed.</p>
068:         * <p>For WikiPermissions, the decision criteria is relatively simple: the caller either
069:         * possesses the permission, as granted by the wiki security policy -- or not.</p>
070:         * <p>For PagePermissions, the logic is exactly the same if the page being checked
071:         * does not have an access control list. However, if the page does have an ACL, the
072:         * authorization decision is made based the <em>union</em> of the permissions
073:         * granted in the ACL and in the security policy. In other words, the user must
074:         * be named in the ACL (or belong to a group or role that is named in the ACL)
075:         * <em>and</em> be granted (at least) the same permission in the security policy. We
076:         * do this to prevent a user from gaining more permissions than they already
077:         * have, based on the security policy.</p>
078:         * <p>See the {@link #checkPermission(WikiSession, Permission)} and
079:         * {@link #hasRoleOrPrincipal(WikiSession, Principal)} methods for more information
080:         * on the authorization logic.</p>
081:         * @author Andrew Jaquith
082:         * @since 2.3
083:         * @see AuthenticationManager
084:         */
085:        public final class AuthorizationManager {
086:            private static final Logger log = Logger
087:                    .getLogger(AuthorizationManager.class);
088:            /**
089:             * The default external Authorizer is the {@link com.ecyrd.jspwiki.auth.authorize.WebContainerAuthorizer}
090:             */
091:            public static final String DEFAULT_AUTHORIZER = "com.ecyrd.jspwiki.auth.authorize.WebContainerAuthorizer";
092:
093:            /** Name of the default security policy file, in WEB-INF. */
094:            protected static final String DEFAULT_POLICY = "jspwiki.policy";
095:
096:            /**
097:             * The property name in jspwiki.properties for specifying the external {@link Authorizer}.
098:             */
099:            public static final String PROP_AUTHORIZER = "jspwiki.authorizer";
100:
101:            private Authorizer m_authorizer = null;
102:
103:            /** Cache for storing ProtectionDomains used to evaluate the local policy. */
104:            private Map m_cachedPds = new WeakHashMap();
105:
106:            private WikiEngine m_engine = null;
107:
108:            private LocalPolicy m_localPolicy = null;
109:
110:            private boolean m_useJAAS = true;
111:
112:            /**
113:             * Constructs a new AuthorizationManager instance.
114:             */
115:            public AuthorizationManager() {
116:            }
117:
118:            /**
119:             * Returns <code>true</code> or <code>false</code>, depending on
120:             * whether a Permission is allowed for the Subject associated with
121:             * a supplied WikiSession. The access control algorithm works this way:
122:             * <ol>
123:             * <li>The {@link com.ecyrd.jspwiki.auth.acl.Acl} for the page is obtained</li>
124:             * <li>The Subject associated with the current
125:             * {@link com.ecyrd.jspwiki.WikiSession} is obtained</li>
126:             * <li>If the Subject's Principal set includes the Role Principal that is
127:             * the administrator group, always allow the Permission</li>
128:             * <li>For all permissions, check to see if the Permission is allowed according
129:             * to the default security policy. If it isn't, deny the permission and halt
130:             * further processing.</li>
131:             * <li>If there is an Acl, get the list of Principals assigned this
132:             * Permission in the Acl: these will be role, group or user Principals, or
133:             * {@link com.ecyrd.jspwiki.auth.acl.UnresolvedPrincipal}s (see below).
134:             * Then iterate through the Subject's Principal set and determine whether
135:             * the user (Subject) posesses any one of these specified Roles or
136:             * Principals. The matching process delegates to
137:             * {@link #hasRoleOrPrincipal(WikiSession, Principal)}.
138:             * </ol>
139:             * <p>
140:             * Note that when iterating through the Acl's list of authorized Principals,
141:             * it is possible that one or more of the Acl's Principal entries are of
142:             * type <code>UnresolvedPrincipal</code>. This means that the last time
143:             * the ACL was read, the Principal (user, built-in Role, authorizer Role, or
144:             * wiki Group) could not be resolved: the Role was not valid, the user
145:             * wasn't found in the UserDatabase, or the Group wasn't known to (e.g.,
146:             * cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is
147:             * encountered, this method will attempt to resolve it first <em>before</em>
148:             * checking to see if the Subject possesses this principal, by calling
149:             * {@link #resolvePrincipal(String)}. If the (re-)resolution does not
150:             * succeed, the access check for the principal will fail by definition (the
151:             * Subject should never contain UnresolvedPrincipals).
152:             * </p>
153:             * <p>
154:             * If security not set to JAAS, will return true.
155:             * </p>
156:             * @param session the current wiki session
157:             * @param permission the Permission being checked
158:             * @see #hasRoleOrPrincipal(WikiSession, Principal)
159:             * @return the result of the Permission check
160:             */
161:            public final boolean checkPermission(WikiSession session,
162:                    Permission permission) {
163:                if (!m_useJAAS) {
164:                    //
165:                    //  Nobody can login, if JAAS is turned off.
166:                    //
167:
168:                    if (permission == null
169:                            || "login".equals(permission.getActions()))
170:                        return false;
171:
172:                    return true;
173:                }
174:
175:                //
176:                //  A slight sanity check.
177:                //
178:                if (session == null || permission == null) {
179:                    fireEvent(WikiSecurityEvent.ACCESS_DENIED, null, permission);
180:                    return false;
181:                }
182:
183:                Principal user = session.getLoginPrincipal();
184:
185:                // Always allow the action if user has AllPermission
186:                Permission allPermission = new AllPermission(m_engine
187:                        .getApplicationName());
188:                boolean hasAllPermission = checkStaticPermission(session,
189:                        allPermission);
190:                if (hasAllPermission) {
191:                    fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user,
192:                            permission);
193:                    return true;
194:                }
195:
196:                // If the user doesn't have *at least* the permission
197:                // granted by policy, return false.
198:                boolean hasPolicyPermission = checkStaticPermission(session,
199:                        permission);
200:                if (!hasPolicyPermission) {
201:                    fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
202:                    return false;
203:                }
204:
205:                // If this isn't a PagePermission, it's allowed
206:                if (!(permission instanceof  PagePermission)) {
207:                    fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user,
208:                            permission);
209:                    return true;
210:                }
211:
212:                //
213:                // If the page or ACL is null, it's allowed.
214:                //
215:                String pageName = ((PagePermission) permission).getPage();
216:                WikiPage page = m_engine.getPage(pageName);
217:                Acl acl = (page == null) ? null : m_engine.getAclManager()
218:                        .getPermissions(page);
219:                if (page == null || acl == null || acl.isEmpty()) {
220:                    fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user,
221:                            permission);
222:                    return true;
223:                }
224:
225:                //
226:                //  Next, iterate through the Principal objects assigned
227:                //  this permission. If the context's subject possesses
228:                //  any of these, the action is allowed.
229:
230:                Principal[] aclPrincipals = acl.findPrincipals(permission);
231:
232:                log.debug("Checking ACL entries...");
233:                log.debug("Acl for this page is: " + acl);
234:                log.debug("Checking for principal: "
235:                        + String.valueOf(aclPrincipals));
236:                log.debug("Permission: " + permission);
237:
238:                for (int i = 0; i < aclPrincipals.length; i++) {
239:                    Principal aclPrincipal = aclPrincipals[i];
240:
241:                    // If the ACL principal we're looking at is unresolved,
242:                    // try to resolve it here & correct the Acl
243:                    if (aclPrincipal instanceof  UnresolvedPrincipal) {
244:                        AclEntry aclEntry = acl.getEntry(aclPrincipal);
245:                        aclPrincipal = resolvePrincipal(aclPrincipal.getName());
246:                        if (aclEntry != null
247:                                && !(aclPrincipal instanceof  UnresolvedPrincipal)) {
248:                            aclEntry.setPrincipal(aclPrincipal);
249:                        }
250:                    }
251:
252:                    if (hasRoleOrPrincipal(session, aclPrincipal)) {
253:                        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user,
254:                                permission);
255:                        return true;
256:                    }
257:                }
258:                fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
259:                return false;
260:            }
261:
262:            /**
263:             * <p>Determines if the Subject associated with a
264:             * supplied WikiSession contains a desired Role or GroupPrincipal.
265:             * The algorithm simply checks to see if the Subject possesses
266:             * the Role or GroupPrincipal it in its Principal set. Note that
267:             * any user (anyonymous, asserted, authenticated) can possess
268:             * a built-in role. But a user <em>must</em> be authenticated to
269:             * possess a role other than one of the built-in ones.
270:             * We do this to prevent privilege escalation.</p>
271:             * <p>For all other cases, this method returns <code>false</code>.</p>
272:             * <p>Note that this method does <em>not</em> consult the external
273:             * Authorizer or GroupManager; it relies on the Principals that
274:             * have been injected into the user's Subject at login time, or
275:             * after group creation/modification/deletion.</p>
276:             * @param session the current wiki session, which must be non-null. If null,
277:             *            the result of this method always returns <code>false</code>
278:             * @param principal the Principal (role or group principal) to look
279:             *            for, which must be non-<cor>null</code>. If <code>null</code>,
280:             *            the result of this method always returns <code>false</code>
281:             * @return <code>true</code> if the Subject supplied with the WikiContext
282:             *         posesses the Role or GroupPrincipal, <code>false</code> otherwise
283:             */
284:            public final boolean isUserInRole(WikiSession session,
285:                    Principal principal) {
286:                if (session == null || principal == null
287:                        || AuthenticationManager.isUserPrincipal(principal)) {
288:                    return false;
289:                }
290:
291:                // Any type of user can possess a built-in role
292:                if (principal instanceof  Role
293:                        && Role.isBuiltInRole((Role) principal)) {
294:                    return session.hasPrincipal(principal);
295:                }
296:
297:                // Only authenticated users can posssess groups or custom roles
298:                if (session.isAuthenticated()
299:                        && AuthenticationManager.isRolePrincipal(principal)) {
300:                    return session.hasPrincipal(principal);
301:                }
302:                return false;
303:            }
304:
305:            /**
306:             * Returns the current external {@link Authorizer} in use. This method
307:             * is guaranteed to return a properly-initialized Authorizer, unless
308:             * it could not be initialized. In that case, this method throws
309:             * a {@link com.ecyrd.jspwiki.auth.WikiSecurityException}.
310:             * @throws com.ecyrd.jspwiki.auth.WikiSecurityException if the Authorizer could
311:             * not be initialized
312:             * @return the current Authorizer
313:             */
314:            public final Authorizer getAuthorizer()
315:                    throws WikiSecurityException {
316:                if (m_authorizer != null) {
317:                    return m_authorizer;
318:                }
319:                throw new WikiSecurityException(
320:                        "Authorizer did not initialize properly. Check the logs.");
321:            }
322:
323:            /**
324:             * <p>Determines if the Subject associated with a supplied WikiSession contains
325:             * a desired user Principal or built-in Role principal, OR is a member a
326:             * Group or external Role. The rules are as follows:</p>
327:             * <ol>
328:             * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to
329:             * {@link #isUserInRole(WikiSession, Principal)} and
330:             * return the result.</li>
331:             * <li>Otherwise, we're looking for a user Principal,
332:             * so iterate through the Principal set and see if
333:             * any share the same name as the one we are looking for.</li>
334:             * </ol>
335:             * <p><em>Note: if the Principal parameter is a user principal, the session
336:             * must be authenticated in order for the user to "possess it". Anonymous
337:             * or asserted sessions will never posseess a named user principal.</em></p>
338:             * @param session the current wiki session, which must be non-null. If null,
339:             *            the result of this method always returns <code>false</code>
340:             * @param principal the Principal (role, group, or user principal) to look
341:             *            for, which must be non-null. If null, the result of this
342:             *            method always returns <code>false</code>
343:             * @return <code>true</code> if the Subject supplied with the WikiContext
344:             *         posesses the Role, GroupPrincipal or desired
345:             *         user Principal, <code>false</code> otherwise
346:             */
347:            protected boolean hasRoleOrPrincipal(WikiSession session,
348:                    Principal principal) {
349:                // If either parameter is null, always deny
350:                if (session == null || principal == null) {
351:                    return false;
352:                }
353:
354:                // If principal is role, delegate to isUserInRole
355:                if (AuthenticationManager.isRolePrincipal(principal)) {
356:                    return isUserInRole(session, principal);
357:                }
358:
359:                // We must be looking for a user principal, assuming that the user
360:                // has been properly logged in.
361:                // So just look for a name match.
362:                if (session.isAuthenticated()
363:                        && AuthenticationManager.isUserPrincipal(principal)) {
364:                    String principalName = principal.getName();
365:                    Principal[] userPrincipals = session.getPrincipals();
366:                    for (int i = 0; i < userPrincipals.length; i++) {
367:                        Principal userPrincipal = userPrincipals[i];
368:                        if (userPrincipal.getName().equals(principalName)) {
369:                            return true;
370:                        }
371:                    }
372:                }
373:                return false;
374:            }
375:
376:            /**
377:             * Initializes AuthorizationManager with an engine and set of properties.
378:             * Expects to find property 'jspwiki.authorizer' with a valid Authorizer
379:             * implementation name to take care of group lookup operations.
380:             * @param engine the wiki engine
381:             * @param properties the set of properties used to initialize the wiki engine
382:             * @throws WikiException if the AuthorizationManager cannot be initialized
383:             */
384:            public final void initialize(WikiEngine engine,
385:                    Properties properties) throws WikiException {
386:                m_engine = engine;
387:
388:                m_useJAAS = AuthenticationManager.SECURITY_JAAS
389:                        .equals(properties.getProperty(
390:                                AuthenticationManager.PROP_SECURITY,
391:                                AuthenticationManager.SECURITY_JAAS));
392:
393:                if (!m_useJAAS)
394:                    return;
395:
396:                //
397:                //  JAAS authorization continues
398:                //
399:                m_authorizer = getAuthorizerImplementation(properties);
400:                m_authorizer.initialize(engine, properties);
401:
402:                // Initialize local security policy
403:                try {
404:                    URL policyURL = AuthenticationManager.findConfigFile(
405:                            engine, DEFAULT_POLICY);
406:
407:                    if (policyURL != null) {
408:                        File policyFile = new File(policyURL.getPath());
409:                        m_localPolicy = new LocalPolicy(policyFile, engine
410:                                .getContentEncoding());
411:                        m_localPolicy.refresh();
412:                        log.info("Initialized default security policy: "
413:                                + policyFile.getAbsolutePath());
414:                    } else {
415:                        StringBuffer sb = new StringBuffer(
416:                                "JSPWiki was unable to initialize the ");
417:                        sb
418:                                .append("default security policy (WEB-INF/jspwiki.policy) file. ");
419:                        sb
420:                                .append("Please ensure that the jspwiki.policy file exists in the default location. ");
421:                        sb
422:                                .append("This file should exist regardless of the existance of a global policy file. ");
423:                        sb
424:                                .append("The global policy file is identified by the java.security.policy variable. ");
425:                        WikiSecurityException wse = new WikiSecurityException(
426:                                sb.toString());
427:                        log.fatal(sb.toString(), wse);
428:                        throw wse;
429:                    }
430:                } catch (PolicyException e) {
431:                    log.error("Could not initialize local security policy: "
432:                            + e.getMessage());
433:                    throw new WikiException(e.getMessage());
434:                }
435:            }
436:
437:            /**
438:             * Returns <code>true</code> if JSPWiki's JAAS authorization system
439:             * is used for authorization in addition to container controls.
440:             * @return the result
441:             */
442:            protected boolean isJAASAuthorized() {
443:                return m_useJAAS;
444:            }
445:
446:            /**
447:             * Attempts to locate and initialize a Authorizer to use with this manager.
448:             * Throws a WikiException if no entry is found, or if one fails to
449:             * initialize.
450:             * @param props jspwiki.properties, containing a
451:             *            'jspwiki.authorization.provider' class name
452:             * @return a Authorizer used to get page authorization information
453:             * @throws WikiException
454:             */
455:            private final Authorizer getAuthorizerImplementation(
456:                    Properties props) throws WikiException {
457:                String authClassName = props.getProperty(PROP_AUTHORIZER,
458:                        DEFAULT_AUTHORIZER);
459:                return (Authorizer) locateImplementation(authClassName);
460:            }
461:
462:            private final Object locateImplementation(String clazz)
463:                    throws WikiException {
464:                if (clazz != null) {
465:                    try {
466:                        Class authClass = ClassUtil.findClass(
467:                                "com.ecyrd.jspwiki.auth.authorize", clazz);
468:                        Object impl = authClass.newInstance();
469:                        return impl;
470:                    } catch (ClassNotFoundException e) {
471:                        log
472:                                .fatal("Authorizer " + clazz
473:                                        + " cannot be found", e);
474:                        throw new WikiException("Authorizer " + clazz
475:                                + " cannot be found");
476:                    } catch (InstantiationException e) {
477:                        log.fatal("Authorizer " + clazz + " cannot be created",
478:                                e);
479:                        throw new WikiException("Authorizer " + clazz
480:                                + " cannot be created");
481:                    } catch (IllegalAccessException e) {
482:                        log
483:                                .fatal(
484:                                        "You are not allowed to access this authorizer class",
485:                                        e);
486:                        throw new WikiException(
487:                                "You are not allowed to access this authorizer class");
488:                    }
489:                }
490:
491:                throw new NoRequiredPropertyException("Unable to find a "
492:                        + PROP_AUTHORIZER + " entry in the properties.",
493:                        PROP_AUTHORIZER);
494:            }
495:
496:            /**
497:             * Checks to see if the local security policy allows a particular static Permission.
498:             * Do not use this method for normal permission checks; use
499:             * {@link #checkPermission(WikiSession, Permission)} instead.
500:             * @param principals the Principals to check
501:             * @param permission the Permission
502:             * @return the result
503:             */
504:            protected boolean allowedByLocalPolicy(Principal[] principals,
505:                    Permission permission) {
506:                for (int i = 0; i < principals.length; i++) {
507:                    // Get ProtectionDomain for this Principal from cache, or create new one
508:                    ProtectionDomain pd = (ProtectionDomain) m_cachedPds
509:                            .get(principals[i]);
510:                    if (pd == null) {
511:                        ClassLoader cl = this .getClass().getClassLoader();
512:                        CodeSource cs = new CodeSource(null,
513:                                (Certificate[]) null);
514:                        pd = new ProtectionDomain(cs, null, cl,
515:                                new Principal[] { principals[i] });
516:                        m_cachedPds.put(principals[i], pd);
517:                    }
518:
519:                    // Consult the local policy and get the answer
520:                    if (m_localPolicy.implies(pd, permission)) {
521:                        return true;
522:                    }
523:                }
524:                return false;
525:            }
526:
527:            /**
528:             * Determines whether a Subject posesses a given "static" Permission as
529:             * defined in the security policy file. This method uses standard Java 2
530:             * security calls to do its work. Note that the current access control
531:             * context's <code>codeBase</code> is effectively <em>this class</em>,
532:             * not that of the caller. Therefore, this method will work best when what
533:             * matters in the policy is <em>who</em> makes the permission check, not
534:             * what the caller's code source is. Internally, this method works by
535:             * excuting <code>Subject.doAsPrivileged</code> with a privileged action
536:             * that simply calls {@link java.security.AccessController#checkPermission(Permission)}.
537:             * @link AccessController#checkPermission(java.security.Permission). A
538:             *       caught exception (or lack thereof) determines whether the privilege
539:             *       is absent (or present).
540:             * @param session the WikiSession whose permission status is being queried
541:             * @param permission the Permission the Subject must possess
542:             * @return <code>true</code> if the Subject posesses the permission,
543:             *         <code>false</code> otherwise
544:             */
545:            protected final boolean checkStaticPermission(
546:                    final WikiSession session, final Permission permission) {
547:                if (!m_useJAAS)
548:                    return true;
549:
550:                Boolean allowed = (Boolean) WikiSession.doPrivileged(session,
551:                        new PrivilegedAction() {
552:                            public Object run() {
553:                                try {
554:                                    // Check the JVM-wide security policy first
555:                                    AccessController
556:                                            .checkPermission(permission);
557:                                    return Boolean.TRUE;
558:                                } catch (AccessControlException e) {
559:                                    // Global policy denied the permission
560:                                }
561:
562:                                // Try the local policy - check each Role/Group and User Principal
563:                                if (allowedByLocalPolicy(session.getRoles(),
564:                                        permission)
565:                                        || allowedByLocalPolicy(session
566:                                                .getPrincipals(), permission)) {
567:                                    return Boolean.TRUE;
568:                                }
569:                                return Boolean.FALSE;
570:                            }
571:                        });
572:                return allowed.booleanValue();
573:            }
574:
575:            /**
576:             * <p>Given a supplied string representing a Principal's name from an Acl, this
577:             * method resolves the correct type of Principal (role, group, or user).
578:             * This method is guaranteed to always return a Principal.
579:             * The algorithm is straightforward:</p>
580:             * <ol>
581:             * <li>If the name matches one of the built-in {@link com.ecyrd.jspwiki.auth.authorize.Role} names,
582:             * return that built-in Role</li>
583:             * <li>If the name matches one supplied by the current
584:             * {@link com.ecyrd.jspwiki.auth.Authorizer}, return that Role</li>
585:             * <li>If the name matches a group managed by the
586:             * current {@link com.ecyrd.jspwiki.auth.authorize.GroupManager}, return that Group</li>
587:             * <li>Otherwise, assume that the name represents a user
588:             * principal. Using the current {@link com.ecyrd.jspwiki.auth.user.UserDatabase}, find the
589:             * first user who matches the supplied name by calling
590:             * {@link com.ecyrd.jspwiki.auth.user.UserDatabase#find(String)}.</li>
591:             * <li>Finally, if a user cannot be found, manufacture
592:             * and return a generic {@link com.ecyrd.jspwiki.auth.acl.UnresolvedPrincipal}</li>
593:             * </ol>
594:             * @param name the name of the Principal to resolve
595:             * @return the fully-resolved Principal
596:             */
597:            public final Principal resolvePrincipal(String name) {
598:                if (!m_useJAAS) {
599:                    return new UnresolvedPrincipal(name);
600:                }
601:
602:                // Check built-in Roles first
603:                Role role = new Role(name);
604:                if (Role.isBuiltInRole(role)) {
605:                    return role;
606:                }
607:
608:                // Check Authorizer Roles
609:                Principal principal = m_authorizer.findRole(name);
610:                if (principal != null) {
611:                    return principal;
612:                }
613:
614:                // Check Groups
615:                principal = m_engine.getGroupManager().findRole(name);
616:                if (principal != null) {
617:                    return principal;
618:                }
619:
620:                // Ok, no luck---this must be a user principal
621:                Principal[] principals = null;
622:                UserProfile profile = null;
623:                UserDatabase db = m_engine.getUserManager().getUserDatabase();
624:                try {
625:                    profile = db.find(name);
626:                    principals = db.getPrincipals(profile.getLoginName());
627:                    for (int i = 0; i < principals.length; i++) {
628:                        principal = principals[i];
629:                        if (principal.getName().equals(name)) {
630:                            return principal;
631:                        }
632:                    }
633:                } catch (NoSuchPrincipalException e) {
634:                    // We couldn't find the user...
635:                }
636:                // Ok, no luck---mark this as unresolved and move on
637:                return new UnresolvedPrincipal(name);
638:            }
639:
640:            // events processing .......................................................
641:
642:            /**
643:             * Registers a WikiEventListener with this instance.
644:             * @param listener the event listener
645:             */
646:            public final synchronized void addWikiEventListener(
647:                    WikiEventListener listener) {
648:                WikiEventManager.addWikiEventListener(this , listener);
649:            }
650:
651:            /**
652:             * Un-registers a WikiEventListener with this instance.
653:             * @param listener the event listener
654:             */
655:            public final synchronized void removeWikiEventListener(
656:                    WikiEventListener listener) {
657:                WikiEventManager.removeWikiEventListener(this , listener);
658:            }
659:
660:            /**
661:             *  Fires a WikiSecurityEvent of the provided type, user,
662:             *  and permission to all registered listeners.
663:             *
664:             * @see com.ecyrd.jspwiki.event.WikiSecurityEvent
665:             * @param type        the event type to be fired
666:             * @param user        the user associated with the event
667:             * @param permission  the permission the subject must possess
668:             */
669:            protected final void fireEvent(int type, Principal user,
670:                    Object permission) {
671:                if (WikiEventManager.isListening(this )) {
672:                    WikiEventManager.fireEvent(this , new WikiSecurityEvent(
673:                            this, type, user, permission));
674:                }
675:            }
676:
677:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.