Subversion Repositories general

Rev

Rev 1072 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
924 dev 1
package ak.hostadmiral.core.servlet;
919 dev 2
 
3
import java.util.List;
4
import java.util.ArrayList;
5
import java.util.StringTokenizer;
6
import java.io.IOException;
7
import java.net.URLEncoder;
8
import java.security.Principal;
9
import java.security.AccessControlException;
10
 
11
import javax.servlet.Filter;
12
import javax.servlet.FilterChain;
13
import javax.servlet.FilterConfig;
14
import javax.servlet.ServletException;
15
import javax.servlet.ServletRequest;
16
import javax.servlet.ServletResponse;
17
import javax.servlet.http.HttpSession;
18
import javax.servlet.http.HttpServletRequest;
19
import javax.servlet.http.HttpServletResponse;
20
 
21
import org.apache.log4j.Logger;
22
 
23
import ak.backpath.BackPath;
24
 
1072 dev 25
import ak.hostadmiral.util.ModelException;
26
import ak.hostadmiral.core.servlet.LoginInfo;
924 dev 27
import ak.hostadmiral.core.model.User;
1072 dev 28
import ak.hostadmiral.core.model.UserManager;
919 dev 29
 
30
/**
31
 * Ensures that user is logged in to the system to process its request.
32
 */
33
public class LoginFilter
34
	implements Filter
35
{
36
	private static final Logger logger = Logger.getLogger(LoginFilter.class);
37
 
38
	private FilterConfig filterConfig;
39
	private String       loginUrl;
40
	private String       loginServlet;
41
	private List         passUrls  = new ArrayList();
42
	private List         passMasks = new ArrayList();
43
 
44
	public void init(FilterConfig filterConfig)
45
		throws ServletException
46
	{
47
		// get config
48
		this.filterConfig = filterConfig;
49
 
50
		if(filterConfig == null)
51
			throw new ServletException("No configuration for the filter");
52
 
53
		// get login url
54
		loginUrl = filterConfig.getInitParameter("loginUrl");
55
 
56
		if(loginUrl == null)
57
			throw new ServletException("No login URL specified");
58
 
59
		// ensure it's absolute path
60
		if(!loginUrl.startsWith("/"))
61
			loginUrl = "/" + loginUrl;
62
 
63
		// get servlet part ot the url
64
		int qPos = loginUrl.indexOf("?");
65
 
66
		if(qPos < 0)
67
			loginServlet = loginUrl;
68
		else
69
			loginServlet = loginUrl.substring(0, qPos);
70
 
71
		// get pass through URLs
72
		String passUrlsStr = filterConfig.getInitParameter("passUrls");
73
		if(passUrlsStr != null) {
74
			String[] urls = passUrlsStr.split("\\s*;\\s*");
75
 
76
			for(int i = 0; i < urls.length; i++) {
77
	        	if(urls[i].endsWith("*")) {
78
	        		passMasks.add(urls[i].substring(0, urls[i].length()-1));
79
	        	}
80
	        	else {
81
					passUrls.add(urls[i]);
82
	        	}
83
			}
84
		}
85
 
86
		// avoid loop
87
		if(!isPassThrough(loginServlet)) {
88
			passUrls.add(loginServlet);
89
		}
90
	}
91
 
92
	private boolean isPassThrough(String url)
93
	{
94
        for(int i = 0; i < passUrls.size(); i++) {
95
        	if(url.equals((String)passUrls.get(i))) return true;
96
        }
97
 
98
        for(int i = 0; i < passMasks.size(); i++) {
99
        	if(url.startsWith((String)passMasks.get(i))) return true;
100
        }
101
 
102
        return false;
103
	}
104
 
105
	public void doFilter(ServletRequest request, ServletResponse response,
106
			FilterChain chain)
107
		throws IOException, ServletException
108
	{
109
		boolean processNext;
110
 
111
		if(!(request instanceof HttpServletRequest))
112
			throw new ServletException("Do not know how to handle non-HTTP requests");
113
		if(!(response instanceof HttpServletResponse))
1222 dev 114
			throw new ServletException("Do not know how to handle non-HTTP responses");
919 dev 115
 
116
        HttpServletRequest  httpRequest  = (HttpServletRequest)request;
117
        HttpServletResponse httpResponse = (HttpServletResponse)response;
118
 
119
        logger.debug("Requested " + httpRequest.getServletPath());
120
 
121
		if(isPassThrough(httpRequest.getServletPath())) {
122
			processNext = true;
123
			logger.debug("pass through");
124
		}
125
		else {
126
			try {
127
				HttpSession session = httpRequest.getSession(false);
128
 
129
				if(session == null)
130
					throw new AccessControlException("No session");
131
 
1056 dev 132
				Object userObj = session.getAttribute(SessionKeys.USER);
1072 dev 133
				if(userObj == null) {
134
					// try to relogin
135
					Object loginInfoObj = session.getAttribute(SessionKeys.LOGIN_INFO);
136
					if(loginInfoObj == null)
137
						throw new AccessControlException("No user");
919 dev 138
 
1072 dev 139
					if(!(loginInfoObj instanceof LoginInfo))
140
						throw new ServletException(
141
							"Wrong type of login info information: "
142
								+ loginInfoObj.getClass().getName());
919 dev 143
 
1072 dev 144
                    try {
145
						userObj = UserManager.getInstance().get(((LoginInfo)loginInfoObj).getId());
146
                    }
147
                    catch(ModelException ex) {
148
						throw new AccessControlException("No user");
149
                    }
150
 
151
					if(userObj == null)
152
						throw new AccessControlException("No user");
153
 
154
					session.setAttribute(SessionKeys.USER, userObj);
155
			        logger.debug("User re-logined: " + userObj);
156
				}
157
                else {
158
					if(!(userObj instanceof User))
159
						throw new ServletException(
160
							"Wrong type of user information: " + userObj.getClass().getName());
161
 
162
					logger.debug("User found - OK");
163
				}
164
 
919 dev 165
				processNext = true;
166
			}
167
			catch(AccessControlException ex) {
168
				String redirectUrl;
169
				try {
170
					redirectUrl = httpRequest.getContextPath() + loginUrl
171
						+ BackPath.findBackPath(httpRequest).getForwardParams();
172
				}
173
				catch(Exception ex2) {
174
					logger.error("Cannot get forward redirect", ex2);
175
					redirectUrl = httpRequest.getContextPath() + loginUrl;
176
				}
177
 
178
				logger.info("Redirect because of '" + ex.getMessage() + "' to " + redirectUrl);
179
				httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
180
 
181
				processNext = false;
182
			}
183
		}
184
 
185
		if(processNext) {              // no problems found
186
			chain.doFilter(request, response);
187
		}
188
	}
189
 
190
	public void destroy()
191
	{
192
	}
193
}