1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.security.plugins;
23
24 import java.lang.reflect.UndeclaredThrowableException;
25 import java.security.Principal;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.security.auth.Subject;
30 import javax.security.auth.callback.CallbackHandler;
31
32 import org.jboss.security.AuthenticationManager;
33 import org.jboss.security.RealmMapping;
34 import org.jboss.security.SubjectSecurityManager;
35 import org.jboss.security.auth.callback.SecurityAssociationHandler;
36 import org.jboss.security.plugins.auth.JaasSecurityManagerBase;
37 import org.jboss.system.ServiceMBeanSupport;
38 import org.jboss.util.CachePolicy;
39
40 /** The JaasSecurityManager is responsible both for authenticating credentials
41 associated with principals and for role mapping. This implementation relies
42 on the JAAS LoginContext/LoginModules associated with the security
43 domain name associated with the class for authentication,
44 and the context JAAS Subject object for role mapping.
45
46 @see #isValid(Principal, Object, Subject)
47 @see #getPrincipal(Principal)
48 @see #doesUserHaveRole(Principal, Set)
49
50 @author <a href="on@ibis.odessa.ua">Oleg Nitz</a>
51 @author Scott.Stark@jboss.org
52 @author Anil.Saldhana@jboss.org
53 @version $Revision: 62860 $
54 */
55 public class JaasSecurityManager extends ServiceMBeanSupport
56 implements SubjectSecurityManager, RealmMapping
57 {
58 private JaasSecurityManagerBase delegate = null;
59
60 /** Creates a default JaasSecurityManager for with a securityDomain
61 name of 'other'.
62 */
63 public JaasSecurityManager()
64 {
65 this("other", new SecurityAssociationHandler());
66 }
67 /** Creates a JaasSecurityManager for with a securityDomain
68 name of that given by the 'securityDomain' argument.
69 @param securityDomain the name of the security domain
70 @param handler the JAAS callback handler instance to use
71 @exception UndeclaredThrowableException thrown if handler does not
72 implement a setSecurityInfo(Princpal, Object) method
73 */
74 public JaasSecurityManager(String securityDomain, CallbackHandler handler)
75 {
76 delegate = new JaasSecurityManagerBase(securityDomain,handler);
77 }
78
79 /** The domainCache is typically a shared object that is populated
80 by the login code(LoginModule, etc.) and read by this class in the
81 isValid() method.
82 @see #isValid(Principal, Object, Subject)
83 */
84 public void setCachePolicy(CachePolicy domainCache)
85 {
86 delegate.setCachePolicy(domainCache);
87 }
88
89 /**
90 * Flag to specify if deep copy of subject sets needs to be
91 * enabled
92 *
93 * @param flag
94 */
95 public void setDeepCopySubjectOption(Boolean flag)
96 {
97 delegate.setDeepCopySubjectOption(flag);
98 }
99
100 /** Not really used anymore as the security manager service manages the
101 security domain authentication caches.
102 */
103 public void flushCache()
104 {
105 delegate.flushCache();
106 }
107
108 /** Get the name of the security domain associated with this security mgr.
109 @return Name of the security manager security domain.
110 */
111 public String getSecurityDomain()
112 {
113 return delegate.getSecurityDomain();
114 }
115
116 /** Get the currently authenticated Subject. This is a thread local
117 property shared across all JaasSecurityManager instances.
118 @return The Subject authenticated in the current thread if one
119 exists, null otherwise.
120 */
121 public Subject getActiveSubject()
122 {
123 return delegate.getActiveSubject();
124 }
125
126 /** Validate that the given credential is correct for principal. This
127 returns the value from invoking isValid(principal, credential, null).
128 @param principal - the security domain principal attempting access
129 @param credential - the proof of identity offered by the principal
130 @return true if the principal was authenticated, false otherwise.
131 */
132 public boolean isValid(Principal principal, Object credential)
133 {
134 return delegate.isValid(principal, credential, null);
135 }
136
137 /** Validate that the given credential is correct for principal. This first
138 will check the current CachePolicy object if one exists to see if the
139 user's cached credentials match the given credential. If there is no
140 credential cache or the cache information is invalid or does not match,
141 the user is authenticated against the JAAS login modules configured for
142 the security domain.
143 @param principal - the security domain principal attempting access
144 @param credential the proof of identity offered by the principal
145 @param activeSubject - if not null, a Subject that will be populated with
146 the state of the authenticated Subject.
147 @return true if the principal was authenticated, false otherwise.
148 */
149 public boolean isValid(Principal principal, Object credential,
150 Subject activeSubject)
151 {
152 return delegate.isValid(principal, credential, activeSubject);
153 }
154
155 /** Map the argument principal from the deployment environment principal
156 to the developer environment. This is called by the EJB context
157 getCallerPrincipal() to return the Principal as described by
158 the EJB developer domain.
159 @return a Principal object that is valid in the deployment environment
160 if one exists. If no Subject exists or the Subject has no principals
161 then the argument principal is returned.
162 */
163 public Principal getPrincipal(Principal principal)
164 {
165 return delegate.getPrincipal(principal);
166 }
167
168 /** Does the current Subject have a role(a Principal) that equates to one
169 of the role names. This method obtains the Group named 'Roles' from
170 the principal set of the currently authenticated Subject as determined
171 by the SecurityAssociation.getSubject() method and then creates a
172 SimplePrincipal for each name in roleNames. If the role is a member of the
173 Roles group, then the user has the role. This requires that the caller
174 establish the correct SecurityAssociation subject prior to calling this
175 method. In the past this was done as a side-effect of an isValid() call,
176 but this is no longer the case.
177
178 @param principal - ignored. The current authenticated Subject determines
179 the active user and assigned user roles.
180 @param rolePrincipals - a Set of Principals for the roles to check.
181
182 @see java.security.acl.Group;
183 @see Subject#getPrincipals()
184 */
185 public boolean doesUserHaveRole(Principal principal, Set<Principal> rolePrincipals)
186 {
187 return delegate.doesUserHaveRole(principal, rolePrincipals);
188 }
189
190 /** Return the set of domain roles the current active Subject 'Roles' group
191 found in the subject Principals set.
192
193 @param principal - ignored. The current authenticated Subject determines
194 the active user and assigned user roles.
195 @return The Set<Principal> for the application domain roles that the
196 principal has been assigned.
197 */
198 public Set<Principal> getUserRoles(Principal principal)
199 {
200 return delegate.getUserRoles(principal);
201 }
202
203 /**
204 * @see AuthenticationManager#getTargetPrincipal(Principal,Map)
205 */
206 public Principal getTargetPrincipal(Principal anotherDomainPrincipal, Map<String,Object> contextMap)
207 {
208 return delegate.getTargetPrincipal(anotherDomainPrincipal, contextMap);
209 }
210 }