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