From ca19e1aeccc299295d581aab6e9f409f85c248c2 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Jun 2010 23:47:21 +0200 Subject: import 1.1. --- .../shibboleth/wayf/DiscoveryServiceHandler.html | 1909 ++++++++++---------- 1 file changed, 955 insertions(+), 954 deletions(-) (limited to 'doc/src-xref/edu/internet2/middleware/shibboleth/wayf/DiscoveryServiceHandler.html') diff --git a/doc/src-xref/edu/internet2/middleware/shibboleth/wayf/DiscoveryServiceHandler.html b/doc/src-xref/edu/internet2/middleware/shibboleth/wayf/DiscoveryServiceHandler.html index 9f4e4ed..a9e9e2f 100644 --- a/doc/src-xref/edu/internet2/middleware/shibboleth/wayf/DiscoveryServiceHandler.html +++ b/doc/src-xref/edu/internet2/middleware/shibboleth/wayf/DiscoveryServiceHandler.html @@ -52,964 +52,965 @@ 42 import org.opensaml.saml2.metadata.EntityDescriptor; 43 import org.opensaml.saml2.metadata.RoleDescriptor; 44 import org.opensaml.saml2.metadata.SPSSODescriptor; -45 import org.opensaml.xml.XMLObject; -46 import org.slf4j.Logger; -47 import org.slf4j.LoggerFactory; -48 import org.w3c.dom.Element; -49 import org.w3c.dom.NodeList; -50 -51 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException; -52 import edu.internet2.middleware.shibboleth.wayf.plugins.Plugin; -53 import edu.internet2.middleware.shibboleth.wayf.plugins.PluginContext; -54 import edu.internet2.middleware.shibboleth.wayf.plugins.PluginMetadataParameter; -55 import edu.internet2.middleware.shibboleth.wayf.plugins.WayfRequestHandled; -56 -57 /** -58 * Specific handler for each version of the Discovery Service. -59 */ -60 public class DiscoveryServiceHandler { -61 -62 /* -63 * Protcol parameters - Old. -64 */ -65 /** -66 * Shire is the SP Assertion Consumer endpoint. -67 */ -68 private static final String SHIRE_PARAM_NAME = "shire"; -69 /** -70 * TargetName is where we are trying to get to. -71 */ -72 private static final String TARGET_PARAM_NAME = "target"; -73 /** -74 * time is to do with replay attack. -75 */ -76 private static final String TIME_PARAM_NAME = "time"; -77 /** -78 * This is the ID (in the metadata) of the SP. -79 */ -80 private static final String PROVIDERID_PARAM_NAME = "providerId"; -81 -82 /* -83 * Protocol parameters - New -84 */ -85 /** -86 * The SP id. -87 */ -88 private static final String ENTITYID_PARAM_NAME = "entityID"; -89 /** -90 * Where to send the request back to. -91 */ -92 private static final String RETURN_PARAM_NAME = "return"; -93 /** -94 * "return" is an invalid attribute, so we use returnX. -95 */ -96 private static final String RETURN_ATTRIBUTE_NAME = "returnX"; -97 /** -98 * Alternatively the index of where to send the address back to. -99 */ -100 private static final String RETURN_INDEX_NAME = "returnIndex"; -101 -102 /** -103 * What value to put the ID of the selected metadata into. -104 */ -105 private static final String RETURNID_PARAM_NAME = "returnIDParam"; -106 -107 /** -108 * What returnIDParam defaults to. -109 */ -110 private static final String RETURNID_DEFAULT_VALUE = "entityID"; -111 /** -112 * Whether we are allowed to interact. -113 */ -114 private static final String ISPASSIVE_PARAM_NAME = "isPassive"; -115 -116 /** -117 * Whether we understand this or not. -118 */ -119 private static final String POLICY_PARAM_NAME = "policy"; -120 -121 /** -122 * The only policy we know about. -123 */ -124 private static final String KNOWN_POLICY_NAME -125 = "urn:oasis:names:tc:SAML:profiles:SSO:idp-discoveryprotocol:single"; -126 -127 /** -128 * Mandatory Serialization constant. -129 */ -130 private static final Logger LOG = LoggerFactory.getLogger(DiscoveryServiceHandler.class.getName()); -131 -132 /** -133 * The location defines the last part of the URL which distinguished this handler. -134 */ -135 private final String location; -136 -137 /** -138 * If isDefault is true then if there is a mismatch then this handler is used. -139 */ -140 private final boolean isDefault; -141 -142 /** -143 * Config handles detailed behavior. -144 */ -145 private final HandlerConfig config; -146 -147 /** -148 * The list of all the metadata providers that this discovery handler believes in. -149 */ -150 private final List <IdPSiteSet> siteSets; -151 -152 /** -153 * The list of all the plugins that this hanlder has had configured. -154 */ -155 private final List <Plugin> plugins; -156 -157 /** -158 * Constructor to create and configure the handler. -159 * @param config - DOM Element with configuration information. -160 * @param federations - Supplies all known providers which will be included if so configured. -161 * @param plugins - Supplies all known plugins which will be included if configured in. -162 * @param defaultConfig - The default configurations. -163 * @throws ShibbolethConfigurationException - if we find something odd in the config file. -164 */ -165 protected DiscoveryServiceHandler(Element config, -166 Hashtable <String, IdPSiteSet> federations, -167 Hashtable <String, Plugin> plugins, -168 HandlerConfig defaultConfig) throws ShibbolethConfigurationException -169 { -170 siteSets = new ArrayList <IdPSiteSet>(federations.size()); -171 this.plugins = new ArrayList <Plugin>(plugins.size()); -172 -173 // -174 // Collect the Configuration from the XML -175 // -176 -177 this.config = new HandlerConfig(config, defaultConfig); -178 -179 location = config.getAttribute("location"); -180 -181 if (location == null || location.equals("")) { -182 -183 LOG.error("DiscoveryService must have a location specified"); -184 throw new ShibbolethConfigurationException("DiscoveryService must have a location specified"); -185 } -186 -187 // -188 // Is this the default WAYF? -189 // -190 -191 String attribute = config.getAttribute("default"); -192 if (attribute != null && !attribute.equals("")) { -193 isDefault = Boolean.valueOf(attribute).booleanValue(); -194 } else { -195 isDefault = true; -196 } -197 -198 // -199 // Which federations (sitesets) do we care about? -200 // -201 -202 NodeList list = config.getElementsByTagName("Federation"); -203 -204 for (int i = 0; i < list.getLength(); i++ ) { -205 -206 attribute = ((Element) list.item(i)).getAttribute("identifier"); -207 -208 IdPSiteSet siteset = federations.get(attribute); -209 -210 if (siteset == null) { -211 LOG.error("Handler " + location + ": could not find metadata for <Federation> with identifier " + attribute + "."); -212 throw new ShibbolethConfigurationException( -213 "Handler " + location + ": could not find metadata for <Federation> identifier " + attribute + "."); -214 } -215 -216 siteSets.add(siteset); -217 } -218 -219 if (siteSets.size() == 0) { -220 // -221 // No Federations explicitly named pick em all -222 // -223 siteSets.addAll(federations.values()); -224 } -225 -226 // -227 // Now, which plugins? -228 // -229 -230 list = config.getElementsByTagName("PluginInstance"); -231 -232 for (int i = 0; i < list.getLength(); i++ ) { -233 -234 attribute = ((Element) list.item(i)).getAttribute("identifier"); -235 -236 Plugin plugin = plugins.get(attribute); -237 -238 if (plugin == null) { -239 LOG.error("Handler " + location + ": could not find plugin for identifier " + attribute); -240 throw new ShibbolethConfigurationException( -241 "Handler " + location + ": could not find plugin for identifier " + attribute); -242 } -243 -244 this.plugins.add(plugin); -245 } -246 -247 // -248 // So now tell every IdPSite about every plugin. -249 // -250 // Note that there is only one idpsite per metadatafile per WAYF and that the discovery -251 // services share them, so the data explosion is only number(IdpSites) * number(Plugins) not -252 // number(IdpSites) * number(Plugins) * number(DiscoverHandlers) -253 -254 for (IdPSiteSet site: siteSets) { -255 for (Plugin plugin: this.plugins) { -256 site.addPlugin(plugin); -257 } -258 } -259 } -260 +45 import org.opensaml.samlext.idpdisco.DiscoveryResponse; +46 import org.opensaml.xml.XMLObject; +47 import org.slf4j.Logger; +48 import org.slf4j.LoggerFactory; +49 import org.w3c.dom.Element; +50 import org.w3c.dom.NodeList; +51 +52 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException; +53 import edu.internet2.middleware.shibboleth.wayf.plugins.Plugin; +54 import edu.internet2.middleware.shibboleth.wayf.plugins.PluginContext; +55 import edu.internet2.middleware.shibboleth.wayf.plugins.PluginMetadataParameter; +56 import edu.internet2.middleware.shibboleth.wayf.plugins.WayfRequestHandled; +57 +58 /** +59 * Specific handler for each version of the Discovery Service. +60 */ +61 public class DiscoveryServiceHandler { +62 +63 /* +64 * Protcol parameters - Old. +65 */ +66 /** +67 * Shire is the SP Assertion Consumer endpoint. +68 */ +69 private static final String SHIRE_PARAM_NAME = "shire"; +70 /** +71 * TargetName is where we are trying to get to. +72 */ +73 private static final String TARGET_PARAM_NAME = "target"; +74 /** +75 * time is to do with replay attack. +76 */ +77 private static final String TIME_PARAM_NAME = "time"; +78 /** +79 * This is the ID (in the metadata) of the SP. +80 */ +81 private static final String PROVIDERID_PARAM_NAME = "providerId"; +82 +83 /* +84 * Protocol parameters - New +85 */ +86 /** +87 * The SP id. +88 */ +89 private static final String ENTITYID_PARAM_NAME = "entityID"; +90 /** +91 * Where to send the request back to. +92 */ +93 private static final String RETURN_PARAM_NAME = "return"; +94 /** +95 * "return" is an invalid attribute, so we use returnX. +96 */ +97 private static final String RETURN_ATTRIBUTE_NAME = "returnX"; +98 /** +99 * Alternatively the index of where to send the address back to. +100 */ +101 private static final String RETURN_INDEX_NAME = "returnIndex"; +102 +103 /** +104 * What value to put the ID of the selected metadata into. +105 */ +106 private static final String RETURNID_PARAM_NAME = "returnIDParam"; +107 +108 /** +109 * What returnIDParam defaults to. +110 */ +111 private static final String RETURNID_DEFAULT_VALUE = "entityID"; +112 /** +113 * Whether we are allowed to interact. +114 */ +115 private static final String ISPASSIVE_PARAM_NAME = "isPassive"; +116 +117 /** +118 * Whether we understand this or not. +119 */ +120 private static final String POLICY_PARAM_NAME = "policy"; +121 +122 /** +123 * The only policy we know about. +124 */ +125 private static final String KNOWN_POLICY_NAME +126 = "urn:oasis:names:tc:SAML:profiles:SSO:idp-discoveryprotocol:single"; +127 +128 /** +129 * Mandatory Serialization constant. +130 */ +131 private static final Logger LOG = LoggerFactory.getLogger(DiscoveryServiceHandler.class.getName()); +132 +133 /** +134 * The location defines the last part of the URL which distinguished this handler. +135 */ +136 private final String location; +137 +138 /** +139 * If isDefault is true then if there is a mismatch then this handler is used. +140 */ +141 private final boolean isDefault; +142 +143 /** +144 * Config handles detailed behavior. +145 */ +146 private final HandlerConfig config; +147 +148 /** +149 * The list of all the metadata providers that this discovery handler believes in. +150 */ +151 private final List <IdPSiteSet> siteSets; +152 +153 /** +154 * The list of all the plugins that this hanlder has had configured. +155 */ +156 private final List <Plugin> plugins; +157 +158 /** +159 * Constructor to create and configure the handler. +160 * @param config - DOM Element with configuration information. +161 * @param federations - Supplies all known providers which will be included if so configured. +162 * @param plugins - Supplies all known plugins which will be included if configured in. +163 * @param defaultConfig - The default configurations. +164 * @throws ShibbolethConfigurationException - if we find something odd in the config file. +165 */ +166 protected DiscoveryServiceHandler(Element config, +167 Hashtable <String, IdPSiteSet> federations, +168 Hashtable <String, Plugin> plugins, +169 HandlerConfig defaultConfig) throws ShibbolethConfigurationException +170 { +171 siteSets = new ArrayList <IdPSiteSet>(federations.size()); +172 this.plugins = new ArrayList <Plugin>(plugins.size()); +173 +174 // +175 // Collect the Configuration from the XML +176 // +177 +178 this.config = new HandlerConfig(config, defaultConfig); +179 +180 location = config.getAttribute("location"); +181 +182 if (location == null || location.equals("")) { +183 +184 LOG.error("DiscoveryService must have a location specified"); +185 throw new ShibbolethConfigurationException("DiscoveryService must have a location specified"); +186 } +187 +188 // +189 // Is this the default WAYF? +190 // +191 +192 String attribute = config.getAttribute("default"); +193 if (attribute != null && !attribute.equals("")) { +194 isDefault = Boolean.valueOf(attribute).booleanValue(); +195 } else { +196 isDefault = false; +197 } +198 +199 // +200 // Which federations (sitesets) do we care about? +201 // +202 +203 NodeList list = config.getElementsByTagName("Federation"); +204 +205 for (int i = 0; i < list.getLength(); i++ ) { +206 +207 attribute = ((Element) list.item(i)).getAttribute("identifier"); +208 +209 IdPSiteSet siteset = federations.get(attribute); +210 +211 if (siteset == null) { +212 LOG.error("Handler " + location + ": could not find metadata for <Federation> with identifier " + attribute + "."); +213 throw new ShibbolethConfigurationException( +214 "Handler " + location + ": could not find metadata for <Federation> identifier " + attribute + "."); +215 } +216 +217 siteSets.add(siteset); +218 } +219 +220 if (siteSets.size() == 0) { +221 // +222 // No Federations explicitly named pick em all +223 // +224 siteSets.addAll(federations.values()); +225 } +226 +227 // +228 // Now, which plugins? +229 // +230 +231 list = config.getElementsByTagName("PluginInstance"); +232 +233 for (int i = 0; i < list.getLength(); i++ ) { +234 +235 attribute = ((Element) list.item(i)).getAttribute("identifier"); +236 +237 Plugin plugin = plugins.get(attribute); +238 +239 if (plugin == null) { +240 LOG.error("Handler " + location + ": could not find plugin for identifier " + attribute); +241 throw new ShibbolethConfigurationException( +242 "Handler " + location + ": could not find plugin for identifier " + attribute); +243 } +244 +245 this.plugins.add(plugin); +246 } +247 +248 // +249 // So now tell every IdPSite about every plugin. +250 // +251 // Note that there is only one idpsite per metadatafile per WAYF and that the discovery +252 // services share them, so the data explosion is only number(IdpSites) * number(Plugins) not +253 // number(IdpSites) * number(Plugins) * number(DiscoverHandlers) +254 +255 for (IdPSiteSet site: siteSets) { +256 for (Plugin plugin: this.plugins) { +257 site.addPlugin(plugin); +258 } +259 } +260 } 261 -262 // -263 // Standard Beany Methods -264 // -265 /** -266 * The 'Name' of the service. the path used to identify the ServiceHandler. -267 * @return the path used to identify the ServiceHandler. -268 */ -269 -270 protected String getLocation() { -271 return location; -272 } -273 -274 /** -275 * Whether this is the default service. -276 * @return is it? -277 */ -278 protected boolean isDefault() { -279 return isDefault; -280 } -281 -282 // -283 // Now the bits that deal with the user request -284 // -285 -286 public void doGet(HttpServletRequest req, HttpServletResponse res) { -287 -288 String policy = req.getParameter(POLICY_PARAM_NAME); -289 -290 if (null != policy && !KNOWN_POLICY_NAME.equals(policy)) { -291 // -292 // unknown policy -293 // -294 LOG.error("Unknown policy " + policy); -295 handleError(req, res, "Unknown policy " + policy); -296 return; -297 } -298 -299 // -300 // Decide how to route the request based on query string -301 // -302 String requestType = req.getParameter("action"); -303 -304 if (requestType == null || requestType.equals("")) { -305 requestType = "lookup"; -306 } -307 -308 try { -309 -310 if (requestType.equals("search")) { -311 -312 String parameter = req.getParameter("string"); -313 if (parameter != null && parameter.equals("")) { -314 parameter = null; -315 } -316 handleLookup(req, res, parameter); -317 -318 } else if (requestType.equals("selection")) { -319 -320 handleSelection(req, res); -321 } else { -322 handleLookup(req, res, null); -323 } -324 } catch (WayfException we) { -325 LOG.error("Error processing DS request:", we); -326 handleError(req, res, we.getLocalizedMessage()); -327 } catch (WayfRequestHandled we) { -328 // -329 // Yuck - a sucess path involving an exception -330 // -331 } -332 -333 } -334 -335 /** -336 * When the WAYF user has selected something we look it up, tell the plugins and then dispatch to the Idp. -337 * -338 * @param req - standard J2EE stuff -339 * @param res - standard J2EE stuff -340 * @throws WayfRequestHandled - if one of the plugins has done the dispatch -341 * @throws WayfException - if we had an errors -342 */ -343 private void handleSelection(HttpServletRequest req, -344 HttpServletResponse res) throws WayfRequestHandled, WayfException -345 { -346 -347 String idpName = req.getParameter("origin"); -348 LOG.debug("Processing handle selection: " + idpName); -349 -350 String sPName = getSPId(req); -351 -352 if (idpName == null || idpName.equals("")) { -353 handleLookup(req, res, null); -354 return; -355 } -356 -357 if (getValue(req, SHIRE_PARAM_NAME) == null) { -358 // -359 // 2.0 protocol -360 // -361 setupReturnAddress(sPName, req); -362 } -363 // -364 // Notify plugins -365 // -366 IdPSite site = null; -367 -368 for (Plugin plugin:plugins) { -369 for (IdPSiteSet idPSiteSet: siteSets) { -370 PluginMetadataParameter param = idPSiteSet.paramFor(plugin); -371 plugin.selected(req, res, param, idpName); -372 if (site == null && idPSiteSet.containsIdP(idpName)) { -373 site = idPSiteSet.getSite(idpName); -374 } -375 } -376 } -377 -378 if (site == null) { -379 handleLookup(req, res, null); -380 } else { -381 forwardRequest(req, res, site); -382 } -383 } -384 +262 +263 // +264 // Standard Beany Methods +265 // +266 /** +267 * The 'Name' of the service. the path used to identify the ServiceHandler. +268 * @return the path used to identify the ServiceHandler. +269 */ +270 +271 protected String getLocation() { +272 return location; +273 } +274 +275 /** +276 * Whether this is the default service. +277 * @return is it? +278 */ +279 protected boolean isDefault() { +280 return isDefault; +281 } +282 +283 // +284 // Now the bits that deal with the user request +285 // +286 +287 public void doGet(HttpServletRequest req, HttpServletResponse res) { +288 +289 String policy = req.getParameter(POLICY_PARAM_NAME); +290 +291 if (null != policy && !KNOWN_POLICY_NAME.equals(policy)) { +292 // +293 // unknown policy +294 // +295 LOG.error("Unknown policy " + policy); +296 handleError(req, res, "Unknown policy " + policy); +297 return; +298 } +299 +300 // +301 // Decide how to route the request based on query string +302 // +303 String requestType = req.getParameter("action"); +304 +305 if (requestType == null || requestType.equals("")) { +306 requestType = "lookup"; +307 } +308 +309 try { +310 +311 if (requestType.equals("search")) { +312 +313 String parameter = req.getParameter("string"); +314 if (parameter != null && parameter.equals("")) { +315 parameter = null; +316 } +317 handleLookup(req, res, parameter); +318 +319 } else if (requestType.equals("selection")) { +320 +321 handleSelection(req, res); +322 } else { +323 handleLookup(req, res, null); +324 } +325 } catch (WayfException we) { +326 LOG.error("Error processing DS request:", we); +327 handleError(req, res, we.getLocalizedMessage()); +328 } catch (WayfRequestHandled we) { +329 // +330 // Yuck - a sucess path involving an exception +331 // +332 } +333 +334 } +335 +336 /** +337 * When the WAYF user has selected something we look it up, tell the plugins and then dispatch to the Idp. +338 * +339 * @param req - standard J2EE stuff +340 * @param res - standard J2EE stuff +341 * @throws WayfRequestHandled - if one of the plugins has done the dispatch +342 * @throws WayfException - if we had an errors +343 */ +344 private void handleSelection(HttpServletRequest req, +345 HttpServletResponse res) throws WayfRequestHandled, WayfException +346 { +347 +348 String idpName = req.getParameter("origin"); +349 LOG.debug("Processing handle selection: " + idpName); +350 +351 String sPName = getSPId(req); +352 +353 if (idpName == null || idpName.equals("")) { +354 handleLookup(req, res, null); +355 return; +356 } +357 +358 if (getValue(req, SHIRE_PARAM_NAME) == null) { +359 // +360 // 2.0 protocol +361 // +362 setupReturnAddress(sPName, req); +363 } +364 // +365 // Notify plugins +366 // +367 IdPSite site = null; +368 +369 for (Plugin plugin:plugins) { +370 for (IdPSiteSet idPSiteSet: siteSets) { +371 PluginMetadataParameter param = idPSiteSet.paramFor(plugin); +372 plugin.selected(req, res, param, idpName); +373 if (site == null && idPSiteSet.containsIdP(idpName)) { +374 site = idPSiteSet.getSite(idpName); +375 } +376 } +377 } +378 +379 if (site == null) { +380 handleLookup(req, res, null); +381 } else { +382 forwardRequest(req, res, site); +383 } +384 } 385 -386 /** -387 * This sets up the parameter RETURN_ATTRIBUTE_NAME with the return address -388 * harvested from the reqest. -389 * <ul><le>If a "return" parameter is present we check in the metadata for spoofing -390 * and then set up from there </le> -391 * <le>If "returnID" is specified we get this from the metadata</le> -392 * <le>If nothing is provided we get the default from the metadata (if provided)</le> -393 * <le>Otherwise we whine</le> -394 * </ul> -395 * @param spName - the name of the Service provider. -396 * @param req - The request. -397 * @throws WayfException - if we spot spoofing or there is no defaumlt -398 */ -399 private void setupReturnAddress(String spName, HttpServletRequest req) throws WayfException{ -400 -401 DiscoveryResponseImpl[] discoveryServices; -402 Set<XMLObject> objects = new HashSet<XMLObject>(); -403 String defaultName = null; -404 -405 for (IdPSiteSet metadataProvider:siteSets) { -406 -407 // -408 // Only do work if the SP makes sense -409 // -410 -411 if (metadataProvider.containsSP(spName)) { -412 -413 // -414 // The name makes sense so let's get the entity and from that -415 // all of its roles -416 // -417 -418 EntityDescriptor entity = metadataProvider.getEntity(spName); -419 List<RoleDescriptor> roles = entity.getRoleDescriptors(); -420 -421 for (RoleDescriptor role:roles) { -422 -423 // -424 // Check every role -425 // -426 -427 if (role instanceof SPSSODescriptor) { -428 -429 // -430 // And grab hold of all the extensions for SPSSO descriptors -431 // -432 -433 Extensions exts = role.getExtensions(); -434 if (exts != null) { -435 objects.addAll(exts.getOrderedChildren()); -436 } -437 } -438 } -439 } -440 } -441 -442 // -443 // Now, let's strip out everything which isn't a DiscoveryService -444 // -445 -446 discoveryServices = new DiscoveryResponseImpl[objects.size()]; -447 int dsCount = 0; -448 -449 for (XMLObject obj:objects) { -450 if (obj instanceof DiscoveryResponseImpl) { -451 DiscoveryResponseImpl ds = (DiscoveryResponseImpl) obj; -452 discoveryServices[dsCount++] = ds; -453 if (ds.isDefault() || null == defaultName) { -454 defaultName = ds.getLocation(); -455 } -456 } -457 } -458 -459 // -460 // Now process the return parameters. The name is either a parameter -461 // called RETURN_PARAM_NAME or an attributes called RETURN_ATTRIBUTE_NAME -462 // -463 String returnName = req.getParameter(RETURN_PARAM_NAME); -464 -465 if (returnName == null || returnName.length() == 0) { -466 returnName = getValue(req, RETURN_ATTRIBUTE_NAME); -467 } -468 -469 // -470 // Return index is only ever a parameter -471 // -472 -473 String returnIndex = req.getParameter(RETURN_INDEX_NAME); -474 -475 if (returnName != null && returnName.length() != 0) { -476 // -477 // Given something so we have to police it. -478 // -479 String nameNoParam = returnName; -480 URL providedReturnURL; -481 int index = nameNoParam.indexOf('?'); -482 boolean found = false; -483 -484 if (index >= 0) { -485 nameNoParam = nameNoParam.substring(0,index); -486 } -487 -488 try { -489 providedReturnURL = new URL(nameNoParam); -490 } catch (MalformedURLException e) { -491 throw new WayfException("Couldn't parse provided return name " + nameNoParam, e); -492 } -493 +386 +387 /** +388 * This sets up the parameter RETURN_ATTRIBUTE_NAME with the return address +389 * harvested from the reqest. +390 * <ul><le>If a "return" parameter is present we check in the metadata for spoofing +391 * and then set up from there </le> +392 * <le>If "returnID" is specified we get this from the metadata</le> +393 * <le>If nothing is provided we get the default from the metadata (if provided)</le> +394 * <le>Otherwise we whine</le> +395 * </ul> +396 * @param spName - the name of the Service provider. +397 * @param req - The request. +398 * @throws WayfException - if we spot spoofing or there is no defaumlt +399 */ +400 private void setupReturnAddress(String spName, HttpServletRequest req) throws WayfException{ +401 +402 DiscoveryResponse[] discoveryServices; +403 Set<XMLObject> objects = new HashSet<XMLObject>(); +404 String defaultName = null; +405 +406 for (IdPSiteSet metadataProvider:siteSets) { +407 +408 // +409 // Only do work if the SP makes sense +410 // +411 +412 if (metadataProvider.containsSP(spName)) { +413 +414 // +415 // The name makes sense so let's get the entity and from that +416 // all of its roles +417 // +418 +419 EntityDescriptor entity = metadataProvider.getEntity(spName); +420 List<RoleDescriptor> roles = entity.getRoleDescriptors(); +421 +422 for (RoleDescriptor role:roles) { +423 +424 // +425 // Check every role +426 // +427 +428 if (role instanceof SPSSODescriptor) { +429 +430 // +431 // And grab hold of all the extensions for SPSSO descriptors +432 // +433 +434 Extensions exts = role.getExtensions(); +435 if (exts != null) { +436 objects.addAll(exts.getOrderedChildren()); +437 } +438 } +439 } +440 } +441 } +442 +443 // +444 // Now, let's strip out everything which isn't a DiscoveryService +445 // +446 +447 discoveryServices = new DiscoveryResponse[objects.size()]; +448 int dsCount = 0; +449 +450 for (XMLObject obj:objects) { +451 if (obj instanceof DiscoveryResponse) { +452 DiscoveryResponse ds = (DiscoveryResponse) obj; +453 discoveryServices[dsCount++] = ds; +454 if (ds.isDefault() || null == defaultName) { +455 defaultName = ds.getLocation(); +456 } +457 } +458 } +459 +460 // +461 // Now process the return parameters. The name is either a parameter +462 // called RETURN_PARAM_NAME or an attributes called RETURN_ATTRIBUTE_NAME +463 // +464 String returnName = req.getParameter(RETURN_PARAM_NAME); +465 +466 if (returnName == null || returnName.length() == 0) { +467 returnName = getValue(req, RETURN_ATTRIBUTE_NAME); +468 } +469 +470 // +471 // Return index is only ever a parameter +472 // +473 +474 String returnIndex = req.getParameter(RETURN_INDEX_NAME); +475 +476 if (returnName != null && returnName.length() != 0) { +477 // +478 // Given something so we have to police it. +479 // +480 String nameNoParam = returnName; +481 URL providedReturnURL; +482 int index = nameNoParam.indexOf('?'); +483 boolean found = false; +484 +485 if (index >= 0) { +486 nameNoParam = nameNoParam.substring(0,index); +487 } +488 +489 try { +490 providedReturnURL = new URL(nameNoParam); +491 } catch (MalformedURLException e) { +492 throw new WayfException("Couldn't parse provided return name " + nameNoParam, e); +493 } 494 -495 for (DiscoveryResponseImpl disc: discoveryServices) { -496 if (equalsURL(disc, providedReturnURL)) { -497 found = true; -498 break; -499 } -500 } -501 if (!found) { -502 throw new WayfException("Couldn't find endpoint " + nameNoParam + " in metadata"); -503 } -504 } else if (returnIndex != null && returnIndex.length() != 0) { -505 -506 int index; -507 try { -508 index = Integer.parseInt(returnIndex); -509 } catch (NumberFormatException e) { -510 throw new WayfException("Couldn't convert " + returnIndex + " into an index"); -511 } -512 // -513 // So look throught to find the endpoint with the correct index -514 // -515 -516 boolean found = false; -517 -518 for (DiscoveryResponseImpl disc: discoveryServices) { -519 if (index == disc.getIndex()) { -520 found = true; -521 returnName = disc.getLocation(); -522 break; -523 } -524 } -525 if (!found) { -526 throw new WayfException("Couldn't not find endpoint " + returnIndex + "in metadata"); -527 } -528 } else { -529 // -530 // No name, not index, so we want the default -531 // -532 returnName = defaultName; -533 } -534 // -535 // So by now returnName has the correct value, either harvested from or -536 // policed against the metadata -537 // -538 req.setAttribute(RETURN_ATTRIBUTE_NAME, returnName); -539 } -540 -541 /** -542 * Helper function to see whather the provided endpoint in the metadata matches the -543 * provided return URL in the request. -544 * -545 * @param discovery -546 * @param providedName -547 * @return -548 */ -549 private static boolean equalsURL(DiscoveryResponseImpl discovery, URL providedName) { -550 -551 // -552 // Nothing provided - no match -553 // -554 if (null == discovery) { -555 return false; -556 } -557 -558 URL discoveryName; -559 try { -560 discoveryName = new URL(discovery.getLocation()); -561 } catch (MalformedURLException e) { -562 // -563 // Something bad happened. Log it (it is only of interest to the sysadmin, not to the user) -564 // -565 LOG.warn("Found invalid discovery end point : " + discovery.getLocation(), e); -566 return false; -567 } -568 -569 return providedName.equals(discoveryName); -570 -571 } -572 -573 /** -574 * Displays a Discovery Service selection page, having first consulted the plugins as needed. -575 * @param req Describes the request -576 * @param res Describes the response -577 * @param searchName What are we looking for? -578 * -579 * @throws WayfRequestHandled if a plugin has dealt with the request -580 * @throws WayfException in case of an error. -581 */ -582 private void handleLookup(HttpServletRequest req, -583 HttpServletResponse res, -584 String searchName) throws WayfException, WayfRequestHandled { -585 -586 String shire = getValue(req, SHIRE_PARAM_NAME); -587 String providerId = getSPId(req); -588 boolean twoZeroProtocol = (shire == null); -589 boolean isPassive = (twoZeroProtocol && -590 "true".equalsIgnoreCase(getValue(req, ISPASSIVE_PARAM_NAME))); -591 -592 Collection <IdPSiteSetEntry> siteLists = null; -593 Collection<IdPSite> searchResults = null; -594 -595 if (config.getProvideListOfLists()) { -596 siteLists = new ArrayList <IdPSiteSetEntry>(siteSets.size()); -597 } -598 -599 Collection <IdPSite> sites = null; -600 Comparator<IdPSite> comparator = new IdPSite.Compare(req); -601 -602 if (config.getProvideList()) { -603 sites = new TreeSet<IdPSite>(comparator); -604 } -605 -606 if (searchName != null && !searchName.equals("")) { -607 searchResults = new TreeSet<IdPSite>(comparator); -608 } -609 -610 LOG.debug("Processing Idp Lookup for : " + providerId); -611 -612 // -613 // Iterate over all the sitesets and if they know about the SP pass them to the plugins -614 // and then add them too the list -615 // -616 -617 PluginContext[] ctx = new PluginContext[plugins.size()]; -618 List<IdPSite> hintList = new ArrayList<IdPSite>(); -619 -620 if (twoZeroProtocol) { -621 setupReturnAddress(providerId, req); -622 } -623 // -624 // By having siteLists and sites as parameters we only iterate over -625 // the metadata arrays once. -626 // -627 try { -628 for (IdPSiteSet metadataProvider:siteSets) { -629 -630 // -631 // Only do work if the SP makes sense -632 // -633 -634 if (metadataProvider.containsSP(providerId) || !config.getLookupSp()) { -635 -636 Collection <IdPSite> search = null; -637 -638 if (searchResults != null) { -639 search = new TreeSet<IdPSite>(comparator); -640 } -641 -642 Map <String, IdPSite> theseSites = metadataProvider.getIdPSites(searchName, config, search); -643 -644 // -645 // Consult the plugins -646 // -647 for (int i = 0; i < plugins.size(); i++) { -648 -649 Plugin plugin = plugins.get(i); -650 -651 if (searchResults == null) { -652 // -653 // This was a search -654 // -655 ctx[i] = plugin.lookup(req, -656 res, -657 metadataProvider.paramFor(plugin), -658 theseSites, -659 ctx[i], -660 hintList); -661 } else { -662 ctx[i] = plugin.search(req, -663 res, -664 metadataProvider.paramFor(plugin), -665 searchName, -666 theseSites, -667 ctx[i], -668 searchResults, -669 hintList); -670 } -671 } -672 -673 if (null == theseSites || theseSites.isEmpty()) { -674 continue; -675 } -676 -677 // -678 -679 // Accumulate any per-metadata provider information -680 // -681 -682 Collection<IdPSite> values = new TreeSet<IdPSite>(comparator); -683 if (null != theseSites) { -684 values.addAll(theseSites.values()); -685 } -686 -687 if (siteLists != null) { -688 siteLists.add(new IdPSiteSetEntry(metadataProvider,values)); -689 } -690 -691 if (sites != null) { -692 sites.addAll(values); -693 } -694 -695 if (searchResults != null) { -696 searchResults.addAll(search); -697 } -698 } -699 } -700 -701 if (isPassive) { -702 // -703 // No GUI intervention. -704 // -705 if (0 != hintList.size()) { -706 // -707 // We found a candidate, hand it back -708 // -709 forwardRequest(req, res, hintList.get(0)); -710 } else { -711 forwardRequest(req, res, null); -712 } -713 return; -714 } -715 -716 // -717 // Now set up all the funky stuff that the JSP needs. Firstly the protocol -718 // specific parameters which will come back to us -719 // -720 -721 if (twoZeroProtocol) { -722 // -723 // The return address was set up in setupReturnAddress -724 // -725 String returnString = (String) req.getAttribute(RETURN_ATTRIBUTE_NAME); -726 if (null == returnString || 0 == returnString.length()) { -727 throw new WayfException("Parameter " + RETURN_PARAM_NAME + " not supplied"); -728 } -729 -730 String returnId = getValue(req, RETURNID_PARAM_NAME); -731 if (null == returnId || 0 == returnId.length()) { -732 returnId = RETURNID_DEFAULT_VALUE; -733 } -734 // -735 // Return *means* something so we cannot use it as an attribute -736 // -737 req.setAttribute(RETURN_ATTRIBUTE_NAME, returnString); -738 req.setAttribute(RETURNID_PARAM_NAME, returnId); -739 req.setAttribute(ENTITYID_PARAM_NAME, providerId); -740 -741 } else { -742 String target = getValue(req, TARGET_PARAM_NAME); -743 if (null == target || 0 == target.length()) { -744 throw new WayfException("Could not extract target from provided parameters"); -745 } -746 req.setAttribute(SHIRE_PARAM_NAME, shire); -747 req.setAttribute(TARGET_PARAM_NAME, target); -748 req.setAttribute(PROVIDERID_PARAM_NAME, providerId); -749 // -750 // Time is in unix format -751 // -752 req.setAttribute("time", new Long(new Date().getTime() / 1000).toString()); -753 -754 } -755 -756 // -757 // Setup the stuff that the GUI wants. -758 // -759 -760 setDisplayLanguage(sites, req); -761 req.setAttribute("sites", sites); -762 if (null != siteLists) { -763 for (IdPSiteSetEntry siteSetEntry:siteLists) { -764 setDisplayLanguage(siteSetEntry.getSites(), req); -765 } -766 } -767 -768 req.setAttribute("siteLists", siteLists); -769 req.setAttribute("requestURL", req.getRequestURI().toString()); -770 -771 if (searchResults != null) { -772 if (searchResults.size() != 0) { -773 setDisplayLanguage(searchResults, req); -774 req.setAttribute("searchresults", searchResults); -775 } else { -776 req.setAttribute("searchResultsEmpty", "true"); -777 } -778 } -779 -780 if (hintList.size() > 0) { -781 setDisplayLanguage(hintList, req); -782 req.setAttribute("cookieList", hintList); -783 } -784 -785 LOG.debug("Displaying WAYF selection page."); -786 RequestDispatcher rd = req.getRequestDispatcher(config.getJspFile()); -787 -788 // -789 // And off to the jsp -790 // -791 rd.forward(req, res); -792 } catch (IOException ioe) { -793 LOG.error("Problem displaying WAYF UI.\n" + ioe.getMessage()); -794 throw new WayfException("Problem displaying WAYF UI", ioe); -795 } catch (ServletException se) { -796 LOG.error("Problem displaying WAYF UI.\n" + se.getMessage()); -797 throw new WayfException("Problem displaying WAYF UI", se); -798 } -799 } -800 -801 /** -802 * Prior to display we set the display language from the -803 * browser. There is probably a proper way to do this using -804 * jsp, but I want to keep the API between JSP and java the same 1.3->2.0 -805 * @param sites - the sites we need to impact -806 * @param req - from whiuch we get the locale -807 */ -808 private void setDisplayLanguage(Collection<IdPSite> sites, HttpServletRequest req) { -809 -810 if (null == sites) { -811 return; -812 } -813 Locale locale = req.getLocale(); -814 if (null == locale) { -815 Locale.getDefault(); -816 } -817 String lang = locale.getLanguage(); -818 -819 for (IdPSite site : sites) { -820 site.setDisplayLanguage(lang); -821 } -822 } -823 +495 +496 for (DiscoveryResponse disc: discoveryServices) { +497 if (equalsURL(disc, providedReturnURL)) { +498 found = true; +499 break; +500 } +501 } +502 if (!found) { +503 throw new WayfException("Couldn't find endpoint " + nameNoParam + " in metadata"); +504 } +505 } else if (returnIndex != null && returnIndex.length() != 0) { +506 +507 int index; +508 try { +509 index = Integer.parseInt(returnIndex); +510 } catch (NumberFormatException e) { +511 throw new WayfException("Couldn't convert " + returnIndex + " into an index"); +512 } +513 // +514 // So look throught to find the endpoint with the correct index +515 // +516 +517 boolean found = false; +518 +519 for (DiscoveryResponse disc: discoveryServices) { +520 if (index == disc.getIndex()) { +521 found = true; +522 returnName = disc.getLocation(); +523 break; +524 } +525 } +526 if (!found) { +527 throw new WayfException("Couldn't not find endpoint " + returnIndex + "in metadata"); +528 } +529 } else { +530 // +531 // No name, not index, so we want the default +532 // +533 returnName = defaultName; +534 } +535 // +536 // So by now returnName has the correct value, either harvested from or +537 // policed against the metadata +538 // +539 req.setAttribute(RETURN_ATTRIBUTE_NAME, returnName); +540 } +541 +542 /** +543 * Helper function to see whather the provided endpoint in the metadata matches the +544 * provided return URL in the request. +545 * +546 * @param discovery +547 * @param providedName +548 * @return +549 */ +550 private static boolean equalsURL(DiscoveryResponse discovery, URL providedName) { +551 +552 // +553 // Nothing provided - no match +554 // +555 if (null == discovery) { +556 return false; +557 } +558 +559 URL discoveryName; +560 try { +561 discoveryName = new URL(discovery.getLocation()); +562 } catch (MalformedURLException e) { +563 // +564 // Something bad happened. Log it (it is only of interest to the sysadmin, not to the user) +565 // +566 LOG.warn("Found invalid discovery end point : " + discovery.getLocation(), e); +567 return false; +568 } +569 +570 return providedName.equals(discoveryName); +571 +572 } +573 +574 /** +575 * Displays a Discovery Service selection page, having first consulted the plugins as needed. +576 * @param req Describes the request +577 * @param res Describes the response +578 * @param searchName What are we looking for? +579 * +580 * @throws WayfRequestHandled if a plugin has dealt with the request +581 * @throws WayfException in case of an error. +582 */ +583 private void handleLookup(HttpServletRequest req, +584 HttpServletResponse res, +585 String searchName) throws WayfException, WayfRequestHandled { +586 +587 String shire = getValue(req, SHIRE_PARAM_NAME); +588 String providerId = getSPId(req); +589 boolean twoZeroProtocol = (shire == null); +590 boolean isPassive = (twoZeroProtocol && +591 "true".equalsIgnoreCase(getValue(req, ISPASSIVE_PARAM_NAME))); +592 +593 Collection <IdPSiteSetEntry> siteLists = null; +594 Collection<IdPSite> searchResults = null; +595 +596 if (config.getProvideListOfLists()) { +597 siteLists = new ArrayList <IdPSiteSetEntry>(siteSets.size()); +598 } +599 +600 Collection <IdPSite> sites = null; +601 Comparator<IdPSite> comparator = new IdPSite.Compare(req); +602 +603 if (config.getProvideList()) { +604 sites = new TreeSet<IdPSite>(comparator); +605 } +606 +607 if (searchName != null && !searchName.equals("")) { +608 searchResults = new TreeSet<IdPSite>(comparator); +609 } +610 +611 LOG.debug("Processing Idp Lookup for : " + providerId); +612 +613 // +614 // Iterate over all the sitesets and if they know about the SP pass them to the plugins +615 // and then add them too the list +616 // +617 +618 PluginContext[] ctx = new PluginContext[plugins.size()]; +619 List<IdPSite> hintList = new ArrayList<IdPSite>(); +620 +621 if (twoZeroProtocol) { +622 setupReturnAddress(providerId, req); +623 } +624 // +625 // By having siteLists and sites as parameters we only iterate over +626 // the metadata arrays once. +627 // +628 try { +629 for (IdPSiteSet metadataProvider:siteSets) { +630 +631 // +632 // Only do work if the SP makes sense +633 // +634 +635 if (metadataProvider.containsSP(providerId) || !config.getLookupSp()) { +636 +637 Collection <IdPSite> search = null; +638 +639 if (searchResults != null) { +640 search = new TreeSet<IdPSite>(comparator); +641 } +642 +643 Map <String, IdPSite> theseSites = metadataProvider.getIdPSites(searchName, config, search); +644 +645 // +646 // Consult the plugins +647 // +648 for (int i = 0; i < plugins.size(); i++) { +649 +650 Plugin plugin = plugins.get(i); +651 +652 if (searchResults == null) { +653 // +654 // This was a search +655 // +656 ctx[i] = plugin.lookup(req, +657 res, +658 metadataProvider.paramFor(plugin), +659 theseSites, +660 ctx[i], +661 hintList); +662 } else { +663 ctx[i] = plugin.search(req, +664 res, +665 metadataProvider.paramFor(plugin), +666 searchName, +667 theseSites, +668 ctx[i], +669 searchResults, +670 hintList); +671 } +672 } +673 +674 if (null == theseSites || theseSites.isEmpty()) { +675 continue; +676 } +677 +678 // +679 +680 // Accumulate any per-metadata provider information +681 // +682 +683 Collection<IdPSite> values = new TreeSet<IdPSite>(comparator); +684 if (null != theseSites) { +685 values.addAll(theseSites.values()); +686 } +687 +688 if (siteLists != null) { +689 siteLists.add(new IdPSiteSetEntry(metadataProvider,values)); +690 } +691 +692 if (sites != null) { +693 sites.addAll(values); +694 } +695 +696 if (searchResults != null) { +697 searchResults.addAll(search); +698 } +699 } +700 } +701 +702 if (isPassive) { +703 // +704 // No GUI intervention. +705 // +706 if (0 != hintList.size()) { +707 // +708 // We found a candidate, hand it back +709 // +710 forwardRequest(req, res, hintList.get(0)); +711 } else { +712 forwardRequest(req, res, null); +713 } +714 return; +715 } +716 +717 // +718 // Now set up all the funky stuff that the JSP needs. Firstly the protocol +719 // specific parameters which will come back to us +720 // +721 +722 if (twoZeroProtocol) { +723 // +724 // The return address was set up in setupReturnAddress +725 // +726 String returnString = (String) req.getAttribute(RETURN_ATTRIBUTE_NAME); +727 if (null == returnString || 0 == returnString.length()) { +728 throw new WayfException("Parameter " + RETURN_PARAM_NAME + " not supplied"); +729 } +730 +731 String returnId = getValue(req, RETURNID_PARAM_NAME); +732 if (null == returnId || 0 == returnId.length()) { +733 returnId = RETURNID_DEFAULT_VALUE; +734 } +735 // +736 // Return *means* something so we cannot use it as an attribute +737 // +738 req.setAttribute(RETURN_ATTRIBUTE_NAME, returnString); +739 req.setAttribute(RETURNID_PARAM_NAME, returnId); +740 req.setAttribute(ENTITYID_PARAM_NAME, providerId); +741 +742 } else { +743 String target = getValue(req, TARGET_PARAM_NAME); +744 if (null == target || 0 == target.length()) { +745 throw new WayfException("Could not extract target from provided parameters"); +746 } +747 req.setAttribute(SHIRE_PARAM_NAME, shire); +748 req.setAttribute(TARGET_PARAM_NAME, target); +749 req.setAttribute(PROVIDERID_PARAM_NAME, providerId); +750 // +751 // Time is in unix format +752 // +753 req.setAttribute("time", new Long(new Date().getTime() / 1000).toString()); +754 +755 } +756 +757 // +758 // Setup the stuff that the GUI wants. +759 // +760 +761 setDisplayLanguage(sites, req); +762 req.setAttribute("sites", sites); +763 if (null != siteLists) { +764 for (IdPSiteSetEntry siteSetEntry:siteLists) { +765 setDisplayLanguage(siteSetEntry.getSites(), req); +766 } +767 } +768 +769 req.setAttribute("siteLists", siteLists); +770 req.setAttribute("requestURL", req.getRequestURI().toString()); +771 +772 if (searchResults != null) { +773 if (searchResults.size() != 0) { +774 setDisplayLanguage(searchResults, req); +775 req.setAttribute("searchresults", searchResults); +776 } else { +777 req.setAttribute("searchResultsEmpty", "true"); +778 } +779 } +780 +781 if (hintList.size() > 0) { +782 setDisplayLanguage(hintList, req); +783 req.setAttribute("cookieList", hintList); +784 } +785 +786 LOG.debug("Displaying WAYF selection page."); +787 RequestDispatcher rd = req.getRequestDispatcher(config.getJspFile()); +788 +789 // +790 // And off to the jsp +791 // +792 rd.forward(req, res); +793 } catch (IOException ioe) { +794 LOG.error("Problem displaying WAYF UI.\n" + ioe.getMessage()); +795 throw new WayfException("Problem displaying WAYF UI", ioe); +796 } catch (ServletException se) { +797 LOG.error("Problem displaying WAYF UI.\n" + se.getMessage()); +798 throw new WayfException("Problem displaying WAYF UI", se); +799 } +800 } +801 +802 /** +803 * Prior to display we set the display language from the +804 * browser. There is probably a proper way to do this using +805 * jsp, but I want to keep the API between JSP and java the same 1.3->2.0 +806 * @param sites - the sites we need to impact +807 * @param req - from whiuch we get the locale +808 */ +809 private void setDisplayLanguage(Collection<IdPSite> sites, HttpServletRequest req) { +810 +811 if (null == sites) { +812 return; +813 } +814 Locale locale = req.getLocale(); +815 if (null == locale) { +816 Locale.getDefault(); +817 } +818 String lang = locale.getLanguage(); +819 +820 for (IdPSite site : sites) { +821 site.setDisplayLanguage(lang); +822 } +823 } 824 -825 /** -826 * Uses an HTTP Status 307 redirect to forward the user to the IdP or the SP. -827 * -828 * @param req request under consideration -829 * @param res response under construction -830 * @param site The Idp -831 * @throws WayfException if bad things happen. -832 */ -833 public static void forwardRequest(HttpServletRequest req, HttpServletResponse res, IdPSite site) -834 throws WayfException { -835 -836 String shire = getValue(req, SHIRE_PARAM_NAME); -837 String providerId = getSPId(req); -838 boolean twoZeroProtocol = (shire == null); -839 -840 if (!twoZeroProtocol) { -841 String handleService = site.getAddressForWAYF(); -842 if (handleService != null ) { -843 -844 String target = getValue(req, TARGET_PARAM_NAME); -845 if (null == target || 0 == target.length()) { -846 throw new WayfException("Could not extract target from provided parameters"); -847 } -848 -849 LOG.info("Redirecting to selected Handle Service: " + handleService); -850 try { -851 StringBuffer buffer = new StringBuffer(handleService + -852 "?" + TARGET_PARAM_NAME + "="); -853 buffer.append(URLEncoder.encode(target, "UTF-8")); -854 buffer.append("&" + SHIRE_PARAM_NAME + "="); -855 buffer.append(URLEncoder.encode(shire, "UTF-8")); -856 buffer.append("&" + PROVIDERID_PARAM_NAME + "="); -857 buffer.append(URLEncoder.encode(providerId, "UTF-8")); -858 -859 // -860 // Time is as per U**X -861 // -862 buffer.append("&" + TIME_PARAM_NAME + "="); -863 buffer.append(new Long(new Date().getTime() / 1000).toString()); -864 res.sendRedirect(buffer.toString()); -865 } catch (IOException ioe) { -866 // -867 // That failed. -868 // -869 throw new WayfException("Error forwarding to IdP: \n" + ioe.getMessage()); -870 } -871 } else { -872 String s = "Error finding to IdP: " + site.getDisplayName(req); -873 LOG.error(s); -874 throw new WayfException(s); -875 } -876 } else { -877 String returnUrl = (String) req.getAttribute(RETURN_ATTRIBUTE_NAME); -878 -879 if (null == returnUrl || 0 == returnUrl.length()) { -880 throw new WayfException("Could not find return parameter"); -881 } -882 try { -883 returnUrl = URLDecoder.decode(returnUrl, "UTF-8"); -884 } catch (UnsupportedEncodingException e) { -885 throw new WayfException("Did not understand parameter ", e); -886 } -887 String redirect; -888 if (site != null) { -889 StringBuffer buffer = new StringBuffer(returnUrl); -890 // -891 // If we were given anybody to lookup, construct the URL -892 // -893 String returnParam = getValue(req, RETURNID_PARAM_NAME); -894 if (null == returnParam || 0 == returnParam.length()) { -895 returnParam = RETURNID_DEFAULT_VALUE; -896 } -897 // -898 // Do we add a '?' or a '&' for the parameters -899 // -900 -901 if (returnUrl.indexOf('?') >= 0) { -902 // -903 // there is a parameter already. Add a '&' -904 // -905 buffer.append("&" + returnParam + "="); -906 } else { -907 // -908 // No parameter. Use ? -909 // -910 buffer.append("?" + returnParam + "="); -911 } -912 buffer.append(site.getName()); -913 redirect = buffer.toString(); -914 } else { -915 // -916 // Just send it back -917 // -918 redirect = returnUrl; -919 } -920 -921 LOG.debug("Dispatching to " + redirect); -922 -923 try { -924 res.sendRedirect(redirect); -925 } catch (IOException ioe) { -926 // -927 // That failed. -928 // -929 throw new WayfException("Error forwarding back to Sp: \n" + ioe.getMessage()); -930 } -931 } -932 } -933 -934 /** -935 * Handles all "recoverable" errors in WAYF processing by logging the error and forwarding the user to an -936 * appropriate error page. -937 * -938 * @param req request under consideration -939 * @param res response under construction -940 * @param message - what so say -941 */ -942 private void handleError(HttpServletRequest req, HttpServletResponse res, String message) { -943 -944 LOG.debug("Displaying WAYF error page."); -945 req.setAttribute("errorText", message); -946 req.setAttribute("requestURL", req.getRequestURI().toString()); -947 RequestDispatcher rd = req.getRequestDispatcher(config.getErrorJspFile()); -948 -949 try { -950 rd.forward(req, res); -951 } catch (IOException ioe) { -952 LOG.error("Problem trying to display WAYF error page: " + ioe.toString()); -953 } catch (ServletException se) { -954 LOG.error("Problem trying to display WAYF error page: " + se.toString()); -955 } -956 } -957 -958 /** -959 * Gets the value for the parameter either from the parameter or from jsp. -960 * @param req - the request. -961 * @param name - the name of the parameter. -962 * @return - result -963 */ -964 private static String getValue(HttpServletRequest req, String name) { -965 -966 -967 String value = req.getParameter(name); -968 if (value != null) { -969 return value; -970 } -971 return (String) req.getAttribute(name); -972 } -973 -974 private static String getSPId(HttpServletRequest req) throws WayfException { -975 -976 // -977 // Try first with 2.0 version -978 // -979 String param = req.getParameter(ENTITYID_PARAM_NAME); -980 if (param != null && !(param.length() == 0)) { -981 return param; -982 } -983 -984 param = (String) req.getAttribute(ENTITYID_PARAM_NAME); -985 if (param != null && !(param.length() == 0)) { -986 return param; -987 } -988 // -989 // So Try with 1.3 version -990 // -991 param = req.getParameter(PROVIDERID_PARAM_NAME); -992 if (param != null && !(param.length() == 0)) { -993 return param; -994 } -995 -996 param = (String) req.getAttribute(PROVIDERID_PARAM_NAME); -997 if (param != null && !(param.length() == 0)) { -998 return param; -999 } -1000 throw new WayfException("Could not locate SP identifier in parameters"); -1001 } -1002 } +825 +826 /** +827 * Uses an HTTP Status 307 redirect to forward the user to the IdP or the SP. +828 * +829 * @param req request under consideration +830 * @param res response under construction +831 * @param site The Idp +832 * @throws WayfException if bad things happen. +833 */ +834 public static void forwardRequest(HttpServletRequest req, HttpServletResponse res, IdPSite site) +835 throws WayfException { +836 +837 String shire = getValue(req, SHIRE_PARAM_NAME); +838 String providerId = getSPId(req); +839 boolean twoZeroProtocol = (shire == null); +840 +841 if (!twoZeroProtocol) { +842 String handleService = site.getAddressForWAYF(); +843 if (handleService != null ) { +844 +845 String target = getValue(req, TARGET_PARAM_NAME); +846 if (null == target || 0 == target.length()) { +847 throw new WayfException("Could not extract target from provided parameters"); +848 } +849 +850 LOG.info("Redirecting to selected Handle Service: " + handleService); +851 try { +852 StringBuffer buffer = new StringBuffer(handleService + +853 "?" + TARGET_PARAM_NAME + "="); +854 buffer.append(URLEncoder.encode(target, "UTF-8")); +855 buffer.append("&" + SHIRE_PARAM_NAME + "="); +856 buffer.append(URLEncoder.encode(shire, "UTF-8")); +857 buffer.append("&" + PROVIDERID_PARAM_NAME + "="); +858 buffer.append(URLEncoder.encode(providerId, "UTF-8")); +859 +860 // +861 // Time is as per U**X +862 // +863 buffer.append("&" + TIME_PARAM_NAME + "="); +864 buffer.append(new Long(new Date().getTime() / 1000).toString()); +865 res.sendRedirect(buffer.toString()); +866 } catch (IOException ioe) { +867 // +868 // That failed. +869 // +870 throw new WayfException("Error forwarding to IdP: \n" + ioe.getMessage()); +871 } +872 } else { +873 String s = "Error finding to IdP: " + site.getDisplayName(req); +874 LOG.error(s); +875 throw new WayfException(s); +876 } +877 } else { +878 String returnUrl = (String) req.getAttribute(RETURN_ATTRIBUTE_NAME); +879 +880 if (null == returnUrl || 0 == returnUrl.length()) { +881 throw new WayfException("Could not find return parameter"); +882 } +883 try { +884 returnUrl = URLDecoder.decode(returnUrl, "UTF-8"); +885 } catch (UnsupportedEncodingException e) { +886 throw new WayfException("Did not understand parameter ", e); +887 } +888 String redirect; +889 if (site != null) { +890 StringBuffer buffer = new StringBuffer(returnUrl); +891 // +892 // If we were given anybody to lookup, construct the URL +893 // +894 String returnParam = getValue(req, RETURNID_PARAM_NAME); +895 if (null == returnParam || 0 == returnParam.length()) { +896 returnParam = RETURNID_DEFAULT_VALUE; +897 } +898 // +899 // Do we add a '?' or a '&' for the parameters +900 // +901 +902 if (returnUrl.indexOf('?') >= 0) { +903 // +904 // there is a parameter already. Add a '&' +905 // +906 buffer.append("&" + returnParam + "="); +907 } else { +908 // +909 // No parameter. Use ? +910 // +911 buffer.append("?" + returnParam + "="); +912 } +913 buffer.append(site.getName()); +914 redirect = buffer.toString(); +915 } else { +916 // +917 // Just send it back +918 // +919 redirect = returnUrl; +920 } +921 +922 LOG.debug("Dispatching to " + redirect); +923 +924 try { +925 res.sendRedirect(redirect); +926 } catch (IOException ioe) { +927 // +928 // That failed. +929 // +930 throw new WayfException("Error forwarding back to Sp: \n" + ioe.getMessage()); +931 } +932 } +933 } +934 +935 /** +936 * Handles all "recoverable" errors in WAYF processing by logging the error and forwarding the user to an +937 * appropriate error page. +938 * +939 * @param req request under consideration +940 * @param res response under construction +941 * @param message - what so say +942 */ +943 private void handleError(HttpServletRequest req, HttpServletResponse res, String message) { +944 +945 LOG.debug("Displaying WAYF error page."); +946 req.setAttribute("errorText", message); +947 req.setAttribute("requestURL", req.getRequestURI().toString()); +948 RequestDispatcher rd = req.getRequestDispatcher(config.getErrorJspFile()); +949 +950 try { +951 rd.forward(req, res); +952 } catch (IOException ioe) { +953 LOG.error("Problem trying to display WAYF error page: " + ioe.toString()); +954 } catch (ServletException se) { +955 LOG.error("Problem trying to display WAYF error page: " + se.toString()); +956 } +957 } +958 +959 /** +960 * Gets the value for the parameter either from the parameter or from jsp. +961 * @param req - the request. +962 * @param name - the name of the parameter. +963 * @return - result +964 */ +965 private static String getValue(HttpServletRequest req, String name) { +966 +967 +968 String value = req.getParameter(name); +969 if (value != null) { +970 return value; +971 } +972 return (String) req.getAttribute(name); +973 } +974 +975 private static String getSPId(HttpServletRequest req) throws WayfException { +976 +977 // +978 // Try first with 2.0 version +979 // +980 String param = req.getParameter(ENTITYID_PARAM_NAME); +981 if (param != null && !(param.length() == 0)) { +982 return param; +983 } +984 +985 param = (String) req.getAttribute(ENTITYID_PARAM_NAME); +986 if (param != null && !(param.length() == 0)) { +987 return param; +988 } +989 // +990 // So Try with 1.3 version +991 // +992 param = req.getParameter(PROVIDERID_PARAM_NAME); +993 if (param != null && !(param.length() == 0)) { +994 return param; +995 } +996 +997 param = (String) req.getAttribute(PROVIDERID_PARAM_NAME); +998 if (param != null && !(param.length() == 0)) { +999 return param; +1000 } +1001 throw new WayfException("Could not locate SP identifier in parameters"); +1002 } +1003 }
-- cgit v1.1