View Javadoc
1   package org.argeo.cms.integration;
2   
3   import static org.argeo.api.NodeConstants.LOGIN_CONTEXT_USER;
4   
5   import java.io.IOException;
6   import java.security.AccessControlContext;
7   import java.security.AccessController;
8   import java.security.PrivilegedAction;
9   import java.util.Map;
10  
11  import javax.security.auth.Subject;
12  import javax.security.auth.login.LoginContext;
13  import javax.security.auth.login.LoginException;
14  import javax.servlet.http.HttpServletRequest;
15  import javax.servlet.http.HttpServletResponse;
16  
17  import org.argeo.cms.auth.HttpRequestCallbackHandler;
18  import org.osgi.service.http.context.ServletContextHelper;
19  
20  /** Manages security access to servlets. */
21  public class CmsPrivateServletContext extends ServletContextHelper {
22  	public final static String LOGIN_PAGE = "argeo.cms.integration.loginPage";
23  	public final static String LOGIN_SERVLET = "argeo.cms.integration.loginServlet";
24  	private String loginPage;
25  	private String loginServlet;
26  
27  	public void init(Map<String, String> properties) {
28  		loginPage = properties.get(LOGIN_PAGE);
29  		loginServlet = properties.get(LOGIN_SERVLET);
30  	}
31  
32  	/**
33  	 * Add the {@link AccessControlContext} as a request attribute, or redirect to
34  	 * the login page.
35  	 */
36  	@Override
37  	public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) throws IOException {
38  		LoginContext lc = null;
39  
40  		String pathInfo = request.getPathInfo();
41  		String servletPath = request.getServletPath();
42  		if ((pathInfo != null && (servletPath + pathInfo).equals(loginPage)) || servletPath.contentEquals(loginServlet))
43  			return true;
44  		try {
45  			lc = new LoginContext(LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request, response));
46  			lc.login();
47  		} catch (LoginException e) {
48  			lc = processUnauthorized(request, response);
49  			if (lc == null)
50  				return false;
51  		}
52  		Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
53  
54  			@Override
55  			public Void run() {
56  				request.setAttribute(REMOTE_USER, AccessController.getContext());
57  				return null;
58  			}
59  
60  		});
61  
62  		return true;
63  	}
64  
65  	protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
66  		try {
67  			response.sendRedirect(loginPage);
68  		} catch (IOException e) {
69  			throw new RuntimeException("Cannot redirect to login page", e);
70  		}
71  		return null;
72  	}
73  }