Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 281   Methods: 14
NCLOC: 100   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SiteminderAuthenticationProcessingFilter.java 78.6% 91.7% 100% 90.6%
coverage coverage
 1    /* Copyright 2004, 2005 Acegi Technology Pty Limited
 2    *
 3    * Licensed under the Apache License, Version 2.0 (the "License");
 4    * you may not use this file except in compliance with the License.
 5    * You may obtain a copy of the License at
 6    *
 7    * http://www.apache.org/licenses/LICENSE-2.0
 8    *
 9    * Unless required by applicable law or agreed to in writing, software
 10    * distributed under the License is distributed on an "AS IS" BASIS,
 11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    * See the License for the specific language governing permissions and
 13    * limitations under the License.
 14    */
 15   
 16    package org.acegisecurity.ui.webapp;
 17   
 18    import org.acegisecurity.Authentication;
 19    import org.acegisecurity.AuthenticationException;
 20   
 21    import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 22   
 23    import org.acegisecurity.ui.WebAuthenticationDetails;
 24   
 25    import javax.servlet.FilterConfig;
 26    import javax.servlet.ServletException;
 27    import javax.servlet.http.HttpServletRequest;
 28   
 29   
 30    /**
 31    * Extends Acegi's AuthenticationProcessingFilter to pick up Netegrity
 32    * Siteminder's headers.
 33    *
 34    * <P>
 35    * Also provides a backup form-based authentication and the ability set source
 36    * key names.
 37    * </p>
 38    *
 39    * <P>
 40    * <B>Siteminder</B> must present two <B>headers</B> to this filter, a username
 41    * and password. You must set the header keys before this filter is used for
 42    * authentication, otherwise Siteminder checks will be skipped. If the
 43    * Siteminder check is unsuccessful (i.e. if the headers are not found), then
 44    * the form parameters will be checked (see next paragraph). This allows
 45    * applications to optionally function even when their Siteminder
 46    * infrastructure is unavailable, as is often the case during development.
 47    * </p>
 48    *
 49    * <P>
 50    * <B>Login forms</B> must present two <B>parameters</B> to this filter: a
 51    * username and password. If not specified, the parameter names to use are
 52    * contained in the static fields {@link #ACEGI_SECURITY_FORM_USERNAME_KEY}
 53    * and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}.
 54    * </p>
 55    *
 56    * <P>
 57    * <B>Do not use this class directly.</B> Instead, configure
 58    * <code>web.xml</code> to use the {@link
 59    * org.acegisecurity.util.FilterToBeanProxy}.
 60    * </p>
 61    */
 62    public class SiteminderAuthenticationProcessingFilter
 63    extends AuthenticationProcessingFilter {
 64    //~ Instance fields ========================================================
 65   
 66    /** Form password request key. */
 67    private String formPasswordParameterKey = null;
 68   
 69    /** Form username request key. */
 70    private String formUsernameParameterKey = null;
 71   
 72    /** Siteminder password header key. */
 73    private String siteminderPasswordHeaderKey = null;
 74   
 75    /** Siteminder username header key. */
 76    private String siteminderUsernameHeaderKey = null;
 77   
 78    //~ Constructors ===========================================================
 79   
 80    /**
 81    * Basic constructor.
 82    */
 83  5 public SiteminderAuthenticationProcessingFilter() {
 84  5 super();
 85    }
 86   
 87    //~ Methods ================================================================
 88   
 89    /**
 90    * @see org.acegisecurity.ui.AbstractProcessingFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest)
 91    */
 92  4 public Authentication attemptAuthentication(HttpServletRequest request)
 93    throws AuthenticationException {
 94  4 String username = null;
 95  4 String password = null;
 96   
 97    // Check the Siteminder headers for authentication info
 98  4 if ((siteminderUsernameHeaderKey != null)
 99    && (siteminderUsernameHeaderKey.length() > 0)
 100    && (siteminderPasswordHeaderKey != null)
 101    && (siteminderPasswordHeaderKey.length() > 0)) {
 102  1 username = request.getHeader(siteminderUsernameHeaderKey);
 103  1 password = request.getHeader(siteminderPasswordHeaderKey);
 104    }
 105   
 106    // If the Siteminder authentication info wasn't available, then get it
 107    // from the form parameters
 108  4 if ((username == null) || (username.length() == 0)
 109    || (password == null) || (password.length() == 0)) {
 110  3 if (logger.isDebugEnabled()) {
 111  0 logger.debug(
 112    "Siteminder headers not found for authentication, so trying to use form values");
 113    }
 114   
 115  3 if ((formUsernameParameterKey != null)
 116    && (formUsernameParameterKey.length() > 0)) {
 117  0 username = request.getParameter(formUsernameParameterKey);
 118    } else {
 119  3 username = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
 120    }
 121   
 122  3 password = obtainPassword(request);
 123    }
 124   
 125    // Convert username and password to upper case. This is normally not a
 126    // good practice but we do it here because Siteminder gives us the username
 127    // in lower case, while most backing systems store it in upper case.
 128  4 if (username != null) {
 129  3 username = username.toUpperCase();
 130    } else {
 131    // If username is null, set to blank to avoid a NPE.
 132  1 username = "";
 133    }
 134   
 135  4 if (password != null) {
 136  3 password = password.toUpperCase();
 137    } else {
 138    // If password is null, set to blank to avoid a NPE.
 139  1 password = "";
 140    }
 141   
 142  4 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
 143    password);
 144   
 145    // Allow subclasses to set the "details" property
 146  4 setDetails(request, authRequest);
 147   
 148    // Place the last username attempted into HttpSession for views
 149  4 request.getSession()
 150    .setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
 151   
 152  4 return this.getAuthenticationManager().authenticate(authRequest);
 153    }
 154   
 155    /**
 156    * This filter by default responds to <code>/j_acegi_security_check</code>.
 157    *
 158    * @return the default
 159    */
 160  5 public String getDefaultFilterProcessesUrl() {
 161  5 return "/j_acegi_security_check";
 162    }
 163   
 164    /**
 165    * Returns the form password parameter key.
 166    *
 167    * @return The form password parameter key.
 168    */
 169  1 public String getFormPasswordParameterKey() {
 170  1 return formPasswordParameterKey;
 171    }
 172   
 173    /**
 174    * Returns the form username parameter key.
 175    *
 176    * @return The form username parameter key.
 177    */
 178  1 public String getFormUsernameParameterKey() {
 179  1 return formUsernameParameterKey;
 180    }
 181   
 182    /**
 183    * Returns the Siteminder password header key.
 184    *
 185    * @return The Siteminder password header key.
 186    */
 187  1 public String getSiteminderPasswordHeaderKey() {
 188  1 return siteminderPasswordHeaderKey;
 189    }
 190   
 191    /**
 192    * Returns the Siteminder username header key.
 193    *
 194    * @return The Siteminder username header key.
 195    */
 196  1 public String getSiteminderUsernameHeaderKey() {
 197  1 return siteminderUsernameHeaderKey;
 198    }
 199   
 200    /**
 201    * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
 202    */
 203  4 public void init(FilterConfig filterConfig) throws ServletException {}
 204   
 205    /**
 206    * Enables subclasses to override the composition of the password, such as
 207    * by including additional values and a separator.
 208    *
 209    * <p>
 210    * This might be used for example if a postcode/zipcode was required in
 211    * addition to the password. A delimiter such as a pipe (|) should be used
 212    * to separate the password and extended value(s). The
 213    * <code>AuthenticationDao</code> will need to generate the expected
 214    * password in a corresponding manner.
 215    * </p>
 216    *
 217    * @param request so that request attributes can be retrieved
 218    *
 219    * @return the password that will be presented in the
 220    * <code>Authentication</code> request token to the
 221    * <code>AuthenticationManager</code>
 222    */
 223  3 protected String obtainPassword(HttpServletRequest request) {
 224  3 if ((formPasswordParameterKey != null)
 225    && (formPasswordParameterKey.length() > 0)) {
 226  0 return request.getParameter(formPasswordParameterKey);
 227    } else {
 228  3 return request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);
 229    }
 230    }
 231   
 232    /**
 233    * Provided so that subclasses may configure what is put into the
 234    * authentication request's details property. The default implementation
 235    * simply constructs {@link WebAuthenticationDetails}.
 236    *
 237    * @param request that an authentication request is being created for
 238    * @param authRequest the authentication request object that should have
 239    * its details set
 240    */
 241  4 protected void setDetails(HttpServletRequest request,
 242    UsernamePasswordAuthenticationToken authRequest) {
 243  4 authRequest.setDetails(new WebAuthenticationDetails(request));
 244    }
 245   
 246    /**
 247    * Sets the form password parameter key.
 248    *
 249    * @param key The form password parameter key.
 250    */
 251  1 public void setFormPasswordParameterKey(final String key) {
 252  1 this.formPasswordParameterKey = key;
 253    }
 254   
 255    /**
 256    * Sets the form username parameter key.
 257    *
 258    * @param key The form username parameter key.
 259    */
 260  1 public void setFormUsernameParameterKey(final String key) {
 261  1 this.formUsernameParameterKey = key;
 262    }
 263   
 264    /**
 265    * Sets the Siteminder password header key.
 266    *
 267    * @param key The Siteminder password header key.
 268    */
 269  2 public void setSiteminderPasswordHeaderKey(final String key) {
 270  2 this.siteminderPasswordHeaderKey = key;
 271    }
 272   
 273    /**
 274    * Sets the Siteminder username header key.
 275    *
 276    * @param key The Siteminder username header key.
 277    */
 278  2 public void setSiteminderUsernameHeaderKey(final String key) {
 279  2 this.siteminderUsernameHeaderKey = key;
 280    }
 281    }