View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.security.impl.ntlm;
18  
19  import java.security.Principal;
20  
21  import javax.servlet.http.HttpServletRequest;
22  import javax.servlet.http.HttpServletRequestWrapper;
23  
24  import org.apache.commons.lang.ArrayUtils;
25  import org.apache.commons.lang.StringUtils;
26  
27  /***
28   * NtlmHttpServletRequestWrapper should be used in combination with an Ntml authentication filter (jCIFS).
29   * This filter wraps the original request, setting the principal and remoteUser retrieved by Ntml 
30   * authentication with the client. The wrapper Request sets the principal and remoteUser, <i>regardless</i> 
31   * of the principal already present in the original request. This HttpServletRequestWrapper returns the principal 
32   * from the original request when it's there, and otherwise returns the Ntml principal. When the
33   * the Ntml principal is actually returned can be influenced by a comma-separated list of servlet urls: 
34   *  only for these urls the Ntlm principal / remoteUser is ignored. 
35   * @see NtlmHttpServletRequestFilter
36   * @author <a href="mailto:d.dam@hippo.nl">Dennis Dam</a>
37   * @version $Id$
38   */
39  public class NtlmHttpServletRequestWrapper extends HttpServletRequestWrapper {
40      private Principal principal;
41      private String remoteUser;
42      
43      public NtlmHttpServletRequestWrapper(HttpServletRequest req, String ignoreNtmlUrls) {
44          super(req);    
45          if (req instanceof HttpServletRequestWrapper){
46              String[] urls = ignoreNtmlUrls != null ? StringUtils.split(ignoreNtmlUrls, ',') : new String[]{};
47              String servletUrl = req.getServletPath();
48              Principal reqPrincipal = req.getUserPrincipal();
49              HttpServletRequest originalRequest = (HttpServletRequest)((HttpServletRequestWrapper) req).getRequest();
50              /*
51               *  Original request principal has precedence over Ntml authenticated principal. This is needed
52               *  in the case that the Ntlm authenticated principal is not authorized by Jetspeed: a fallback login 
53               *  method can then be used. If Ntml authentication succeeds, then the principal from the
54               *  original request will be null.
55               */ 
56              if (originalRequest.getUserPrincipal() != null){
57                  principal = originalRequest.getUserPrincipal();
58              } else 
59              /*
60               *   If no principal in the original request, take principal from Ntlm authentication, but
61               *   only if the current servlet url is not in the ignore list. The last
62               *   requirement is necessary when falling back to another authentication method, e.g. container-based
63               *   form authentication: these authentication methods might only work if there is no 
64               *   principal in the request.    
65               */
66              if (!ArrayUtils.contains(urls,servletUrl) && reqPrincipal != null && req.getRemoteUser() != null){
67                  principal = reqPrincipal;
68                  remoteUser = req.getRemoteUser();
69              }             
70          } else {            
71              principal = super.getUserPrincipal();
72          }
73      }
74      
75      public Principal getUserPrincipal() {        
76          return principal;
77      }
78      
79      public String getRemoteUser() {   
80          return remoteUser;
81      }
82      
83  }