KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > SecurityContext


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.security;
24
25 import java.lang.System JavaDoc;
26 import java.lang.SecurityManager JavaDoc;
27 import java.util.logging.Logger JavaDoc;
28 import java.util.logging.Level JavaDoc;
29
30 import java.util.Set JavaDoc;
31
32 import java.security.Principal JavaDoc;
33 import java.security.AccessController JavaDoc;
34 import java.security.AccessControlContext JavaDoc;
35 import java.security.PrivilegedExceptionAction JavaDoc;
36 import java.security.PrivilegedAction JavaDoc;
37 import java.security.ProtectionDomain JavaDoc;
38 import javax.security.auth.Subject JavaDoc;
39 import com.sun.enterprise.deployment.PrincipalImpl;
40 import com.sun.enterprise.config.serverbeans.*;
41 import com.sun.enterprise.config.*;
42 import com.sun.enterprise.server.ApplicationServer;
43 import com.sun.web.security.PrincipalGroupFactory;
44 import com.sun.logging.*;
45
46
47 /**
48 * This class that extends AbstractSecurityContext that gets
49  * stored in Thread Local Storage. If the current thread creates
50  * child threads, the SecurityContext stored in the current
51  * thread is automatically propogated to the child threads.
52  *
53  * This class is used on the server side to represent the
54  * security context.
55  *
56  * Thread Local Storage is a concept introduced in JDK1.2.
57  * @see java.lang.ThreadLocal
58  * @see java.lang.InheritableThreadLocal
59  *
60  * @author Harish Prabandham
61  * @author Harpreet Singh
62  */

63 public class SecurityContext extends AbstractSecurityContext {
64
65     private static Logger JavaDoc _logger=null;
66     static {
67         _logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
68     }
69
70     private static InheritableThreadLocal JavaDoc currentSecCtx =
71         new InheritableThreadLocal JavaDoc();
72     private static SecurityContext defaultSecurityContext =
73     generateDefaultSecurityContext();
74
75     private static javax.security.auth.AuthPermission JavaDoc doAsPrivilegedPerm =
76     new javax.security.auth.AuthPermission JavaDoc("doAsPrivileged");
77  
78     // Did the client log in as or did the server generate the context
79
private boolean SERVER_GENERATED_SECURITY_CONTEXT = false;
80
81
82     /* This creates a new SecurityContext object.
83      * Note: that the docs for Subject state that the internal sets
84      * (eg. the principal set) cannot be modified unless the caller
85      * has the modifyPrincipals AuthPermission. That said, there may
86      * be some value to setting the Subject read only.
87      * Note: changing the principals in the embedded subject (after
88      * construction will likely cause problem in the principal set
89      * keyed HashMaps of EJBSecurityManager.
90      * @param username The name of the user/caller principal.
91      * @param subject contains the authenticated principals and credential.
92      */

93     public SecurityContext(String JavaDoc userName, Subject JavaDoc subject) {
94     Subject JavaDoc s = subject;
95     if (s == null) {
96         s = new Subject JavaDoc();
97         _logger.warning("java_security.null_subject");
98     }
99     this.initiator = new PrincipalImpl(userName);
100         final Subject JavaDoc sub = s;
101         this.subject = (javax.security.auth.Subject JavaDoc)
102             AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
103                 public java.lang.Object JavaDoc run() {
104                     sub.getPrincipals().add(initiator);
105                     return sub;
106                 }
107             });
108     }
109
110   public SecurityContext(String JavaDoc userName, Subject JavaDoc subject, String JavaDoc realm) {
111     Subject JavaDoc s = subject;
112     if (s == null) {
113         s = new Subject JavaDoc();
114         _logger.warning("java_security.null_subject");
115     }
116     this.initiator = PrincipalGroupFactory.getPrincipalInstance(userName, realm);
117         final Subject JavaDoc sub = s;
118         this.subject = (javax.security.auth.Subject JavaDoc)
119             AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
120                 public java.lang.Object JavaDoc run() {
121                     sub.getPrincipals().add(initiator);
122                     return sub;
123                 }
124             });
125     }
126     
127     /* private constructor for constructing default security context
128      */

129     private SecurityContext() {
130     this.subject = new Subject JavaDoc();
131     // delay assignment of caller principal until it is requested
132
this.initiator = null;
133     this.setServerGeneratedCredentials();
134         // read only is only done for guest logins.
135
this.subject.setReadOnly();
136     }
137     
138     /**
139      * Initialize the SecurityContext and handle the unauthenticated
140      * principal case
141      */

