Coverage report

  %line %branch
org.apache.jetspeed.security.impl.ntlm.NtlmSecurityValve
0% 
0% 

 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  
 import java.util.HashSet;
 21  
 import java.util.Set;
 22  
 
 23  
 import javax.security.auth.Subject;
 24  
 
 25  
 import org.apache.commons.lang.StringUtils;
 26  
 import org.apache.jetspeed.administration.PortalAuthenticationConfiguration;
 27  
 import org.apache.jetspeed.pipeline.PipelineException;
 28  
 import org.apache.jetspeed.request.RequestContext;
 29  
 import org.apache.jetspeed.security.SecurityException;
 30  
 import org.apache.jetspeed.security.SecurityHelper;
 31  
 import org.apache.jetspeed.security.User;
 32  
 import org.apache.jetspeed.security.UserManager;
 33  
 import org.apache.jetspeed.security.UserPrincipal;
 34  
 import org.apache.jetspeed.security.impl.AbstractSecurityValve;
 35  
 import org.apache.jetspeed.security.impl.UserPrincipalImpl;
 36  
 import org.apache.jetspeed.statistics.PortalStatistics;
 37  
 /**
 38  
  * NTLMSecurityValve provides Subject creation based on the
 39  
  * NTLM provided request.getRemoteUser() user name. When request.getRemoteUser() holds
 40  
  * a valid value, then this user is authorized. Otherwise the username is retrieved
 41  
  * from the Principal name in the request. In this way you can use NTLM authentication, with
 42  
  * a fallback authentication method in case the user is not properly authenticated / authorized using
 43  
  * NTLM. 
 44  
  * 
 45  
  * There are basically three authentication scenarios:
 46  
  * <ol>
 47  
  *   <li>
 48  
  *     <p><b>The user is successfully authenticated and authorized by Ntml authentication</b></p>
 49  
  *     <p>A Subject is created, with Principal derived from the remoteUser value from Ntlm authentication</p>
 50  
  *   </li>
 51  
  *   <li> 
 52  
  *     <p><b>The user is not authenticated by Ntlm, or the authenticated (can be NTLM or any other method) user cannot be authorized by Jetspeed.</b></p>
 53  
  *     <p>An anonymous Subject is created. The user can then be redirected to a login page for example.</p>
 54  
  *   </li>
 55  
  *   <li> 
 56  
  *     <p><b>The user is authenticated by a (non-NTLM) authentication method, e.g. container-based form authentication.</b></p>
 57  
  *     <p>
 58  
  *       A subject is created based on the Principal name in the request.
 59  
  *     </p>
 60  
  *   </li>
 61  
  * </ol>
 62  
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
 63  
  * @author <a href="mailto:rwatler@finali.com">Randy Walter </a>
 64  
  * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
 65  
  * @author <a href="mailto:d.dam@hippo.nl">Dennis Dam</a>
 66  
  * @version $Id$
 67  
  */
 68  
 public class NtlmSecurityValve extends AbstractSecurityValve 
 69  
 {
 70  
     private UserManager userMgr;
 71  
     private PortalStatistics statistics;
 72  
     private String networkDomain;
 73  
     private boolean ntlmAuthRequired;
 74  
     private boolean omitDomain;
 75  
     
 76  
     
 77  
     /**
 78  
      * @param userMgr A UserManager
 79  
      * @param statistics Portal Statistics
 80  
      * @param networkDomain The network domain is used in combination with the <code>omitDomain</code> flag. 
 81  
      * @param omitDomain If <code>true</code>, then the network domain is stripped from the remoteUser name.
 82  
      * @param ntlmAuthRequired if <code>true</code>, then an exception is thrown when there is no valid remoteUser,
 83  
      * or the remoteUser cannot be authorized.
 84  
      * 
 85  
      */
 86  
     public NtlmSecurityValve(UserManager userMgr, String networkDomain, boolean omitDomain, class="keyword">boolean ntlmAuthRequired, 
 87  
             PortalStatistics statistics, PortalAuthenticationConfiguration authenticationConfiguration) 
 88  0
     {
 89  0
         this.userMgr = userMgr;
 90  0
         this.statistics = statistics;
 91  0
         this.networkDomain = networkDomain;
 92  0
         this.ntlmAuthRequired = ntlmAuthRequired;
 93  0
         this.omitDomain = omitDomain;
 94  0
         this.authenticationConfiguration = authenticationConfiguration;
 95  0
     }
 96  
 
 97  
     public NtlmSecurityValve(UserManager userMgr, String networkDomain, boolean omitDomain, class="keyword">boolean ntlmAuthRequired, PortalStatistics statistics)
 98  
     {
 99  0
         this(userMgr, networkDomain, omitDomain, ntlmAuthRequired, statistics, null);        
 100  0
     }
 101  
     
 102  
     public NtlmSecurityValve(UserManager userMgr, String networkDomain, boolean omitDomain, class="keyword">boolean ntlmAuthRequired)
 103  
     {
 104  0
         this(userMgr, networkDomain, omitDomain, ntlmAuthRequired, null);
 105  0
     }
 106  
 
 107  
     public String toString()
 108  
     {
 109  0
         return "NtlmSecurityValve";
 110  
     }
 111  
  
 112  
     protected Principal getUserPrincipal(RequestContext context) throws Exception 
 113  
     {
 114  0
         Subject subject = getSubjectFromSession(context);
 115  0
         if (subject != null)
 116  
         {
 117  0
             return SecurityHelper.getPrincipal(subject, UserPrincipal.class);
 118  
         } 
 119  
         // otherwise return anonymous principal
 120  0
         return new UserPrincipalImpl(userMgr.getAnonymousUser());
 121  
     }
 122  
 
 123  
     protected Subject getSubject(RequestContext context) throws Exception 
 124  
     {
 125  0
         Subject subject = getSubjectFromSession(context);
 126  
         // Get remote user name set by web container
 127  0
         String userName = context.getRequest().getRemoteUser();
 128  0
         if ( userName == null )
 129  
         {            
 130  0
             if (ntlmAuthRequired){
 131  0
                 throw new PipelineException("Authorization failed.");    
 132  0
             } else if (context.getRequest().getUserPrincipal() != null){
 133  0
                 userName = context.getRequest().getUserPrincipal().getName();
 134  
             }             
 135  
         } else {
 136  0
             if (omitDomain && networkDomain != null){
 137  0
                 userName = StringUtils.stripStart( userName , networkDomain+"\\");
 138  
             }
 139  
         }
 140  
         
 141  
         // check whether principal name stored in session subject equals the remote user name passed by the web container
 142  0
         if (subject != null)
 143  
         {
 144  0
             Principal subjectUserPrincipal = SecurityHelper.getPrincipal(subject, UserPrincipal.class);
 145  0
             if ((subjectUserPrincipal == null) || !subjectUserPrincipal.getName().equals(userName))
 146  
             {
 147  0
                 subject = null;
 148  
             }
 149  
         }
 150  0
         if ( subject == null ){
 151  0
             if (userName != null){
 152  
                 try
 153  
                 {                    
 154  0
                     User user = userMgr.getUser(userName);
 155  0
                     if ( user != null )
 156  
                     {
 157  0
                         subject = user.getSubject();
 158  
                     }
 159  0
                 } catch (SecurityException sex)
 160  
                 {
 161  0
                     subject = null;
 162  0
                 }
 163  
                 
 164  0
                 if (subject == null && this.ntlmAuthRequired){
 165  0
                     throw new PipelineException("Authorization failed for user '"+userName+"'.");
 166  
                 }
 167  
             }  
 168  0
             if (subject == null){
 169  
                 // create anonymous user
 170  0
                 Principal userPrincipal = getUserPrincipal(context);
 171  0
                 Set principals = new HashSet();
 172  0
                 principals.add(userPrincipal);
 173  0
                 subject = new Subject(true, principals, class="keyword">new HashSet(), class="keyword">new HashSet()); 
 174  
             }
 175  
             
 176  
             // create a new statistics *user* session
 177  0
             if (statistics != null)
 178  
             {
 179  0
                 statistics.logUserLogin(context, 0);
 180  
             }
 181  
             // put IP address in session for logout
 182  0
             context.setSessionAttribute(IP_ADDRESS, context.getRequest().getRemoteAddr());            
 183  
         }        
 184  
         
 185  0
         return subject;
 186  
     }
 187  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.