View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.security;
18  
19  /***
20   * Wrapper for the javax.security.auth.Subject class.
21   * Due to a design oversight in JAAS 1.0, the javax.security.auth.Subject.getSubject method does not return the Subject 
22   * that is associated with the running thread !inside! a java.security.AccessController.doPrivileged code block.
23   * As a result, the current subject cannot be determined correctly.
24   * This class uses the ThreadLocal mechanism to carry the thread-specific instance of the subject 
25   * @author hajo
26   *
27   */
28  
29  import javax.security.auth.*;
30  import java.security.AccessControlContext;
31  import java.security.PrivilegedActionException;
32  
33  
34  
35  public class JSSubject implements java.io.Serializable 
36  {
37  
38      private static final long serialVersionUID = -8308522755600156057L;
39  
40      static ThreadLocal threadLocal = 
41          new ThreadLocal();
42      
43      
44      
45      
46  
47      /***
48       * Get the <code>Subject</code> associated with the provided
49       * <code>AccessControlContext</code> fromn the current Thread or from the standard SUBJECT mechansim 
50       * <p>
51       *
52       * @param  acc the <code>AccessControlContext</code> from which to retrieve
53       *		the <code>Subject</code>. Only used if current thread doesn't carry subject
54       *
55       * @return  the <code>Subject</code> associated with the provided
56       *		<code>AccessControlContext</code>, or <code>null</code>
57       *		if no <code>Subject</code> is associated
58       *		with the provided <code>AccessControlContext</code>.
59       *
60       * @exception SecurityException if the caller does not have permission
61       *		to get the <code>Subject</code>. <p>
62       *
63       * @exception NullPointerException if the provided
64       *		<code>AccessControlContext</code> is <code>null</code>.
65       */
66      public static Subject getSubject(final AccessControlContext acc) 
67      {
68      	Subject s = null;
69      		try
70      	{
71      		s=  (Subject)threadLocal.get();
72      	}
73      	catch (Exception e)
74      	{}
75      	if (s == null)
76      		return Subject.getSubject(acc);
77      	else
78      		return s;
79      }
80  
81      /***
82       * Perform work as a particular <code>Subject</code> after setting subject reference in current thread 
83       *
84       * @param subject the <code>Subject</code> that the specified
85       *			<code>action</code> will run as.  This parameter
86       *			may be <code>null</code>. <p>
87       *
88       * @param action the code to be run as the specified
89       *			<code>Subject</code>. <p>
90       *
91       * @return the <code>Object</code> returned by the PrivilegedAction's
92       *			<code>run</code> method.
93       *
94       * @exception NullPointerException if the <code>PrivilegedAction</code>
95       *			is <code>null</code>. <p>
96       *
97       * @exception SecurityException if the caller does not have permission
98       *			to invoke this method.
99       */
100     public static Object doAs(final Subject subject1,
101 			final java.security.PrivilegedAction action) 
102     {
103     	Subject subject = subject1;
104     	if (subject == null)
105     		subject = JSSubject.getSubject(null);
106     	threadLocal.set(subject);
107     	return Subject.doAs(subject,action);	
108     }
109 
110     /***
111      * Perform work as a particular <code>Subject</code> after setting subject reference in current thread.
112      *
113      *
114      * @param subject the <code>Subject</code> that the specified
115      *			<code>action</code> will run as.  This parameter
116      *			may be <code>null</code>. <p>
117      *
118      * @param action the code to be run as the specified
119      *			<code>Subject</code>. <p>
120      *
121      * @return the <code>Object</code> returned by the
122      *			PrivilegedExceptionAction's <code>run</code> method.
123      *
124      * @exception PrivilegedActionException if the
125      *			<code>PrivilegedExceptionAction.run</code>
126      *			method throws a checked exception. <p>
127      *
128      * @exception NullPointerException if the specified
129      *			<code>PrivilegedExceptionAction</code> is
130      *			<code>null</code>. <p>
131      *
132      * @exception SecurityException if the caller does not have permission
133      *			to invoke this method.
134      */
135     public static Object doAs(final Subject subject1,
136 			final java.security.PrivilegedExceptionAction action)
137 			throws java.security.PrivilegedActionException 
138 			{
139     	Subject subject = subject1;
140     	if (subject == null)
141     		subject = JSSubject.getSubject(null);
142     	threadLocal.set(subject);
143     	if (subject != null)
144     		return Subject.doAs(subject,action);
145     	else
146     		return Subject.doAs(subject,action);
147 			}
148     /***
149      * Perform privileged work as a particular <code>Subject</code> after setting subject reference in current thread.
150      *
151      *
152      * @param subject the <code>Subject</code> that the specified
153      *			<code>action</code> will run as.  This parameter
154      *			may be <code>null</code>. <p>
155      *
156      * @param action the code to be run as the specified
157      *			<code>Subject</code>. <p>
158      *
159      * @param acc the <code>AccessControlContext</code> to be tied to the
160      *			specified <i>subject</i> and <i>action</i>. <p>
161      *
162      * @return the <code>Object</code> returned by the PrivilegedAction's
163      *			<code>run</code> method.
164      *
165      * @exception NullPointerException if the <code>PrivilegedAction</code>
166      *			is <code>null</code>. <p>
167      *
168      * @exception SecurityException if the caller does not have permission
169      *			to invoke this method.
170      */
171     public static Object doAsPrivileged(final Subject subject1,
172 			final java.security.PrivilegedAction action,
173 			final java.security.AccessControlContext acc) {
174     	Subject subject = subject1;
175     	if (subject == null)
176     		subject = JSSubject.getSubject(acc);
177     	threadLocal.set(subject);
178     	if (subject != null)
179     		return Subject.doAsPrivileged(subject,action,acc);
180     	else
181     		return Subject.doAsPrivileged(subject,action,acc);
182     		
183 	}
184 
185 
186     /***
187      * Perform privileged work as a particular <code>Subject</code> after setting subject reference in current thread.
188      *
189      *
190      * @param subject the <code>Subject</code> that the specified
191      *			<code>action</code> will run as.  This parameter
192      *			may be <code>null</code>. <p>
193      *
194      * @param action the code to be run as the specified
195      *			<code>Subject</code>. <p>
196      *
197      * @param acc the <code>AccessControlContext</code> to be tied to the
198      *			specified <i>subject</i> and <i>action</i>. <p>
199      *
200      * @return the <code>Object</code> returned by the
201      *			PrivilegedExceptionAction's <code>run</code> method.
202      *
203      * @exception PrivilegedActionException if the
204      *			<code>PrivilegedExceptionAction.run</code>
205      *			method throws a checked exception. <p>
206      *
207      * @exception NullPointerException if the specified
208      *			<code>PrivilegedExceptionAction</code> is
209      *			<code>null</code>. <p>
210      *
211      * @exception SecurityException if the caller does not have permission
212      *			to invoke this method.
213      */
214     public static Object doAsPrivileged(final Subject subject,
215 			final java.security.PrivilegedExceptionAction action,
216 			final java.security.AccessControlContext acc)
217 			throws java.security.PrivilegedActionException {
218     	Subject s = subject;
219     	if (s == null)
220     		s = JSSubject.getSubject(acc);
221     	threadLocal.set(s);
222     	if (s != null)
223     		return Subject.doAsPrivileged(s,action,acc);
224     	else
225     		return Subject.doAsPrivileged(s,action,acc);
226 
227 	}
228 
229 
230 }