142     public static SecurityContext init(){
143         SecurityContext sc = (SecurityContext) currentSecCtx.get();
144         if(sc == null) { // there is no current security context...
145
sc = defaultSecurityContext;
146     }
147         return sc;
148     }
149       
150     public static SecurityContext getDefaultSecurityContext(){
151         //unauthen. Security Context.
152
return defaultSecurityContext;
153     }
154
155     public static Subject JavaDoc getDefaultSubject(){
156         //Subject of unauthen. Security Context.
157
return defaultSecurityContext.subject;
158     }
159      
160     // ger caller principal of unauthenticated Security Context
161
public static Principal JavaDoc getDefaultCallerPrincipal(){
162         synchronized(SecurityContext.class) {
163         if (defaultSecurityContext.initiator == null) {
164         String JavaDoc guestUser = null;
165         try {
166             guestUser = (String JavaDoc)
167             AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc() {
168                 public java.lang.Object JavaDoc run() throws Exception JavaDoc {
169                     ConfigContext configContext =
170                     ApplicationServer.getServerContext().
171                     getConfigContext();
172                     assert(configContext != null);
173                     SecurityService securityBean =
174                     ServerBeansFactory.
175                     getSecurityServiceBean(configContext);
176                     assert(securityBean != null);
177                     return securityBean.getDefaultPrincipal();
178                 }
179                 });
180         } catch (Exception JavaDoc e) {
181             _logger.log(Level.SEVERE,
182                 "java_security.default_user_login_Exception", e);
183         } finally {
184             if (guestUser == null) {
185             guestUser = "ANONYMOUS";
186             }
187         }
188         defaultSecurityContext.initiator = new PrincipalImpl(guestUser);
189         }
190     }
191     return defaultSecurityContext.initiator;
192     }
193       
194     private static SecurityContext generateDefaultSecurityContext() {
195         synchronized (SecurityContext.class) {
196         try{
197         return (SecurityContext)
198             AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc() {
199                 public java.lang.Object JavaDoc run() throws Exception JavaDoc{
200                 return new SecurityContext();
201                 }
202             });
203         } catch(Exception JavaDoc e){
204         _logger.log(Level.SEVERE,
205                 "java_security.security_context_exception",e);
206         }
207     }
208         return null;
209     }
210     
211     /**
212      * No need to unmarshall the unauthenticated principal....
213      */

214     public static void reset(SecurityContext sc){
215     setCurrent(sc);
216     }
217
218
219     /**
220      * This method gets the SecurityContext stored in the
221      * Thread Local Store (TLS) of the current thread.
222      * @return The current Security Context stored in TLS. It returns
223      * null if SecurityContext could not be found in the current thread.
224      */

225     public static SecurityContext getCurrent() {
226     SecurityContext sc = (SecurityContext) currentSecCtx.get();
227     if (sc == null) {
228         sc = defaultSecurityContext;
229     }
230     return sc;
231     }
232
233     
234     /**
235      * This method sets the SecurityContext stored in the TLS.
236      * @param The Security Context that should be stored in TLS.
237      * This public static method needs to be protected
238      * such that it can only be called by container code. Otherwise
239      * it can be called by application code to set its subject (which the
240      * EJB security manager will use to create a domain combiner,
241      * and then everything the ejb does will be run as the
242      * corresponding subject.
243      */

244     public static void setCurrent(SecurityContext sc) {
245
246     if (sc != null && sc != defaultSecurityContext) {
247  
248         SecurityContext current = (SecurityContext)currentSecCtx.get();
249  
250         if (sc != current) {
251  
252         boolean permitted = false;
253  
254         try {
255             SecurityManager JavaDoc sm = System.getSecurityManager();
256             if (sm != null) {
257             if(_logger.isLoggable(Level.FINE)){
258                 _logger.fine("permission check done to set SecurityContext");
259             }
260             sm.checkPermission(doAsPrivilegedPerm);
261             }
262             permitted = true;
263         } catch (java.lang.SecurityException JavaDoc se) {
264             _logger.log(Level.SEVERE, "java_security.security_context_permission_exception", se);
265         } catch (Throwable JavaDoc t) {
266             _logger.log(Level.SEVERE, "java_security.security_context_unexpected_exception", t);
267         }
268         
269         if (permitted) {
270             currentSecCtx.set(sc);
271         } else {
272             _logger.severe("java_security.security_context_nochange");
273         }
274         }
275     } else {
276         currentSecCtx.set(sc);
277     }
278     }
279    
280     public static void setUnauthenticatedContext() {
281     currentSecCtx.set(defaultSecurityContext);
282     }
283
284     public boolean didServerGenerateCredentials (){
285     return SERVER_GENERATED_SECURITY_CONTEXT;
286     }
287     
288     private void setServerGeneratedCredentials(){
289     SERVER_GENERATED_SECURITY_CONTEXT = true;
290     }
291
292
293     /**
294      * This method returns the caller principal.
295      * This information may be redundant since the same information
296      * can be inferred by inspecting the Credentials of the caller.
297      * @return The caller Principal.
298      */

299     public Principal JavaDoc getCallerPrincipal() {
300     return this == defaultSecurityContext ? getDefaultCallerPrincipal() : initiator;
301     }
302
303     
304     public Subject JavaDoc getSubject() {
305     return subject;
306     }
307
308
309     public String JavaDoc toString() {
310     return "SecurityContext[ " + "Initiator: " +
311         initiator + "Subject " + subject + " ]";
312     }
313
314     public Set JavaDoc getPrincipalSet() {
315         return subject.getPrincipals();
316     }
317 }
318
319
320
321
322
323
324
325
Popular Tags