1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.security.ui.webapp;
17
18 import org.springframework.security.AuthenticationException;
19
20 import org.springframework.security.ui.AuthenticationEntryPoint;
21
22 import org.springframework.security.util.PortMapper;
23 import org.springframework.security.util.PortMapperImpl;
24 import org.springframework.security.util.PortResolver;
25 import org.springframework.security.util.PortResolverImpl;
26 import org.springframework.security.util.RedirectUrlBuilder;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.springframework.beans.factory.InitializingBean;
32
33 import org.springframework.util.Assert;
34
35 import java.io.IOException;
36
37 import javax.servlet.RequestDispatcher;
38 import javax.servlet.ServletException;
39 import javax.servlet.ServletRequest;
40 import javax.servlet.ServletResponse;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class AuthenticationProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean {
65
66
67 private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class);
68
69
70
71 private PortMapper portMapper = new PortMapperImpl();
72
73 private PortResolver portResolver = new PortResolverImpl();
74
75 private String loginFormUrl;
76
77 private boolean forceHttps = false;
78
79 private boolean serverSideRedirect = false;
80
81
82
83 public void afterPropertiesSet() throws Exception {
84 Assert.hasLength(loginFormUrl, "loginFormUrl must be specified");
85 Assert.notNull(portMapper, "portMapper must be specified");
86 Assert.notNull(portResolver, "portResolver must be specified");
87 }
88
89
90
91
92
93
94
95
96
97 protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
98 AuthenticationException exception) {
99
100 return getLoginFormUrl();
101 }
102
103
104
105
106 public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException)
107 throws IOException, ServletException {
108
109 HttpServletRequest httpRequest = (HttpServletRequest) request;
110 HttpServletResponse httpResponse = (HttpServletResponse) response;
111
112 String redirectUrl = null;
113
114 if (serverSideRedirect) {
115
116 if (forceHttps && "http".equals(request.getScheme())) {
117 redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
118 }
119
120 if (redirectUrl == null) {
121 String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
122
123 if (logger.isDebugEnabled()) {
124 logger.debug("Server side forward to: " + loginForm);
125 }
126
127 RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm);
128
129 dispatcher.forward(request, response);
130
131 return;
132 }
133 } else {
134
135
136 redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException);
137
138 }
139
140 httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
141 }
142
143 protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
144 AuthenticationException authException) {
145
146 String loginForm = determineUrlToUseForThisRequest(request, response, authException);
147 int serverPort = portResolver.getServerPort(request);
148 String scheme = request.getScheme();
149
150 RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
151
152 urlBuilder.setScheme(scheme);
153 urlBuilder.setServerName(request.getServerName());
154 urlBuilder.setPort(serverPort);
155 urlBuilder.setContextPath(request.getContextPath());
156 urlBuilder.setPathInfo(loginForm);
157
158 if (forceHttps && "http".equals(scheme)) {
159 Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
160
161 if (httpsPort != null) {
162
163 urlBuilder.setScheme("https");
164 urlBuilder.setPort(httpsPort.intValue());
165 } else {
166 logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
167 }
168 }
169
170 return urlBuilder.getUrl();
171 }
172
173
174
175
176 protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
177 throws IOException, ServletException {
178
179 int serverPort = portResolver.getServerPort(request);
180 Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
181
182 if (httpsPort != null) {
183 RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
184 urlBuilder.setScheme("https");
185 urlBuilder.setServerName(request.getServerName());
186 urlBuilder.setPort(httpsPort.intValue());
187 urlBuilder.setContextPath(request.getContextPath());
188 urlBuilder.setServletPath(request.getServletPath());
189 urlBuilder.setPathInfo(request.getPathInfo());
190 urlBuilder.setQuery(request.getQueryString());
191
192 return urlBuilder.getUrl();
193 }
194
195
196 logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
197
198 return null;
199 }
200
201
202
203
204
205
206
207 public void setForceHttps(boolean forceHttps) {
208 this.forceHttps = forceHttps;
209 }
210
211 protected boolean isForceHttps() {
212 return forceHttps;
213 }
214
215
216
217
218
219
220 public void setLoginFormUrl(String loginFormUrl) {
221 this.loginFormUrl = loginFormUrl;
222 }
223
224 public String getLoginFormUrl() {
225 return loginFormUrl;
226 }
227
228 public void setPortMapper(PortMapper portMapper) {
229 this.portMapper = portMapper;
230 }
231
232 protected PortMapper getPortMapper() {
233 return portMapper;
234 }
235
236 public void setPortResolver(PortResolver portResolver) {
237 this.portResolver = portResolver;
238 }
239
240 protected PortResolver getPortResolver() {
241 return portResolver;
242 }
243
244
245
246
247
248
249 public void setServerSideRedirect(boolean serverSideRedirect) {
250 this.serverSideRedirect = serverSideRedirect;
251 }
252
253 protected boolean isServerSideRedirect() {
254 return serverSideRedirect;
255 }
256 }