enable conveying login failure to user
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / authn / provider / UsernamePasswordLoginServlet.java
index 448c2c4..2f3a5b2 100644 (file)
@@ -18,6 +18,8 @@ package edu.internet2.middleware.shibboleth.idp.authn.provider;
 
 import java.io.IOException;
 import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
@@ -26,6 +28,7 @@ import javax.security.auth.callback.NameCallback;
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -33,6 +36,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.log4j.Logger;
 import org.opensaml.util.URLBuilder;
 import org.opensaml.xml.util.DatatypeHelper;
+import org.opensaml.xml.util.Pair;
 
 import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationEngine;
 import edu.internet2.middleware.shibboleth.idp.authn.LoginHandler;
@@ -51,9 +55,12 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
 
     /** Name of JAAS configuration used to authenticate users. */
     private final String jaasConfigName = "ShibUserPassAuth";
-    
+
     /** Login page name. */
     private final String loginPage = "login.jsp";
+    
+    /** Parameter name to indicate login failure. */
+    private final String failureParam = "loginFailed";
 
     /** HTTP request parameter containing the user name. */
     private final String usernameAttribute = "j_username";
@@ -62,30 +69,35 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
     private final String passwordAttribute = "j_password";
 
     /** {@inheritDoc} */
-    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
         String username = DatatypeHelper.safeTrimOrNullString(request.getParameter(usernameAttribute));
         String password = DatatypeHelper.safeTrimOrNullString(request.getParameter(passwordAttribute));
 
-        if(username == null || password == null){
-            redirectToLoginPage(request, response);
+        if (username == null || password == null) {
+            redirectToLoginPage(request, response, null);
             return;
         }
-        
-        if(authenticateUser(request)){
+
+        if (authenticateUser(request)) {
             AuthenticationEngine.returnToAuthenticationEngine(request, response);
-        }else{
-            redirectToLoginPage(request, response);
+        } else {
+            List<Pair<String, String>> queryParams = new ArrayList<Pair<String, String>>();
+            queryParams.add(new Pair<String, String>(failureParam, "true"));
+            redirectToLoginPage(request, response, queryParams);
             return;
         }
     }
-    
+
     /**
      * Sends the user to the login page.
      * 
      * @param request current request
      * @param response current response
+     * @param queryParams query parameters to pass to the login page
      */
-    protected void redirectToLoginPage(HttpServletRequest request, HttpServletResponse response){
+    protected void redirectToLoginPage(HttpServletRequest request, HttpServletResponse response,
+            List<Pair<String, String>> queryParams) {
         try {
             StringBuilder pathBuilder = new StringBuilder();
             pathBuilder.append(request.getContextPath());
@@ -97,7 +109,10 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
             urlBuilder.setHost(request.getLocalName());
             urlBuilder.setPort(request.getLocalPort());
             urlBuilder.setPath(pathBuilder.toString());
-
+            if (queryParams != null) {
+                urlBuilder.getQueryParams().addAll(queryParams);
+            }
+            
             if (log.isDebugEnabled()) {
                 log.debug("Redirecting to login page " + urlBuilder.buildURL());
             }
@@ -110,8 +125,8 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
     }
 
     /**
-     * Authenticate a username and password against JAAS.  If authentication succeeds the principal name and 
-     * subject are placed into the request in their respective attributes.
+     * Authenticate a username and password against JAAS. If authentication succeeds the principal name and subject are
+     * placed into the request in their respective attributes.
      * 
      * @param request current authentication request
      * 
@@ -130,7 +145,7 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
 
             jaasLoginCtx.login();
             log.debug("Successfully authenticated user " + username);
-            
+
             Subject subject = jaasLoginCtx.getSubject();
             Principal principal = subject.getPrincipals().iterator().next();
             request.setAttribute(LoginHandler.PRINCIPAL_NAME_KEY, principal.getName());
@@ -146,7 +161,7 @@ public class UsernamePasswordLoginServlet extends HttpServlet {
     }
 
     /**
-     * A callback handler that provides static name and password data to a JAAS loging process.
+     * A callback handler that provides static name and password data to a JAAS login process.
      * 
      * This handler only supports {@link NameCallback} and {@link PasswordCallback}.
      */