View Javadoc

1   /*
2   jGuard is a security framework based on top of jaas (java authentication and authorization security).
3   it is written for web applications, to resolve simply, access control problems.
4   version $Name$
5   http://sourceforge.net/projects/jguard/
6   
7   Copyright (C) 2004  Charles GAY
8   
9   This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13  
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  Lesser General Public License for more details.
18  
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  
23  
24  jGuard project home page:
25  http://sourceforge.net/projects/jguard/
26  
27  */
28  package net.sf.jguard.ext.util;
29  
30  import java.security.AccessControlContext;
31  import java.security.AccessController;
32  import java.security.Principal;
33  import java.util.Collection;
34  import java.util.HashSet;
35  import java.util.Iterator;
36  import java.util.Set;
37  
38  import javax.security.auth.Subject;
39  
40  import net.sf.jguard.core.authentication.AuthenticationException;
41  import net.sf.jguard.core.authentication.credentials.JGuardCredential;
42  import net.sf.jguard.core.authentication.manager.AuthenticationManager;
43  import net.sf.jguard.core.authorization.permissions.PermissionUtils;
44  import net.sf.jguard.core.organization.Organization;
45  import net.sf.jguard.core.principals.RolePrincipal;
46  import net.sf.jguard.core.principals.UserPrincipal;
47  import org.slf4j.Logger;
48  import org.slf4j.LoggerFactory;
49  
50  /**
51   * utility class to query against subject credentials.
52   * @author <a href="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
53   * @author <a href="mailto:tandilero@users.sourceforge.net">Maximiliano Batelli</a>
54   */
55  public class SubjectUtils {
56  
57  	private static final Logger logger = LoggerFactory.getLogger(SubjectUtils.class.getName());
58  
59  	/**
60  	 * return credential values from private and public credential set
61  	 * which are mapped to the specified credentialId.
62  	 * @param subject
63  	 * @param credentialId
64  	 * @return Collection of Object credential values
65  	 */
66  	public static Collection getCredentialValues(Subject subject,String credentialId){
67  		Collection valuesFound = new HashSet();
68  		valuesFound.addAll(getCredentialValues(subject,true,credentialId));
69  		valuesFound.addAll(getCredentialValues(subject,false,credentialId));
70  		return valuesFound;
71  	}
72  
73  	/**
74  	 * return credential values from the specified credential set
75  	 * which are mapped to the specified credentialId.
76  	 * @param subject
77  	 * @param publicVisibility <i>true</i> for publicCredentials, <i>false</i> for
78  	 * private credentials.
79  	 * @param credentialId
80  	 * @return Collection of Object credential values
81  	 */
82  	public static Collection getCredentialValues(Subject subject,boolean publicVisibility ,String credentialId){
83  		Collection valuesFound = new HashSet();
84  		Collection credentials = null;
85  		if(publicVisibility==true){
86  			credentials = subject.getPublicCredentials(JGuardCredential.class);
87  		}else{
88  			try{
89  			credentials = subject.getPrivateCredentials(JGuardCredential.class);
90  			}catch(SecurityException sex){
91  				logger.debug(" you don't have the permission to grab private credentials ");
92  				return valuesFound;
93  			}
94  		}
95  		Iterator it = credentials.iterator();
96  		while(it.hasNext()){
97  			Object credential = (JGuardCredential)it.next();
98  			//we skip non JGuardCredentials
99  			if(credential instanceof JGuardCredential == false){
100 				continue;
101 			}
102 			JGuardCredential cred = (JGuardCredential)credential;
103 			if(cred.getName().equals(credentialId)){
104 				valuesFound.add(cred.getValue());
105 			}
106 		}
107 
108 		return valuesFound;
109 	}
110 
111         public static Organization getOrganization(Subject subject){
112 		 Set organizationSet = subject.getPrincipals(Organization.class);
113                  if(organizationSet.size()>1){
114                      throw new IllegalStateException(" a Subject object must contains only one organization in the principal set . ");
115                  }else if(organizationSet.size()==0){
116                      throw new IllegalStateException(" if no organization is set in the principal set of the subject, the default 'system' organization is used  ");
117                  }
118                  return (Organization) organizationSet.iterator().next();
119 	}
120         
121 	/**
122 	 * return credential value from the specified credential set
123 	 * This function assume that credential have only one value
124 	 * return empty string if it is not found
125 	 * @param subject
126 	 * @param publicVisibility <i>true</i> for publicCredentials, <i>false</i> for
127 	 * private credentials.
128 	 * @param credentialId
129 	 * @return credential value as string
130 	 */
131 	public static String getCredentialValueAsString(Subject subject, boolean publicVisibility, String credentialId){
132 		String valueFound = "";
133 		Collection credentials = null;
134 		if(publicVisibility==true){
135 			credentials = subject.getPublicCredentials(JGuardCredential.class);
136 		}else{
137 			try{
138 				credentials = subject.getPrivateCredentials(JGuardCredential.class);
139 			}catch(SecurityException sex){
140 				logger.debug(" you don't have the permission to grab private credentials ");
141 				return valueFound;
142 			}
143 		}
144 		Iterator it = credentials.iterator();
145 		while(it.hasNext()){
146 			JGuardCredential cred = (JGuardCredential)it.next();
147 			if(cred.getName().equals(credentialId)){
148 				valueFound = cred.getValue().toString();
149 			}
150 		}
151 
152 		return valueFound;
153 	}
154 
155 	/**
156 	 * Set credential's value, this method assume that credential have only one value
157 	 * If credentialId exists then the value is replaced, else the credential is created
158 	 * @param subject
159 	 * @param publicVisibility <i>true</i> for publicCredentials, <i>false</i> for
160 	 * private credentials.
161 	 * @param credentialId
162 	 * @param credentialValue
163 	 * @param isIdentity <i>true</i> for identity credential, <i>false</i> otherwise
164 	 */
165 	public static void setCredentialValue(Subject subject, boolean publicVisibility, String credentialId, Object credentialValue, boolean isIdentity) {
166 		Set credentials = null;
167 		boolean credFound = false;
168 		if(publicVisibility){
169 			credentials = subject.getPublicCredentials();
170 		}else{
171 			try{
172 				credentials = subject.getPrivateCredentials();
173 			}catch(SecurityException sex){
174 				logger.debug(" you don't have the permission to grab private credentials ");
175 				return;
176 			}
177 		}
178 		Iterator it = credentials.iterator();
179 		JGuardCredential jCred = null;
180 		while(it.hasNext()){
181 			Object credential = it.next();
182 			if(!(credential instanceof JGuardCredential)){
183 				continue;
184 			}else{
185 				jCred = (JGuardCredential)credential;
186 			}
187 
188 			if(jCred.getName().equals(credentialId)){
189 				jCred.setValue(credentialValue);
190 				credFound = true;
191 				break;
192 			}
193 		}
194 		if(!credFound) {
195 			jCred = new JGuardCredential();
196 			jCred.setName(credentialId);
197 			jCred.setValue(credentialValue);
198 			credentials.add(jCred);
199 		}
200 	}
201 
202 	/**
203 	 * adds new credential value if it does not already exist. Added credential can not be an identity credential.
204 	 * @param subject
205 	 * @param publicVisibility
206 	 * @param credentialId
207 	 * @param credentialValue
208 	 */
209 	public static void addCredentialValue(Subject subject, boolean publicVisibility, String credentialId, Object credentialValue) {
210                 Set credentials = getCredentials(subject,publicVisibility);
211 		JGuardCredential jCred = getCredential(credentials,credentialId,credentialValue);
212 		
213                 //credential is not found
214 		if(jCred==null){
215 			jCred = new JGuardCredential();
216 			jCred.setName(credentialId);
217 			jCred.setValue(credentialValue);
218 			credentials.add(jCred);
219 		}
220 	}
221         
222         private static Set getCredentials(Subject subject,boolean publicVisibility){
223             Set credentials = null;
224                 if(publicVisibility){
225 			credentials = subject.getPublicCredentials();
226 		}else{
227 			try{
228 				credentials = subject.getPrivateCredentials();
229 			}catch(SecurityException sex){
230 				logger.debug(" you don't have the permission to grab private credentials ");
231 				throw sex;
232 			}
233 		}
234             return credentials;
235         }
236         
237         /**
238          *
239          *@return null if the credential is not found, JGuardCredential otherwise.
240          */
241         private static JGuardCredential getCredential(Set credentials, String credentialId, Object credentialValue){
242                 boolean credentialExists = false;
243 		Iterator it = credentials.iterator();
244 		JGuardCredential jCred = null;
245 		while(it.hasNext()){
246 			Object credential = it.next();
247 			if(!(credential instanceof JGuardCredential)){
248 				continue;
249 			}else{
250 				jCred = (JGuardCredential)credential;
251 			}
252 
253 			if(jCred.getName().equals(credentialId) && jCred.getValue().equals(credentialValue)){
254 				credentialExists = true;
255 				break;
256 			}
257 		}
258                 if(credentialExists){
259                     return jCred;
260                 }else{
261                     return null;
262                 }
263         }
264                 
265 
266 	/**
267 	 * return the {link {@link JGuardCredential} identifying uniquely the user.
268 	 * @param subject
269 	 * @param template
270 	 * @return
271 	 * @throws AuthenticationException
272 	 */
273 	public static JGuardCredential getIdentityCredential(Subject subject ,AuthenticationManager authenticationManager) {
274 		String userCredentialId = authenticationManager.getCredentialId();
275 		if(subject == null){
276 			throw new IllegalArgumentException("'subject' parameter is null");
277 		}
278 		
279 		JGuardCredential  idCredential = new JGuardCredential();
280 		idCredential.setName(userCredentialId);
281 		Collection values = getCredentialValues(subject,idCredential.getName());
282 		Iterator it = values.iterator();
283 		if(it.hasNext()){
284 			idCredential.setValue(it.next());
285 		}
286 		return idCredential;
287 	}
288 
289 	/**
290 	 * remove credential value if it already exists. Removed credential can not be an identity credential.
291 	 * @param subject
292 	 * @param publicVisibility
293 	 * @param credentialId
294 	 * @param credentialValue
295 	 */
296 	public static void removeCredentialValue(Subject subject, boolean publicVisibility, String credentialId, Object credentialValue) {
297 		Set credentials = getCredentials(subject,publicVisibility);
298 		JGuardCredential jCred = getCredential(credentials,credentialId,credentialValue);
299                 if(jCred!= null){
300 			credentials.remove(jCred);
301                 }
302 	}
303 	
304 	public static Set getEnabledPrincipals(Set userPrincipals) {
305 		Set enabledPrincipals = new HashSet();
306     	// Find the UserPrincipal to evaluate principal definition
307     	UserPrincipal userPrincipal = null;
308 		Iterator userPrincipalsIt = userPrincipals.iterator();
309 		while(userPrincipalsIt.hasNext()){
310     		Principal ppal = (Principal)userPrincipalsIt.next();
311     		if(ppal instanceof UserPrincipal) {
312     			userPrincipal = (UserPrincipal)ppal;
313     			break;
314     		}
315 		}
316 		userPrincipalsIt = userPrincipals.iterator();
317     	//add all enabled Principals to set
318     	while(userPrincipalsIt.hasNext()) {
319     		Principal ppal = (Principal)userPrincipalsIt.next();
320     		if(ppal instanceof RolePrincipal) {
321     			RolePrincipal tempUserPrincipal = (RolePrincipal) ppal;
322     			if(!"userPrincipal".equals(tempUserPrincipal.getLocalName())&& PermissionUtils.evaluatePrincipal(tempUserPrincipal, userPrincipal)) {
323                             enabledPrincipals.add(tempUserPrincipal);
324                         }
325     		}
326     	}	
327     	
328     	return enabledPrincipals;
329 	}
330         
331         /**
332          * grab the authenticated PersistedSubject in the execution stack.
333          * @return authenticated PersistedSubject or null if user is not authenticated
334          * @throws SecurityExceptionthe caller does not have the permission to call the subject
335          */
336         public static Subject getSubject(){
337                 AccessControlContext acc = AccessController.getContext();
338                 if(acc==null){
339                     //acc== null signifies System code,
340                     //so, no SUbject is bound to it
341                     return null;
342                 }
343 		Subject subject = Subject.getSubject(acc);
344                 return subject;
345         }
346         
347        
348         
349         public static Set getJavaxSecuritySubjects(Set jguardSubjects){
350             Set set = new HashSet();
351             Iterator it = jguardSubjects.iterator();
352             while(it.hasNext()){
353                 net.sf.jguard.ext.authentication.PersistedSubject subject = (net.sf.jguard.ext.authentication.PersistedSubject)it.next();
354                 Subject s = subject.toJavaxSecuritySubject();
355                 set.add(s);
356             }
357             return set;
358         }
359 
360 }