diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java new file mode 100644 index 0000000000..5a036b0bb5 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java @@ -0,0 +1,260 @@ +package net.sf.acegisecurity.ui.webapp; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.AuthenticationException; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.ui.WebAuthenticationDetails; + +/** + * Extends Acegi's AuthenticationProcessingFilter to use Siteminder's headers for identification. + * + *
+ * Provides the ability set all source key names and also provides form-based authentication as a backup. + *
+ * + *+ * You must set the Siteminder header keys, otherwise Siteminder checks will be skipped (there + * are no defaults). If the Siteminder check is unsuccessful or if the headers are not + * defined/found in the HTTP request, then the form parameters will be checked (see below). + * This allows applications to function even when their Siteminder infrastructure + * is unavailable, as is often the case during development. If you do not wish to use backup + * form-based authentication, then set the form parameter keys to null/blank. + *
+ * + *
+ * Siteminder must present at least one HTTP header to this filter - typically
+ * containing a unique identifier such a username, an employee number or a national ID.
+ * This makes sense because Siteminder has already authenticated the user prior to
+ * getting to this filter, so we're really only using it for identification and not authentication.
+ * Set the siteminderUsernameHeaderKey value to tell the filter where to greb the "username"
+ * value. You'll typically also set the siteminderPasswordHeaderKey to the same header key.
+ * Just remember to modify your AuthenticationDAO so that it can handle identity-only requests! *
+ *
+ * Forms must present two parameters to this filter: a username and a password. + * If not specified, the parameter names to use are defaulted to the static fields + * {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}. + *
+ * + *
+ * Do not use this class directly. Instead, configure web.xml
+ * to use the {@link net.sf.acegisecurity.util.FilterChainProxy} and include this filter.
+ *
/j_acegi_security_check.
+ *
+ * @return the default
+ */
+ public String getDefaultFilterProcessesUrl() {
+ return "/j_acegi_security_check";
+ }
+
+ public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
+
+ String username = null;
+ String password = null;
+
+ // Check the Siteminder headers for authentication info
+ if (siteminderUsernameHeaderKey != null
+ && siteminderUsernameHeaderKey.length() > 0
+ && siteminderPasswordHeaderKey != null
+ && siteminderPasswordHeaderKey.length() > 0) {
+
+ username = request.getHeader(siteminderUsernameHeaderKey);
+ password = request.getHeader(siteminderPasswordHeaderKey);
+
+ }
+
+ // If the Siteminder authentication info wasn't available, then get it from the form parameters
+ if (username == null || username.length() == 0 || password == null || password.length() == 0) {
+
+ //System.out.println("Siteminder headers not found for authentication");
+
+ if (formUsernameParameterKey != null && formUsernameParameterKey.length() > 0) {
+ username = request.getParameter(formUsernameParameterKey);
+ }
+ else {
+ username = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
+ }
+
+ password = obtainPassword(request);
+
+ }
+
+ // If either are null, set them to blank to avoid a NPE.
+ if (username == null) {
+ username = "";
+ }
+ if (password == null) {
+ password = "";
+ }
+
+ UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
+
+ // Allow subclasses to set the "details" property
+ setDetails(request, authRequest);
+
+ // Place the last username attempted into HttpSession for views
+ request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
+
+ return this.getAuthenticationManager().authenticate(authRequest);
+ }
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ /***
+ * Provided so that subclasses may configure what is put into the
+ * authentication request's details property. The default implementation
+ * simply constructs {@link WebAuthenticationDetails}.
+ *
+ * @param request that an authentication request is being created for
+ * @param authRequest the authentication request object that should have
+ * its details set
+ */
+ protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
+ authRequest.setDetails(new WebAuthenticationDetails(request));
+ }
+
+ /***
+ * Enables subclasses to override the composition of the password, such as
+ * by including additional values and a separator.
+ *
+ *
+ * This might be used for example if a postcode/zipcode was required in
+ * addition to the password. A delimiter such as a pipe (|) should be used
+ * to separate the password and extended value(s). The
+ * AuthenticationDao will need to generate the expected
+ * password in a corresponding manner.
+ *
Authentication request token to the
+ * AuthenticationManager
+ */
+ protected String obtainPassword(HttpServletRequest request) {
+
+ if (formPasswordParameterKey != null && formPasswordParameterKey.length() > 0) {
+ return request.getParameter(formPasswordParameterKey);
+ }
+ else {
+ return request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);
+ }
+
+ }
+
+ /**
+ * Returns the form password parameter key.
+ *
+ * @return The form password parameter key.
+ */
+ public String getFormPasswordParameterKey() {
+ return formPasswordParameterKey;
+ }
+
+ /**
+ * Returns the form username parameter key.
+ *
+ * @return The form username parameter key.
+ */
+ public String getFormUsernameParameterKey() {
+ return formUsernameParameterKey;
+ }
+
+ /**
+ * Returns the Siteminder password header key.
+ *
+ * @return The Siteminder password header key.
+ */
+ public String getSiteminderPasswordHeaderKey() {
+ return siteminderPasswordHeaderKey;
+ }
+
+ /**
+ * Returns the Siteminder username header key.
+ *
+ * @return The Siteminder username header key.
+ */
+ public String getSiteminderUsernameHeaderKey() {
+ return siteminderUsernameHeaderKey;
+ }
+
+ /**
+ * Sets the form password parameter key.
+ *
+ * @param key The form password parameter key.
+ */
+ public void setFormPasswordParameterKey(final String key) {
+ this.formPasswordParameterKey = key;
+ }
+
+ /**
+ * Sets the form username parameter key.
+ *
+ * @param key The form username parameter key.
+ */
+ public void setFormUsernameParameterKey(final String key) {
+ this.formUsernameParameterKey = key;
+ }
+
+ /**
+ * Sets the Siteminder password header key.
+ *
+ * @param key The Siteminder password header key.
+ */
+ public void setSiteminderPasswordHeaderKey(final String key) {
+ this.siteminderPasswordHeaderKey = key;
+ }
+
+ /**
+ * Sets the Siteminder username header key.
+ *
+ * @param key The Siteminder username header key.
+ */
+ public void setSiteminderUsernameHeaderKey(final String key) {
+ this.siteminderUsernameHeaderKey = key;
+ }
+
+}