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  
29  package net.sf.jguard.jee.provisioning;
30  
31  import java.io.IOException;
32  import java.security.NoSuchAlgorithmException;
33  import java.security.Permission;
34  import java.security.Permissions;
35  import java.util.HashMap;
36  import java.util.HashSet;
37  import java.util.Iterator;
38  import java.util.Map;
39  import java.util.Set;
40  
41  import javax.servlet.ServletException;
42  import javax.servlet.http.HttpServletRequest;
43  import javax.servlet.http.HttpServletResponse;
44  
45  import net.sf.jguard.core.CoreConstants;
46  import net.sf.jguard.core.authentication.AccessContext;
47  import net.sf.jguard.core.authentication.AuthenticationException;
48  import net.sf.jguard.core.authentication.credentials.JGuardCredential;
49  import net.sf.jguard.core.authentication.manager.AuthenticationManager;
50  import net.sf.jguard.core.authentication.manager.AuthenticationManagerFactory;
51  import net.sf.jguard.core.authorization.permissions.URLPermission;
52  import net.sf.jguard.core.provisioning.ProvisioningServicePoint;
53  import net.sf.jguard.core.provisioning.SubjectTemplate;
54  import net.sf.jguard.core.util.CryptUtils;
55  import net.sf.jguard.core.util.XMLUtils;
56  import net.sf.jguard.jee.authentication.callbacks.HttpServletCallbackHandler;
57  import net.sf.jguard.jee.authentication.http.AccessFilter;
58  import net.sf.jguard.jee.authentication.http.AnonymizerRequestWrapper;
59  import net.sf.jguard.jee.authentication.http.HttpConstants;
60  
61  import org.dom4j.Document;
62  import org.dom4j.Element;
63  import org.slf4j.Logger;
64  import org.slf4j.LoggerFactory;
65  
66  /**
67   *
68   * @author <a href="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
69   */
70  public class HttpServletProvisioningServicePoint implements ProvisioningServicePoint{
71      
72      private static final Logger logger = LoggerFactory.getLogger(HttpServletProvisioningServicePoint.class.getName());
73      private String registerURI;
74      private URLPermission registerProcessPermission;
75      private URLPermission registerPermission;
76      
77      
78      /**
79       * Creates a new instance of HttpServletProvisioningServicePoint
80       */
81      public HttpServletProvisioningServicePoint() {
82      }
83  
84      
85  	public void init(String location) {
86  		Map settings = loadFilterConfiguration(location);
87          setSettings(settings);
88  		
89  	}
90      
91      public Permission getRegisterPermission() {
92            return registerPermission;
93      }
94  
95      public Permission getRegisterProcessPermission() {
96          return registerProcessPermission;
97      }
98  
99      public boolean registerProcess(AccessContext context) {
100         boolean registerSucceed = registerCoreProcess(context);
101 	HttpServletRequest request = (HttpServletRequest)context.getAttribute(AccessFilter.SERVLET_REQUEST);
102 	HttpServletResponse response = (HttpServletResponse)context.getAttribute(AccessFilter.SERVLET_RESPONSE);
103 	boolean result = false;	
104         if(!registerSucceed){
105          	logger.debug(" registration failed " ," registerProcess phase ");
106                 
107          	if(!response.isCommitted()){
108          		try {
109 					response.sendRedirect(response.encodeRedirectURL(request.getContextPath()+registerURI));
110 				} catch (IOException e) {
111 					logger.warn(" we cannot redirect to "+request.getContextPath()+registerURI+" because "+e.getMessage());
112 				}
113          	}else{
114          		logger.warn(" we cannot redirect to "+request.getContextPath()+registerURI+" because response is already commited ");
115          	}
116                 result = false;
117          }else if(registerSucceed){
118             	logger.debug(" registration succeed " ," registerProcess phase ");
119             	//the user is registered and we submit directly its credentials to the authentication phase
120             	request.getSession(true).removeAttribute(CoreConstants.AUTHN_UTILS);
121             	request.getSession(true).removeAttribute(CoreConstants.LAST_ACCESS_DENIED_PERMISSION);
122                 result = true;
123             	
124          } 
125         return result;
126     }
127     
128     /**
129 	 * register the user against the @link SubjectTemplate.
130 	 * @param context 
131 	 * @return true if registration succeed, false otherwise
132 	 */
133 	public boolean registerCoreProcess(AccessContext context) {
134 		HttpServletRequest request = (HttpServletRequest)context.getAttribute(AccessFilter.SERVLET_REQUEST);
135 		boolean success = false;
136 		AuthenticationManager auth = AuthenticationManagerFactory.getAuthenticationManager();
137 		SubjectTemplate st = null;
138 		try {
139 			st = buildSubjectTemplate(request);
140 		} catch (AuthenticationException e1) {
141 			logger.error(" subject template cannot be built ",e1);
142                         success = false;
143 			return false;
144 		}
145                 String passwordField = null;//HttpServletCallbackHandler.getPasswordField();
146                 Set credentials = st.getRequiredCredentials();
147                 Iterator itCreds = credentials.iterator();
148                 boolean found = false;
149                 JGuardCredential passwordCredential = null;
150                 while(itCreds.hasNext() && found==false){
151                     JGuardCredential cred = (JGuardCredential) itCreds.next();
152                     if(cred.getName().equals(passwordField)){
153                         passwordCredential = cred;
154                         found = true;
155                     }
156                     
157                 }
158                 
159                 if(!found){
160                     logger.warn("JGuardCredential matching  passwordField not found in the SubjectTemplate");
161                     success = false;
162                     return success;
163                 }
164                 char[] password = (passwordCredential.getValue().toString()).toCharArray();
165                 
166                 try {
167                     passwordCredential.setValue(new String(CryptUtils.cryptPassword(password)));
168                 } catch (NoSuchAlgorithmException ex) {
169                     logger.warn(ex.getMessage());
170                     success = false;
171                     return success;
172                 }
173                 
174 		try {
175 			auth.createUser(st,auth.getDefaultOrganization());
176 			success = true;
177 		} catch (AuthenticationException e) {
178             logger.debug(" registrationProcess failed ");
179             success = false;
180 		}
181 
182 		return success;
183 	}
184 
185 
186     public AccessContext anonymize(AccessContext context) {
187 	AccessContext accContext;
188 	accContext = (AccessContext)context.clone();
189 	HttpServletRequest request = (HttpServletRequest)context.getAttribute(AccessFilter.SERVLET_REQUEST);
190 	accContext.setAttribute(AccessFilter.SERVLET_REQUEST, new AnonymizerRequestWrapper(request));
191 	return accContext;
192     }
193     
194     /**
195      * fill in the SubjectTemplate the credentials from HttpServletRequest.
196      * @param req HttpServletRequest
197      * @return SubjectTemplate filled.
198      * @throws AuthenticationException
199      */
200     private static SubjectTemplate buildSubjectTemplate(HttpServletRequest req) throws AuthenticationException{
201             AuthenticationManager auth = AuthenticationManagerFactory.getAuthenticationManager();
202             SubjectTemplate defaultSt = auth.getDefaultOrganization().getSubjectTemplate();
203             SubjectTemplate st = new SubjectTemplate();
204             
205 
206             //private required credentials
207             Set privateCredRequiredFromDefaultSt =defaultSt.getPrivateRequiredCredentials();
208             Set privRequiredCred = grabRegistrationForm(req,privateCredRequiredFromDefaultSt);
209             st.setPrivateRequiredCredentials(privRequiredCred);
210 
211             //public required credentials
212             Set publicCredRequiredFromDefaultSt =defaultSt.getPublicRequiredCredentials();
213             Set pubRequiredCred = grabRegistrationForm(req,publicCredRequiredFromDefaultSt);
214             st.setPublicRequiredCredentials(pubRequiredCred);
215 
216             //public optional credentials
217             Set publicCredOptionalFromDefaultSt =defaultSt.getPublicOptionalCredentials();
218             Set pubOptionalCred = grabRegistrationForm(req,publicCredOptionalFromDefaultSt);
219             st.setPublicOptionalCredentials(pubOptionalCred);
220 
221             //public optional credentials
222             Set privateCredOptionalFromDefaultSt =defaultSt.getPrivateOptionalCredentials();
223             Set privOptionalCred = grabRegistrationForm(req,privateCredOptionalFromDefaultSt);
224             st.setPrivateOptionalCredentials(privOptionalCred);
225 
226 
227             return st;
228     }
229     
230     /**
231 	 * build a set of credentials by grabbing data from HttpServletRequest.
232 	 * @param req HttpServletRequest
233 	 * @param st SubjectTemplate
234 	 * @param credentialsFromDefaultSt
235 	 * @return Set of {@link JGuardCredential}
236 	 */
237 	private static Set grabRegistrationForm(HttpServletRequest req, Set credentialsFromDefaultSt) {
238 		Iterator itCredentials = credentialsFromDefaultSt.iterator();
239 		Set credSet = new HashSet();
240 		while(itCredentials.hasNext()){
241 			JGuardCredential jcredFromDefault = (JGuardCredential)itCredentials.next();
242 
243 			//test if we've found the credential in the http request
244 			if(req.getParameter(jcredFromDefault.getName())!= null){
245 				JGuardCredential jcred = new JGuardCredential();
246 				jcred.setName(jcredFromDefault.getName());
247 				try{
248      				jcred.setValue(req.getParameter(jcredFromDefault.getName()));
249 	    			credSet.add(jcred);
250 				}catch(IllegalArgumentException iae){
251 					logger.warn(" the property "+jcredFromDefault.getName()+" doesn't exist in the HttpServletRequest ");
252 					continue;
253 				}
254 			}
255 
256 		}
257 		return credSet;
258 	}
259 
260 	 /** load configuration from an XML file.
261      * @param configurationLocation
262      * @return Map containing filter configuration
263      */
264 	private Map loadFilterConfiguration(String configurationLocation){
265 		Document doc = XMLUtils.read(configurationLocation);
266 
267 		Element authentication = doc.getRootElement();
268 		Map filterSettings = new HashMap();
269 		if(authentication.element(HttpConstants.REGISTER_PROCESS_URI)!=null){
270 			filterSettings.put(HttpConstants.REGISTER_PROCESS_URI,authentication.element(HttpConstants.REGISTER_PROCESS_URI).getTextTrim());
271 		}
272 		if(authentication.element(HttpConstants.REGISTER_URI)!=null){
273 			filterSettings.put(HttpConstants.REGISTER_URI,authentication.element(HttpConstants.REGISTER_URI).getTextTrim());
274 		}
275 
276 		filterSettings.put(HttpConstants.AUTH_SCHEME,authentication.element(HttpConstants.AUTH_SCHEME).getTextTrim());
277 		Element loginElement = authentication.element(HttpConstants.LOGIN_FIELD);
278 		if (loginElement != null){
279 			filterSettings.put(HttpConstants.LOGIN_FIELD,loginElement.getTextTrim());
280 		}
281 		Element passwordElement = authentication.element(HttpConstants.PASSWORD_FIELD);
282 		if (passwordElement != null){
283 			filterSettings.put(HttpConstants.PASSWORD_FIELD,passwordElement.getTextTrim());
284 		}
285 
286 		
287 		return filterSettings;
288 	}
289 	
290 	
291 	/**
292 	 * @param filterSettings Map which contains filter options
293 	 * @throws ServletException
294 	 */
295 	private void setSettings(Map settings) {
296         
297         registerProcessPermission = new URLPermission(HttpConstants.REGISTER_PROCESS_URI,(String)settings.get(HttpConstants.REGISTER_PROCESS_URI));
298         registerURI =(String)settings.get(HttpConstants.REGISTER_URI);
299         registerPermission = new URLPermission(HttpConstants.REGISTER_URI,registerURI);
300         
301 	}
302 
303 
304 public Permissions getGrantedPermissions() {
305 		
306 		Permissions alwaysGrantedPermissions = new Permissions();
307 		alwaysGrantedPermissions.add(getRegisterPermission());
308 		alwaysGrantedPermissions.add(getRegisterProcessPermission());
309 		return alwaysGrantedPermissions;
310 	}
311 
312 }