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 }