1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.idp.profile;
18
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.concurrent.locks.Lock;
22
23 import javax.servlet.ServletRequest;
24 import javax.servlet.http.HttpServletRequest;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.springframework.context.ApplicationContext;
29
30 import edu.internet2.middleware.shibboleth.common.config.BaseReloadableService;
31 import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
32 import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
33 import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
34 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractRequestURIMappedProfileHandler;
35 import edu.internet2.middleware.shibboleth.common.service.ServiceException;
36 import edu.internet2.middleware.shibboleth.idp.authn.LoginHandler;
37
38
39
40
41
42 public class IdPProfileHandlerManager extends BaseReloadableService implements ProfileHandlerManager {
43
44
45 private final Logger log = LoggerFactory.getLogger(IdPProfileHandlerManager.class);
46
47
48 private AbstractErrorHandler errorHandler;
49
50
51 private Map<String, AbstractRequestURIMappedProfileHandler> profileHandlers;
52
53
54 private Map<String, LoginHandler> loginHandlers;
55
56
57 public IdPProfileHandlerManager() {
58 super();
59 profileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
60 loginHandlers = new HashMap<String, LoginHandler>();
61 }
62
63
64 public AbstractErrorHandler getErrorHandler() {
65 return errorHandler;
66 }
67
68
69
70
71
72
73 public void setErrorHandler(AbstractErrorHandler handler) {
74 if (handler == null) {
75 throw new IllegalArgumentException("Error handler may not be null");
76 }
77 errorHandler = handler;
78 }
79
80
81 public ProfileHandler getProfileHandler(ServletRequest request) {
82 ProfileHandler handler;
83
84 String requestPath = ((HttpServletRequest) request).getPathInfo();
85 log.debug("{}: Looking up profile handler for request path: {}", getId(), requestPath);
86
87 Lock readLock = getReadWriteLock().readLock();
88 readLock.lock();
89 try{
90 handler = profileHandlers.get(requestPath);
91 }finally{
92 readLock.unlock();
93 }
94
95 if (handler != null) {
96 log.debug("{}: Located profile handler of the following type for the request path: {}", getId(), handler
97 .getClass().getName());
98 } else {
99 log.debug("{}: No profile handler registered for request path {}", getId(), requestPath);
100 }
101 return handler;
102 }
103
104
105
106
107
108
109 public Map<String, AbstractRequestURIMappedProfileHandler> getProfileHandlers() {
110 return profileHandlers;
111 }
112
113
114
115
116
117
118 public Map<String, LoginHandler> getLoginHandlers() {
119 return loginHandlers;
120 }
121
122
123 protected void onNewContextCreated(ApplicationContext newServiceContext) throws ServiceException {
124 log.debug("{}: Loading new configuration into service", getId());
125 AbstractErrorHandler oldErrorHandler = errorHandler;
126 Map<String, AbstractRequestURIMappedProfileHandler> oldProfileHandlers = profileHandlers;
127 Map<String, LoginHandler> oldLoginHandlers = loginHandlers;
128
129 try {
130 loadNewErrorHandler(newServiceContext);
131 loadNewProfileHandlers(newServiceContext);
132 loadNewLoginHandlers(newServiceContext);
133 } catch (Exception e) {
134 errorHandler = oldErrorHandler;
135 profileHandlers = oldProfileHandlers;
136 loginHandlers = oldLoginHandlers;
137 throw new ServiceException(getId() + " configuration is not valid, retaining old configuration", e);
138 }
139 }
140
141
142
143
144
145
146 protected void loadNewErrorHandler(ApplicationContext newServiceContext) {
147 String[] errorBeanNames = newServiceContext.getBeanNamesForType(AbstractErrorHandler.class);
148 log.debug("{}: Loading {} new error handler.", getId(), errorBeanNames.length);
149
150 errorHandler = (AbstractErrorHandler) newServiceContext.getBean(errorBeanNames[0]);
151 log.debug("{}: Loaded new error handler of type: {}", getId(), errorHandler.getClass().getName());
152 }
153
154
155
156
157
158
159 protected void loadNewProfileHandlers(ApplicationContext newServiceContext) {
160 String[] profileBeanNames = newServiceContext.getBeanNamesForType(AbstractRequestURIMappedProfileHandler.class);
161 log.debug("{}: Loading {} new profile handlers.", getId(), profileBeanNames.length);
162
163 Map<String, AbstractRequestURIMappedProfileHandler> newProfileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
164 AbstractRequestURIMappedProfileHandler<?, ?> profileHandler;
165 for (String profileBeanName : profileBeanNames) {
166 profileHandler = (AbstractRequestURIMappedProfileHandler) newServiceContext.getBean(profileBeanName);
167 for (String requestPath : profileHandler.getRequestPaths()) {
168 newProfileHandlers.put(requestPath, profileHandler);
169 log.debug("{}: Loaded profile handler for handling requests to request path {}", getId(), requestPath);
170 }
171 }
172 profileHandlers = newProfileHandlers;
173 }
174
175
176
177
178
179
180 protected void loadNewLoginHandlers(ApplicationContext newServiceContext) {
181 String[] authnBeanNames = newServiceContext.getBeanNamesForType(LoginHandler.class);
182 log.debug("{}: Loading {} new authentication handlers.", getId(), authnBeanNames.length);
183
184 Map<String, LoginHandler> newLoginHandlers = new HashMap<String, LoginHandler>();
185 LoginHandler authnHandler;
186 for (String authnBeanName : authnBeanNames) {
187 authnHandler = (LoginHandler) newServiceContext.getBean(authnBeanName);
188 log.debug("{}: Loading authentication handler of type supporting authentication methods: {}", getId(),
189 authnHandler.getSupportedAuthenticationMethods());
190
191 for (String authnMethod : authnHandler.getSupportedAuthenticationMethods()) {
192 newLoginHandlers.put(authnMethod, authnHandler);
193 }
194 }
195 loginHandlers = newLoginHandlers;
196 }
197 }