2 * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package edu.internet2.middleware.shibboleth.idp.profile;
19 import java.util.HashMap;
20 import java.util.List;
22 import java.util.Timer;
23 import java.util.concurrent.locks.Lock;
25 import javax.servlet.ServletRequest;
26 import javax.servlet.http.HttpServletRequest;
28 import org.opensaml.util.resource.Resource;
29 import org.opensaml.xml.util.Pair;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.context.ApplicationContext;
34 import edu.internet2.middleware.shibboleth.common.config.BaseReloadableService;
35 import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
36 import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
37 import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
38 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractRequestURIMappedProfileHandler;
39 import edu.internet2.middleware.shibboleth.idp.authn.LoginHandler;
40 import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
43 * Implementation of a {@link ProfileHandlerManager} that maps the request path, without the servlet context, to a
44 * profile handler and adds support for authentication handlers.
46 public class IdPProfileHandlerManager extends BaseReloadableService implements ProfileHandlerManager {
49 private final Logger log = LoggerFactory.getLogger(IdPProfileHandlerManager.class);
51 /** Handler used for errors. */
52 private AbstractErrorHandler errorHandler;
54 /** Map of request paths to profile handlers. */
55 private Map<String, AbstractRequestURIMappedProfileHandler> profileHandlers;
57 /** Map of authentication methods to login handlers. */
58 private Map<String, LoginHandler> loginHandlers;
61 * Constructor. Configuration resources are not monitored for changes.
63 * @param configurations configuration resources for this service
65 public IdPProfileHandlerManager(List<Resource> configurations) {
66 super(configurations);
67 profileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
68 loginHandlers = new HashMap<String, LoginHandler>();
74 * @param timer timer resource polling tasks are scheduled with
75 * @param configurations configuration resources for this service
76 * @param pollingFrequency the frequency, in milliseconds, to poll the policy resources for changes, must be greater
79 public IdPProfileHandlerManager(List<Resource> configurations, Timer timer, long pollingFrequency) {
80 super(timer, configurations, pollingFrequency);
81 profileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
82 loginHandlers = new HashMap<String, LoginHandler>();
86 public AbstractErrorHandler getErrorHandler() {
91 * Sets the error handler.
93 * @param handler error handler
95 public void setErrorHandler(AbstractErrorHandler handler) {
96 if (handler == null) {
97 throw new IllegalArgumentException("Error handler may not be null");
99 errorHandler = handler;
103 public ProfileHandler getProfileHandler(ServletRequest request) {
104 ProfileHandler handler;
106 String requestPath = ((HttpServletRequest) request).getPathInfo();
107 log.debug("{}: Looking up profile handler for request path: {}", getId(), requestPath);
109 Lock readLock = getReadWriteLock().readLock();
111 handler = profileHandlers.get(requestPath);
114 if (handler != null) {
115 log.debug("{}: Located profile handler of the following type for the request path: {}", getId(), handler
116 .getClass().getName());
118 log.debug("{}: No profile handler registered for request path {}", getId(), requestPath);
124 * Gets the registered profile handlers.
126 * @return registered profile handlers
128 public Map<String, AbstractRequestURIMappedProfileHandler> getProfileHandlers() {
129 return profileHandlers;
133 * Gets the registered authentication handlers.
135 * @return registered authentication handlers
137 public Map<String, LoginHandler> getLoginHandlers() {
138 return loginHandlers;
142 protected void newContextCreated(ApplicationContext newServiceContext) {
143 log.debug("{}: Loading new configuration into service", getId());
144 Lock writeLock = getReadWriteLock().writeLock();
146 loadNewErrorHandler(newServiceContext);
147 loadNewProfileHandlers(newServiceContext);
148 loadNewAuthenticationHandlers(newServiceContext);
153 * Reads the new error handler from the newly created application context and loads it into this manager.
155 * @param newServiceContext newly created application context
157 protected void loadNewErrorHandler(ApplicationContext newServiceContext) {
158 String[] errorBeanNames = newServiceContext.getBeanNamesForType(AbstractErrorHandler.class);
159 log.debug("{}: Loading {} new error handler.", getId(), errorBeanNames.length);
161 errorHandler = (AbstractErrorHandler) newServiceContext.getBean(errorBeanNames[0]);
162 log.debug("{}: Loaded new error handler of type: {}", getId(), errorHandler.getClass().getName());
166 * Reads the new profile handlers from the newly created application context and loads it into this manager.
168 * @param newServiceContext newly created application context
170 protected void loadNewProfileHandlers(ApplicationContext newServiceContext) {
171 String[] profileBeanNames = newServiceContext.getBeanNamesForType(AbstractRequestURIMappedProfileHandler.class);
172 log.debug("{}: Loading {} new profile handlers.", getId(), profileBeanNames.length);
174 profileHandlers.clear();
175 AbstractRequestURIMappedProfileHandler<?, ?> profileHandler;
176 for (String profileBeanName : profileBeanNames) {
177 profileHandler = (AbstractRequestURIMappedProfileHandler) newServiceContext.getBean(profileBeanName);
178 for (String requestPath : profileHandler.getRequestPaths()) {
179 profileHandlers.put(requestPath, profileHandler);
180 log.debug("{}: Loaded profile handler for handling requests to request path {}", getId(), requestPath);
186 * Reads the new authentication handlers from the newly created application context and loads it into this manager.
188 * @param newServiceContext newly created application context
190 protected void loadNewAuthenticationHandlers(ApplicationContext newServiceContext) {
191 String[] authnBeanNames = newServiceContext.getBeanNamesForType(LoginHandler.class);
192 log.debug("{}: Loading {} new authentication handlers.", getId(), authnBeanNames.length);
194 loginHandlers.clear();
195 LoginHandler authnHandler;
196 for (String authnBeanName : authnBeanNames) {
197 authnHandler = (LoginHandler) newServiceContext.getBean(authnBeanName);
198 log.debug("{}: Loading authentication handler of type supporting authentication methods: {}", getId(),
199 authnHandler.getSupportedAuthenticationMethods());
201 for (String authnMethod : authnHandler.getSupportedAuthenticationMethods()) {
202 loginHandlers.put(authnMethod, authnHandler);