001    /**
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.openejb;
019    
020    import java.lang.reflect.Method;
021    import java.security.AccessControlContext;
022    import java.security.AccessControlException;
023    import java.security.Permission;
024    import java.security.Principal;
025    import java.util.Properties;
026    
027    import javax.security.auth.Subject;
028    import javax.security.auth.login.LoginContext;
029    import javax.security.auth.login.LoginException;
030    import javax.security.jacc.EJBMethodPermission;
031    
032    import org.apache.geronimo.security.ContextManager;
033    import org.apache.geronimo.security.SubjectId;
034    import org.apache.openejb.InterfaceType;
035    import org.apache.openejb.core.CoreDeploymentInfo;
036    import org.apache.openejb.core.ThreadContext;
037    import org.apache.openejb.core.security.jaas.UsernamePasswordCallbackHandler;
038    import org.apache.openejb.spi.SecurityService;
039    
040    /**
041     * @version $Rev$ $Date$
042     */
043    public class GeronimoSecurityService implements SecurityService {
044        public void init(Properties props) throws Exception {
045        }
046    
047        public Object login(String user, String pass) throws LoginException {
048            return login("OpenEJB", user, pass);
049        }
050    
051        public Object login(String securityRealm, String user, String pass) throws LoginException {
052            LoginContext context = ContextManager.login(securityRealm, new UsernamePasswordCallbackHandler(user, pass));
053    
054            Subject subject = context.getSubject();
055            return ContextManager.getSubjectId(subject);
056        }
057    
058    //    public void logout(Object securityIdentity) {
059    //        Subject subject = ContextManager.getRegisteredSubject((SubjectId) securityIdentity);
060    //        ContextManager.unregisterSubject(subject);
061    //    }
062    
063        public void associate(Object securityIdentity) throws LoginException {
064            if (securityIdentity == null) {
065                return;
066            }
067    
068            Subject subject = ContextManager.getRegisteredSubject((SubjectId) securityIdentity);
069            if (subject == null) {
070                return;
071            }
072            ContextManager.setCallers(subject, subject);
073        }
074    
075        public void unassociate(Object securityIdentity) {
076            // this is only called before the thread is put back in the pool so it should be ok
077            ContextManager.popCallers(null);
078        }
079    
080        public boolean isCallerAuthorized(Method method, InterfaceType typee) {
081            ThreadContext threadContext = ThreadContext.getThreadContext();
082    
083            try {
084                CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
085    
086                // if security is not enabled we are autorized
087                EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
088                if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
089                    return true;
090                }
091    
092                String ejbName = deploymentInfo.getEjbName();
093    
094                InterfaceType type = deploymentInfo.getInterfaceType(method.getDeclaringClass());
095    
096                String name = (type == null) ? null : type.getSpecName();
097    
098                Permission permission = new EJBMethodPermission(ejbName, name, method);
099    
100                AccessControlContext accessContext = ContextManager.getCurrentContext();
101    
102                if (permission != null) accessContext.checkPermission(permission);
103    
104            } catch (AccessControlException e) {
105                return false;
106            }
107            return true;
108        }
109    
110        public boolean isCallerInRole(String role) {
111            if (role == null) throw new IllegalArgumentException("Role must not be null");
112    
113            ThreadContext threadContext = ThreadContext.getThreadContext();
114    
115            CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
116    
117            // if security is not enabled we are not in that role
118            EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
119            if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
120                return false;
121            }
122    
123            return ContextManager.isCallerInRole(deploymentInfo.getEjbName(), role);
124        }
125    
126        public Principal getCallerPrincipal() {
127            // if security is not enabled, we don't have a principal
128            ThreadContext threadContext = ThreadContext.getThreadContext();
129            CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
130            EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
131            if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
132                return null;
133            }
134    
135            Subject callerSubject = ContextManager.getCurrentCaller();
136            return ContextManager.getCurrentPrincipal(callerSubject);
137        }
138    
139        //
140        // Unused
141        //
142    
143        public Object getSecurityIdentity() {
144            return null;
145        }
146    
147        public void setSecurityIdentity(Object securityIdentity) {
148            throw new UnsupportedOperationException();
149        }
150    
151        public <T> T translateTo(Object securityIdentity, Class<T> type) {
152            throw new UnsupportedOperationException();
153        }
154    
155        public Subject getCurrentSubject() {
156            throw new UnsupportedOperationException();
157        }
158    
159    }