1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.adapters.cas;
17
18 import edu.yale.its.tp.cas.auth.PasswordHandler;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import org.springframework.context.ApplicationContext;
24
25 import org.springframework.web.context.support.WebApplicationContextUtils;
26
27 import java.util.Map;
28
29 import javax.servlet.ServletRequest;
30 import javax.servlet.http.HttpServletRequest;
31
32
33 /***
34 * Enables CAS to use the Acegi Security System for authentication.
35 *
36 * <P>
37 * This class works along with {@link CasPasswordHandler} to enable users to
38 * easily migrate from stand-alone Acegi Security System deployments to
39 * enterprise-wide CAS deployments.
40 * </p>
41 *
42 * <p>
43 * It should be noted that the Acegi Security System will operate as a CAS
44 * client irrespective of the <code>PasswordHandler</code> used on the CAS
45 * server. In other words, this class need <B>not</B> be used on the CAS
46 * server if not desired. It exists solely for the convenience of users
47 * wishing have CAS delegate to an Acegi Security System-based
48 * <code>AuthenticationManager</code>.
49 * </p>
50 *
51 * <p>
52 * This class works requires a properly configured
53 * <code>CasPasswordHandler</code>. On the first authentication request, the
54 * class will use Spring's {@link
55 * WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
56 * method to obtain an <code>ApplicationContext</code> instance, inside which
57 * must be a configured <code>CasPasswordHandler</code> instance. The
58 * <code>CasPasswordHandlerProxy</code> will then delegate authentication
59 * requests to that instance.
60 * </p>
61 *
62 * <p>
63 * To configure CAS to use this class, edit CAS' <code>web.xml</code> and
64 * define the <code>edu.yale.its.tp.cas.authHandler</code> context parameter
65 * with the value
66 * <code>org.acegisecurity.adapters.cas.CasPasswordHandlerProxy</code>.
67 * </p>
68 *
69 * @author Ben Alex
70 * @version $Id: CasPasswordHandlerProxy.java,v 1.2 2005/11/17 00:56:28 benalex Exp $
71 */
72 public class CasPasswordHandlerProxy implements PasswordHandler {
73
74
75 private static final Log logger = LogFactory.getLog(CasPasswordHandlerProxy.class);
76
77
78
79 private ApplicationContext ctx;
80 private CasPasswordHandler handler;
81
82
83
84 /***
85 * Called by CAS when authentication is required.
86 *
87 * <P>
88 * Delegates to the <code>CasPasswordHandler</code>.
89 * </p>
90 *
91 * @param request as provided by CAS
92 * @param username provided to CAS
93 * @param password provided to CAS
94 *
95 * @return whether authentication was successful or not
96 *
97 * @throws IllegalArgumentException if the application context does not
98 * contain a <code>CasPasswordHandler</code> or the
99 * <code>ServletRequest</code> was not of type
100 * <code>HttpServletRequest</code>
101 */
102 public boolean authenticate(ServletRequest request, String username,
103 String password) {
104 if (ctx == null) {
105 if (!(request instanceof HttpServletRequest)) {
106 throw new IllegalArgumentException(
107 "Can only process HttpServletRequest");
108 }
109
110 HttpServletRequest httpRequest = (HttpServletRequest) request;
111
112 ctx = this.getContext(httpRequest);
113 }
114
115 if (handler == null) {
116 Map beans = ctx.getBeansOfType(CasPasswordHandler.class, true, true);
117
118 if (beans.size() == 0) {
119 throw new IllegalArgumentException(
120 "Bean context must contain at least one bean of type CasPasswordHandler");
121 }
122
123 String beanName = (String) beans.keySet().iterator().next();
124 handler = (CasPasswordHandler) beans.get(beanName);
125 }
126
127 return handler.authenticate(request, username, password);
128 }
129
130 /***
131 * Allows test cases to override where application context obtained from.
132 *
133 * @param httpRequest which can be used to find the
134 * <code>ServletContext</code>
135 *
136 * @return the Spring application context
137 */
138 protected ApplicationContext getContext(HttpServletRequest httpRequest) {
139 return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession()
140 .getServletContext());
141 }
142 }