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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
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 Object disassociate() {
076            // this is only called before the thread is put back in the pool so it should be ok
077            ContextManager.popCallers(null);
078            return null;
079        }
080    
081        public boolean isCallerAuthorized(Method method, InterfaceType typee) {
082            ThreadContext threadContext = ThreadContext.getThreadContext();
083    
084            try {
085                CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
086    
087                // if security is not enabled we are autorized
088                EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
089                if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
090                    return true;
091                }
092    
093                String ejbName = deploymentInfo.getEjbName();
094    
095                InterfaceType type = deploymentInfo.getInterfaceType(method.getDeclaringClass());
096    
097                String name = (type == null) ? null : type.getSpecName();
098    
099                Permission permission = new EJBMethodPermission(ejbName, name, method);
100    
101                AccessControlContext accessContext = ContextManager.getCurrentContext();
102    
103                if (permission != null) accessContext.checkPermission(permission);
104    
105            } catch (AccessControlException e) {
106                return false;
107            }
108            return true;
109        }
110    
111        public boolean isCallerInRole(String role) {
112            if (role == null) throw new IllegalArgumentException("Role must not be null");
113    
114            ThreadContext threadContext = ThreadContext.getThreadContext();
115    
116            CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
117    
118            // if security is not enabled we are not in that role
119            EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
120            if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
121                return false;
122            }
123    
124            return ContextManager.isCallerInRole(deploymentInfo.getEjbName(), role);
125        }
126    
127        public Principal getCallerPrincipal() {
128            // if security is not enabled, we don't have a principal
129            ThreadContext threadContext = ThreadContext.getThreadContext();
130            CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
131            EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class);
132            if (ejbDeployment == null || !ejbDeployment.isSecurityEnabled()) {
133                return null;
134            }
135    
136            Subject callerSubject = ContextManager.getCurrentCaller();
137            return ContextManager.getCurrentPrincipal(callerSubject);
138        }
139    
140        //
141        // Unused
142        //
143    
144        public Object getSecurityIdentity() {
145            return null;
146        }
147    
148        public void setSecurityIdentity(Object securityIdentity) {
149            throw new UnsupportedOperationException();
150        }
151    
152        public <T> T translateTo(Object securityIdentity, Class<T> type) {
153            throw new UnsupportedOperationException();
154        }
155    
156        public Subject getCurrentSubject() {
157            throw new UnsupportedOperationException();
158        }
159    
160    }