Source Code Cross Referenced for AccessController.java in  » 6.0-JDK-Core » security » java » security » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » java.security 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.security;
027
028        import sun.security.util.Debug;
029
030        /** 
031         * <p> The AccessController class is used for access control operations
032         * and decisions.
033         * 
034         * <p> More specifically, the AccessController class is used for 
035         * three purposes:
036         * 
037         * <ul>
038         * <li> to decide whether an access to a critical system
039         * resource is to be allowed or denied, based on the security policy
040         * currently in effect,<p> 
041         * <li>to mark code as being "privileged", thus affecting subsequent
042         * access determinations, and<p>
043         * <li>to obtain a "snapshot" of the current calling context so
044         * access-control decisions from a different context can be made with
045         * respect to the saved context. </ul>
046         * 
047         * <p> The {@link #checkPermission(Permission) checkPermission} method
048         * determines whether the access request indicated by a specified
049         * permission should be granted or denied. A sample call appears
050         * below. In this example, <code>checkPermission</code> will determine 
051         * whether or not to grant "read" access to the file named "testFile" in 
052         * the "/temp" directory.
053         * 
054         * <pre>
055         * 
056         * FilePermission perm = new FilePermission("/temp/testFile", "read");
057         * AccessController.checkPermission(perm);
058         * 
059         * </pre>
060         *
061         * <p> If a requested access is allowed, 
062         * <code>checkPermission</code> returns quietly. If denied, an 
063         * AccessControlException is
064         * thrown. AccessControlException can also be thrown if the requested
065         * permission is of an incorrect type or contains an invalid value.
066         * Such information is given whenever possible.
067         * 
068         * Suppose the current thread traversed m callers, in the order of caller 1 
069         * to caller 2 to caller m. Then caller m invoked the 
070         * <code>checkPermission</code> method.
071         * The <code>checkPermission </code>method determines whether access 
072         * is granted or denied based on the following algorithm:
073         * 
074         *  <pre> {@code
075         * for (int i = m; i > 0; i--) {
076         * 
077         *     if (caller i's domain does not have the permission)
078         *         throw AccessControlException
079         * 
080         *     else if (caller i is marked as privileged) {
081         *         if (a context was specified in the call to doPrivileged) 
082         *             context.checkPermission(permission)
083         *         return;
084         *     }
085         * };
086         *
087         * // Next, check the context inherited when the thread was created.
088         * // Whenever a new thread is created, the AccessControlContext at
089         * // that time is stored and associated with the new thread, as the
090         * // "inherited" context.
091         * 
092         * inheritedContext.checkPermission(permission);
093         * }</pre>
094         * 
095         * <p> A caller can be marked as being "privileged" 
096         * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). 
097         * When making access control decisions, the <code>checkPermission</code>
098         * method stops checking if it reaches a caller that 
099         * was marked as "privileged" via a <code>doPrivileged</code> 
100         * call without a context argument (see below for information about a
101         * context argument). If that caller's domain has the
102         * specified permission, no further checking is done and 
103         * <code>checkPermission</code>
104         * returns quietly, indicating that the requested access is allowed.
105         * If that domain does not have the specified permission, an exception
106         * is thrown, as usual.
107         * 
108         * <p> The normal use of the "privileged" feature is as follows. If you
109         * don't need to return a value from within the "privileged" block, do 
110         * the following:
111         *
112         *  <pre> {@code
113         * somemethod() {
114         *     ...normal code here...
115         *     AccessController.doPrivileged(new PrivilegedAction<Void>() {
116         *         public Void run() {
117         *             // privileged code goes here, for example:
118         *             System.loadLibrary("awt");
119         *             return null; // nothing to return
120         *         }
121         *     });
122         *     ...normal code here...
123         * }}</pre>
124         *
125         * <p>
126         * PrivilegedAction is an interface with a single method, named
127         * <code>run</code>.
128         * The above example shows creation of an implementation
129         * of that interface; a concrete implementation of the
130         * <code>run</code> method is supplied.
131         * When the call to <code>doPrivileged</code> is made, an 
132         * instance of the PrivilegedAction implementation is passed
133         * to it. The <code>doPrivileged</code> method calls the
134         * <code>run</code> method from the PrivilegedAction 
135         * implementation after enabling privileges, and returns the 
136         * <code>run</code> method's return value as the 
137         * <code>doPrivileged</code> return value (which is
138         * ignored in this example).
139         *
140         * <p> If you need to return a value, you can do something like the following:
141         *
142         *  <pre> {@code
143         * somemethod() {
144         *     ...normal code here...
145         *     String user = AccessController.doPrivileged(
146         *         new PrivilegedAction<String>() {
147         *         public String run() {
148         *             return System.getProperty("user.name");
149         *             }
150         *         });
151         *     ...normal code here...
152         * }}</pre>
153         *
154         * <p>If the action performed in your <code>run</code> method could
155         * throw a "checked" exception (those listed in the <code>throws</code> clause
156         * of a method), then you need to use the 
157         * <code>PrivilegedExceptionAction</code> interface instead of the
158         * <code>PrivilegedAction</code> interface:
159         * 
160         *  <pre> {@code
161         * somemethod() throws FileNotFoundException {
162         *     ...normal code here...
163         *     try {
164         *         FileInputStream fis = AccessController.doPrivileged(
165         *         new PrivilegedExceptionAction<FileInputStream>() {
166         *             public FileInputStream run() throws FileNotFoundException {
167         *                 return new FileInputStream("someFile");
168         *             }
169         *         });
170         *     } catch (PrivilegedActionException e) {
171         *         // e.getException() should be an instance of FileNotFoundException,
172         *         // as only "checked" exceptions will be "wrapped" in a
173         *         // PrivilegedActionException.
174         *         throw (FileNotFoundException) e.getException();
175         *     }
176         *     ...normal code here...
177         *  }}</pre>
178         * 
179         * <p> Be *very* careful in your use of the "privileged" construct, and 
180         * always remember to make the privileged code section as small as possible.
181         * 
182         * <p> Note that <code>checkPermission</code> always performs security checks
183         * within the context of the currently executing thread.
184         * Sometimes a security check that should be made within a given context
185         * will actually need to be done from within a
186         * <i>different</i> context (for example, from within a worker thread).
187         * The {@link #getContext() getContext} method and 
188         * AccessControlContext class are provided 
189         * for this situation. The <code>getContext</code> method takes a "snapshot"
190         * of the current calling context, and places
191         * it in an AccessControlContext object, which it returns. A sample call is
192         * the following:
193         * 
194         * <pre>
195         * 
196         * AccessControlContext acc = AccessController.getContext()
197         * 
198         * </pre>
199         * 
200         * <p>
201         * AccessControlContext itself has a <code>checkPermission</code> method
202         * that makes access decisions based on the context <i>it</i> encapsulates,
203         * rather than that of the current execution thread.
204         * Code within a different context can thus call that method on the
205         * previously-saved AccessControlContext object. A sample call is the
206         * following:
207         * 
208         * <pre>
209         * 
210         * acc.checkPermission(permission)
211         * 
212         * </pre> 
213         *
214         * <p> There are also times where you don't know a priori which permissions
215         * to check the context against. In these cases you can use the
216         * doPrivileged method that takes a context:
217         * 
218         *  <pre> {@code
219         * somemethod() {
220         *     AccessController.doPrivileged(new PrivilegedAction<Object>() {
221         *         public Object run() {
222         *             // Code goes here. Any permission checks within this
223         *             // run method will require that the intersection of the
224         *             // callers protection domain and the snapshot's
225         *             // context have the desired permission.
226         *         }
227         *     }, acc);
228         *     ...normal code here...
229         * }}</pre>
230         * 
231         * @see AccessControlContext
232         *
233         * @version 1.68 07/05/17
234         * @author Li Gong 
235         * @author Roland Schemers
236         */
237
238        public final class AccessController {
239
240            /** 
241             * Don't allow anyone to instantiate an AccessController
242             */
243            private AccessController() {
244            }
245
246            /**
247             * Performs the specified <code>PrivilegedAction</code> with privileges
248             * enabled. The action is performed with <i>all</i> of the permissions 
249             * possessed by the caller's protection domain.
250             * 
251             * <p> If the action's <code>run</code> method throws an (unchecked)
252             * exception, it will propagate through this method.
253             *
254             * <p> Note that any DomainCombiner associated with the current
255             * AccessControlContext will be ignored while the action is performed.
256             *
257             * @param action the action to be performed.
258             *
259             * @return the value returned by the action's <code>run</code> method.
260             *
261             * @exception NullPointerException if the action is <code>null</code>
262             *
263             * @see #doPrivileged(PrivilegedAction,AccessControlContext)
264             * @see #doPrivileged(PrivilegedExceptionAction)
265             * @see #doPrivilegedWithCombiner(PrivilegedAction)
266             * @see java.security.DomainCombiner
267             */
268
269            public static native <T> T doPrivileged(PrivilegedAction<T> action);
270
271            /**
272             * Performs the specified <code>PrivilegedAction</code> with privileges
273             * enabled. The action is performed with <i>all</i> of the permissions 
274             * possessed by the caller's protection domain.
275             *
276             * <p> If the action's <code>run</code> method throws an (unchecked)
277             * exception, it will propagate through this method.
278             *
279             * <p> This method preserves the current AccessControlContext's
280             * DomainCombiner (which may be null) while the action is performed.
281             *
282             * @param action the action to be performed.
283             *
284             * @return the value returned by the action's <code>run</code> method.
285             *
286             * @exception NullPointerException if the action is <code>null</code>
287             *
288             * @see #doPrivileged(PrivilegedAction)
289             * @see java.security.DomainCombiner
290             *
291             * @since 1.6
292             */
293            public static <T> T doPrivilegedWithCombiner(
294                    PrivilegedAction<T> action) {
295
296                DomainCombiner dc = null;
297                AccessControlContext acc = getStackAccessControlContext();
298                if (acc == null || (dc = acc.getAssignedCombiner()) == null) {
299                    return AccessController.doPrivileged(action);
300                }
301                return AccessController.doPrivileged(action,
302                        preserveCombiner(dc));
303            }
304
305            /**
306             * Performs the specified <code>PrivilegedAction</code> with privileges
307             * enabled and restricted by the specified
308             * <code>AccessControlContext</code>.
309             * The action is performed with the intersection of the permissions
310             * possessed by the caller's protection domain, and those possessed
311             * by the domains represented by the specified
312             * <code>AccessControlContext</code>.
313             * <p>
314             * If the action's <code>run</code> method throws an (unchecked) exception,
315             * it will propagate through this method.
316             *
317             * @param action the action to be performed.
318             * @param context an <i>access control context</i>
319             *                representing the restriction to be applied to the
320             *                caller's domain's privileges before performing
321             *                the specified action.  If the context is
322             *                <code>null</code>,
323             *                then no additional restriction is applied.
324             *
325             * @return the value returned by the action's <code>run</code> method.
326             *
327             * @exception NullPointerException if the action is <code>null</code>
328             * 
329             * @see #doPrivileged(PrivilegedAction)
330             * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
331             */
332            public static native <T> T doPrivileged(PrivilegedAction<T> action,
333                    AccessControlContext context);
334
335            /**
336             * Performs the specified <code>PrivilegedExceptionAction</code> with
337             * privileges enabled.  The action is performed with <i>all</i> of the 
338             * permissions possessed by the caller's protection domain.
339             *
340             * <p> If the action's <code>run</code> method throws an <i>unchecked</i>
341             * exception, it will propagate through this method.
342             *
343             * <p> Note that any DomainCombiner associated with the current
344             * AccessControlContext will be ignored while the action is performed.
345             *
346             * @param action the action to be performed
347             *
348             * @return the value returned by the action's <code>run</code> method
349             *
350             * @exception PrivilegedActionException if the specified action's
351             *         <code>run</code> method threw a <i>checked</i> exception
352             * @exception NullPointerException if the action is <code>null</code>
353             * 
354             * @see #doPrivileged(PrivilegedAction)
355             * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
356             * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
357             * @see java.security.DomainCombiner
358             */
359            public static native <T> T doPrivileged(
360                    PrivilegedExceptionAction<T> action)
361                    throws PrivilegedActionException;
362
363            /**
364             * Performs the specified <code>PrivilegedExceptionAction</code> with
365             * privileges enabled.  The action is performed with <i>all</i> of the 
366             * permissions possessed by the caller's protection domain.
367             *
368             * <p> If the action's <code>run</code> method throws an <i>unchecked</i>
369             * exception, it will propagate through this method.
370             *
371             * <p> This method preserves the current AccessControlContext's
372             * DomainCombiner (which may be null) while the action is performed.
373             *
374             * @param action the action to be performed.
375             *
376             * @return the value returned by the action's <code>run</code> method
377             *
378             * @exception PrivilegedActionException if the specified action's
379             *         <code>run</code> method threw a <i>checked</i> exception
380             * @exception NullPointerException if the action is <code>null</code>
381             * 
382             * @see #doPrivileged(PrivilegedAction)
383             * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
384             * @see java.security.DomainCombiner
385             *
386             * @since 1.6
387             */
388            public static <T> T doPrivilegedWithCombiner(
389                    PrivilegedExceptionAction<T> action)
390                    throws PrivilegedActionException {
391
392                DomainCombiner dc = null;
393                AccessControlContext acc = getStackAccessControlContext();
394                if (acc == null || (dc = acc.getAssignedCombiner()) == null) {
395                    return AccessController.doPrivileged(action);
396                }
397                return AccessController.doPrivileged(action,
398                        preserveCombiner(dc));
399            }
400
401            /**
402             * preserve the combiner across the doPrivileged call
403             */
404            private static AccessControlContext preserveCombiner(
405                    DomainCombiner combiner) {
406
407                /**
408                 * callerClass[0] = Reflection.getCallerClass
409                 * callerClass[1] = AccessController.preserveCombiner
410                 * callerClass[2] = AccessController.doPrivileged
411                 * callerClass[3] = caller
412                 */
413                final Class callerClass = sun.reflect.Reflection
414                        .getCallerClass(3);
415                ProtectionDomain callerPd = doPrivileged(new PrivilegedAction<ProtectionDomain>() {
416                    public ProtectionDomain run() {
417                        return callerClass.getProtectionDomain();
418                    }
419                });
420
421                // perform 'combine' on the caller of doPrivileged,
422                // even if the caller is from the bootclasspath
423                ProtectionDomain[] pds = new ProtectionDomain[] { callerPd };
424                return new AccessControlContext(combiner.combine(pds, null),
425                        combiner);
426            }
427
428            /**
429             * Performs the specified <code>PrivilegedExceptionAction</code> with 
430             * privileges enabled and restricted by the specified
431             * <code>AccessControlContext</code>.  The action is performed with the
432             * intersection of the the permissions possessed by the caller's
433             * protection domain, and those possessed by the domains represented by the
434             * specified <code>AccessControlContext</code>.
435             * <p>
436             * If the action's <code>run</code> method throws an <i>unchecked</i>
437             * exception, it will propagate through this method.
438             *
439             * @param action the action to be performed
440             * @param context an <i>access control context</i>
441             *                representing the restriction to be applied to the
442             *                caller's domain's privileges before performing
443             *                the specified action.  If the context is
444             *                <code>null</code>,
445             *                then no additional restriction is applied.
446             *
447             * @return the value returned by the action's <code>run</code> method
448             *
449             * @exception PrivilegedActionException if the specified action's
450             *         <code>run</code> method
451             *	       threw a <i>checked</i> exception
452             * @exception NullPointerException if the action is <code>null</code>
453             * 
454             * @see #doPrivileged(PrivilegedAction)
455             * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
456             */
457            public static native <T> T doPrivileged(
458                    PrivilegedExceptionAction<T> action,
459                    AccessControlContext context)
460                    throws PrivilegedActionException;
461
462            /**
463             * Returns the AccessControl context. i.e., it gets 
464             * the protection domains of all the callers on the stack,
465             * starting at the first class with a non-null 
466             * ProtectionDomain. 
467             *
468             * @return the access control context based on the current stack or
469             *         null if there was only privileged system code.
470             */
471
472            private static native AccessControlContext getStackAccessControlContext();
473
474            /**
475             * Returns the "inherited" AccessControl context. This is the context
476             * that existed when the thread was created. Package private so 
477             * AccessControlContext can use it.
478             */
479
480            static native AccessControlContext getInheritedAccessControlContext();
481
482            /** 
483             * This method takes a "snapshot" of the current calling context, which
484             * includes the current Thread's inherited AccessControlContext,
485             * and places it in an AccessControlContext object. This context may then
486             * be checked at a later point, possibly in another thread.
487             *
488             * @see AccessControlContext
489             *
490             * @return the AccessControlContext based on the current context.
491             */
492
493            public static AccessControlContext getContext() {
494                AccessControlContext acc = getStackAccessControlContext();
495                if (acc == null) {
496                    // all we had was privileged system code. We don't want
497                    // to return null though, so we construct a real ACC.
498                    return new AccessControlContext(null, true);
499                } else {
500                    return acc.optimize();
501                }
502            }
503
504            /** 
505             * Determines whether the access request indicated by the
506             * specified permission should be allowed or denied, based on
507             * the current AccessControlContext and security policy.
508             * This method quietly returns if the access request
509             * is permitted, or throws a suitable AccessControlException otherwise. 
510             *
511             * @param perm the requested permission.
512             * 
513             * @exception AccessControlException if the specified permission
514             *            is not permitted, based on the current security policy.
515             * @exception NullPointerException if the specified permission
516             *            is <code>null</code> and is checked based on the
517             *            security policy currently in effect.
518             */
519
520            public static void checkPermission(Permission perm)
521                    throws AccessControlException {
522                //System.err.println("checkPermission "+perm);
523                //Thread.currentThread().dumpStack();
524
525                if (perm == null) {
526                    throw new NullPointerException("permission can't be null");
527                }
528
529                AccessControlContext stack = getStackAccessControlContext();
530                // if context is null, we had privileged system code on the stack.
531                if (stack == null) {
532                    Debug debug = AccessControlContext.getDebug();
533                    boolean dumpDebug = false;
534                    if (debug != null) {
535                        dumpDebug = !Debug.isOn("codebase=");
536                        dumpDebug &= !Debug.isOn("permission=")
537                                || Debug.isOn("permission="
538                                        + perm.getClass().getCanonicalName());
539                    }
540
541                    if (dumpDebug && Debug.isOn("stack")) {
542                        Thread.currentThread().dumpStack();
543                    }
544
545                    if (dumpDebug && Debug.isOn("domain")) {
546                        debug.println("domain (context is null)");
547                    }
548
549                    if (dumpDebug) {
550                        debug.println("access allowed " + perm);
551                    }
552                    return;
553                }
554
555                AccessControlContext acc = stack.optimize();
556                acc.checkPermission(perm);
557            }
558        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.