001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.tomcat.listener;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    import javax.security.auth.Subject;
023    
024    import org.apache.catalina.Container;
025    import org.apache.catalina.InstanceEvent;
026    import org.apache.catalina.InstanceListener;
027    import org.apache.catalina.Wrapper;
028    import org.apache.geronimo.security.Callers;
029    import org.apache.geronimo.security.ContextManager;
030    import org.apache.geronimo.tomcat.GeronimoStandardContext;
031    
032    public class RunAsInstanceListener implements InstanceListener {
033    
034        private static final ThreadLocal<List<Callers>> threadLocal = new ThreadLocal<List<Callers>>() {
035            protected List<Callers> initialValue() {
036                return new ArrayList<Callers>(2);
037            }
038        };
039        
040        public void instanceEvent(InstanceEvent event) {
041            
042            if (event.getType().equals(InstanceEvent.BEFORE_SERVICE_EVENT)) {
043                Container parent = event.getWrapper().getParent();
044                if (parent instanceof GeronimoStandardContext) {
045                    GeronimoStandardContext context = (GeronimoStandardContext)parent;
046                    Wrapper wrapper = event.getWrapper();
047                    String runAsRole = wrapper.getRunAs();
048                    Subject runAsSubject = context.getSubjectForRole(runAsRole);
049                    List<Callers> callersStack = threadLocal.get();
050                    if (runAsSubject != null) {
051                        Callers oldCallers = ContextManager.pushNextCaller(runAsSubject);
052                        callersStack.add(oldCallers);
053                    } else {
054                        callersStack.add(null);
055                    }
056                }
057            }
058    
059            else if (event.getType().equals(InstanceEvent.AFTER_SERVICE_EVENT)) {
060                List<Callers> callersStack = threadLocal.get();
061                Callers oldCallers = callersStack.remove(callersStack.size() - 1);
062                if (oldCallers!=null) {
063                    ContextManager.popCallers(oldCallers);
064                }
065            }
066        }
067    }