View Javadoc

1   package org.springframework.security.ui.webapp;
2   
3   import java.io.IOException;
4   
5   import javax.servlet.FilterChain;
6   import javax.servlet.ServletException;
7   import javax.servlet.http.HttpServletRequest;
8   import javax.servlet.http.HttpServletResponse;
9   import javax.servlet.http.HttpSession;
10  
11  import org.springframework.beans.BeanWrapperImpl;
12  import org.springframework.security.AuthenticationException;
13  import org.springframework.security.ui.AbstractProcessingFilter;
14  import org.springframework.security.ui.FilterChainOrder;
15  import org.springframework.security.ui.SpringSecurityFilter;
16  import org.springframework.security.ui.rememberme.AbstractRememberMeServices;
17  
18  /**
19   * For internal use with namespace configuration in the case where a user doesn't configure a login page.
20   * The configuration code will insert this filter in the chain instead.
21   *
22   * Will only work if a redirect is used to the login page.
23   *
24   * @author Luke Taylor
25   * @version $Id: DefaultLoginPageGeneratingFilter.java 3084 2008-05-23 20:55:10Z luke_t $
26   * @since 2.0
27   */
28  public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
29      public static final String DEFAULT_LOGIN_PAGE_URL = "/spring_security_login";
30      public static final String ERROR_PARAMETER_NAME = "login_error";
31      boolean formLoginEnabled;
32      boolean openIdEnabled;
33      private String authenticationUrl;
34      private String usernameParameter;
35      private String passwordParameter;
36      private String rememberMeParameter;
37      private String openIDauthenticationUrl;
38      private String openIDusernameParameter;
39      private String openIDrememberMeParameter;
40      
41      public DefaultLoginPageGeneratingFilter(AbstractProcessingFilter filter) {
42          if (filter instanceof AuthenticationProcessingFilter) {
43              init((AuthenticationProcessingFilter)filter, null);
44          } else {
45              init(null, filter);
46          }
47      }
48      
49      public DefaultLoginPageGeneratingFilter(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
50          init(authFilter, openIDFilter);
51      }
52      
53      private void init(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
54          if (authFilter != null) {
55              formLoginEnabled = true;
56              authenticationUrl = authFilter.getDefaultFilterProcessesUrl();
57              usernameParameter = authFilter.getUsernameParameter();
58              passwordParameter = authFilter.getPasswordParameter();
59      
60              if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
61                  rememberMeParameter = ((AbstractRememberMeServices)authFilter.getRememberMeServices()).getParameter();
62              }
63          }
64          
65          if (openIDFilter != null) {
66              openIdEnabled = true;
67              openIDauthenticationUrl = openIDFilter.getDefaultFilterProcessesUrl();
68              openIDusernameParameter = (String) (new BeanWrapperImpl(openIDFilter)).getPropertyValue("claimedIdentityFieldName");
69  
70              if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
71                  openIDrememberMeParameter = ((AbstractRememberMeServices)openIDFilter.getRememberMeServices()).getParameter();
72              }
73          }        
74      }
75  
76      protected void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
77          if (isLoginUrlRequest(request)) {
78              String loginPageHtml = generateLoginPageHtml(request);
79              response.setContentType("text/html;charset=UTF-8");
80              response.setContentLength(loginPageHtml.length());
81              response.getOutputStream().print(loginPageHtml);            
82  
83              return;
84          }
85  
86          chain.doFilter(request, response);
87      }
88  
89      private String generateLoginPageHtml(HttpServletRequest request) {
90          boolean loginError = request.getParameter(ERROR_PARAMETER_NAME) != null;
91          String errorMsg = "none";
92          String lastUser = "";
93  
94          if (loginError) {
95              HttpSession session = request.getSession(false);
96  
97              if(session != null) {
98                  lastUser = (String) session.getAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
99                  AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
100                 errorMsg = ex != null ? ex.getMessage() : "none";
101                 if (lastUser == null) {
102                     lastUser = "";
103                 }
104             }
105         }
106         
107         StringBuffer sb = new StringBuffer();
108         
109         sb.append("<html><head><title>Login Page</title></head>");
110         
111         if (formLoginEnabled) {
112             sb.append("<body onload='document.f.").append(usernameParameter).append(".focus();'>\n");
113         }
114         
115         if (loginError) {
116             sb.append("<p><font color='red'>Your login attempt was not successful, try again.<br/><br/>Reason: ");
117             sb.append(errorMsg);
118             sb.append("</font></p>");
119         }
120         
121         if (formLoginEnabled) {
122             sb.append("<h3>Login with Username and Password</h3>");
123             sb.append("<form name='f' action='").append(request.getContextPath()).append(authenticationUrl).append("' method='POST'>\n");
124             sb.append(" <table>\n");
125             sb.append("    <tr><td>User:</td><td><input type='text' name='");
126             sb.append(usernameParameter).append("' value='").append(lastUser).append("'></td></tr>\n");
127             sb.append("    <tr><td>Password:</td><td><input type='password' name='").append(passwordParameter).append("'/></td></tr>\n");
128     
129             if (rememberMeParameter != null) {
130                 sb.append("    <tr><td><input type='checkbox' name='").append(rememberMeParameter).append("'/></td><td>Remember me on this computer.</td></tr>\n");
131             }
132     
133             sb.append("    <tr><td colspan='2'><input name=\"submit\" type=\"submit\"/></td></tr>\n");
134             sb.append("    <tr><td colspan='2'><input name=\"reset\" type=\"reset\"/></td></tr>\n");
135             sb.append("  </table>\n");
136             sb.append("</form>");
137         }
138         
139         if(openIdEnabled) {
140             sb.append("<h3>Login with OpenID Identity</h3>");
141             sb.append("<form name='oidf' action='").append(request.getContextPath()).append(openIDauthenticationUrl).append("' method='POST'>\n");
142             sb.append(" <table>\n");
143             sb.append("    <tr><td>Identity:</td><td><input type='text' name='");
144             sb.append(openIDusernameParameter).append("'/></td></tr>\n");
145     
146             if (rememberMeParameter != null) {
147                 sb.append("    <tr><td><input type='checkbox' name='").append(openIDrememberMeParameter).append("'></td><td>Remember me on this computer.</td></tr>\n");
148             }
149     
150             sb.append("    <tr><td colspan='2'><input name=\"submit\" type=\"submit\"/></td></tr>\n");
151             sb.append("    <tr><td colspan='2'><input name=\"reset\" type=\"reset\"/></td></tr>\n");
152             sb.append("  </table>\n");
153             sb.append("</form>");            
154         }
155         
156         sb.append("</body></html>");
157         
158         return sb.toString();
159     }
160 
161     public int getOrder() {
162         return FilterChainOrder.LOGIN_PAGE_FILTER;
163     }
164 
165     private boolean isLoginUrlRequest(HttpServletRequest request) {
166         String uri = request.getRequestURI();
167         int pathParamIndex = uri.indexOf(';');
168 
169         if (pathParamIndex > 0) {
170             // strip everything after the first semi-colon
171             uri = uri.substring(0, pathParamIndex);
172         }
173 
174         if ("".equals(request.getContextPath())) {
175             return uri.endsWith(DEFAULT_LOGIN_PAGE_URL);
176         }
177 
178         return uri.endsWith(request.getContextPath() + DEFAULT_LOGIN_PAGE_URL);
179     }
180 }