/// <summary> /// Performs discovery on the specified identifier. /// </summary> /// <param name="identifier">The identifier to perform discovery on.</param> /// <param name="requestHandler">The means to place outgoing HTTP requests.</param> /// <param name="abortDiscoveryChain">if set to <c>true</c>, no further discovery services will be called for this identifier.</param> /// <returns> /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> public IEnumerable <IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { abortDiscoveryChain = false; var uriIdentifier = identifier as UriIdentifier; if (uriIdentifier == null) { return(Enumerable.Empty <IdentifierDiscoveryResult>()); } var endpoints = new List <IdentifierDiscoveryResult>(); // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, uriIdentifier, identifier.IsDiscoverySecureEndToEnd); if (yadisResult != null) { if (yadisResult.IsXrds) { try { XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText); var xrdsEndpoints = xrds.XrdElements.CreateServiceEndpoints(yadisResult.NormalizedUri, uriIdentifier); // Filter out insecure endpoints if high security is required. if (uriIdentifier.IsDiscoverySecureEndToEnd) { xrdsEndpoints = xrdsEndpoints.Where(se => se.ProviderEndpoint.IsTransportSecure()); } endpoints.AddRange(xrdsEndpoints); } catch (XmlException ex) { Logger.Yadis.Error("Error while parsing the XRDS document. Falling back to HTML discovery.", ex); } } // Failing YADIS discovery of an XRDS document, we try HTML discovery. if (endpoints.Count == 0) { var htmlEndpoints = new List <IdentifierDiscoveryResult>(DiscoverFromHtml(yadisResult.NormalizedUri, uriIdentifier, yadisResult.ResponseText)); if (htmlEndpoints.Any()) { Logger.Yadis.DebugFormat("Total services discovered in HTML: {0}", htmlEndpoints.Count); Logger.Yadis.Debug(htmlEndpoints.ToStringDeferred(true)); endpoints.AddRange(htmlEndpoints.Where(ep => !uriIdentifier.IsDiscoverySecureEndToEnd || ep.ProviderEndpoint.IsTransportSecure())); if (endpoints.Count == 0) { Logger.Yadis.Info("No HTML discovered endpoints met the security requirements."); } } else { Logger.Yadis.Debug("HTML discovery failed to find any endpoints."); } } else { Logger.Yadis.Debug("Skipping HTML discovery because XRDS contained service endpoints."); } } return(endpoints); }
/// <summary> /// Performs discovery on the Identifier. /// </summary> /// <param name="requestHandler">The web request handler to use for discovery.</param> /// <returns> /// An initialized structure containing the discovered provider endpoint information. /// </returns> internal override IEnumerable <ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler) { List <ServiceEndpoint> endpoints = new List <ServiceEndpoint>(); // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this, IsDiscoverySecureEndToEnd); if (yadisResult != null) { if (yadisResult.IsXrds) { XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText); var xrdsEndpoints = xrds.CreateServiceEndpoints(yadisResult.NormalizedUri, this); // Filter out insecure endpoints if high security is required. if (IsDiscoverySecureEndToEnd) { xrdsEndpoints = xrdsEndpoints.Where(se => se.IsSecure); } endpoints.AddRange(xrdsEndpoints); } // Failing YADIS discovery of an XRDS document, we try HTML discovery. if (endpoints.Count == 0) { var htmlEndpoints = new List <ServiceEndpoint>(DiscoverFromHtml(yadisResult.NormalizedUri, this, yadisResult.ResponseText)); if (htmlEndpoints.Any()) { Logger.DebugFormat("Total services discovered in HTML: {0}", htmlEndpoints.Count); Logger.Debug(htmlEndpoints.ToStringDeferred(true)); endpoints.AddRange(htmlEndpoints.Where(ep => !IsDiscoverySecureEndToEnd || ep.IsSecure)); if (endpoints.Count == 0) { Logger.Info("No HTML discovered endpoints met the security requirements."); } } else { Logger.Debug("HTML discovery failed to find any endpoints."); } } else { Logger.Debug("Skipping HTML discovery because XRDS contained service endpoints."); } } return(endpoints); }
/// <summary> /// Searches for an XRDS document at the realm URL. /// </summary> /// <param name="requestHandler">The mechanism to use for sending HTTP requests.</param> /// <param name="allowRedirects">Whether redirects may be followed when discovering the Realm. /// This may be true when creating an unsolicited assertion, but must be /// false when performing return URL verification per 2.0 spec section 9.2.1.</param> /// <returns> /// The XRDS document if found; or <c>null</c> if no service document was discovered. /// </returns> internal virtual XrdsDocument Discover(IDirectWebRequestHandler requestHandler, bool allowRedirects) { // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this.UriWithWildcardChangedToWww, false); if (yadisResult != null) { // Detect disallowed redirects, since realm discovery never allows them for security. ErrorUtilities.VerifyProtocol(allowRedirects || yadisResult.NormalizedUri == yadisResult.RequestUri, OpenIdStrings.RealmCausedRedirectUponDiscovery, yadisResult.RequestUri); if (yadisResult.IsXrds) { try { return new XrdsDocument(yadisResult.ResponseText); } catch (XmlException ex) { throw ErrorUtilities.Wrap(ex, XrdsStrings.InvalidXRDSDocument); } } } return null; }
/// <summary> /// Searches for an XRDS document at the realm URL, and if found, searches /// for a description of a relying party endpoints (OpenId login pages). /// </summary> /// <param name="requestHandler">The mechanism to use for sending HTTP requests.</param> /// <param name="allowRedirects">Whether redirects may be followed when discovering the Realm. /// This may be true when creating an unsolicited assertion, but must be /// false when performing return URL verification per 2.0 spec section 9.2.1.</param> /// <returns> /// The details of the endpoints if found, otherwise null. /// </returns> internal IEnumerable <RelyingPartyEndpointDescription> Discover(IDirectWebRequestHandler requestHandler, bool allowRedirects) { // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this.UriWithWildcardChangedToWww, false); if (yadisResult != null) { // Detect disallowed redirects, since realm discovery never allows them for security. ErrorUtilities.VerifyProtocol(allowRedirects || yadisResult.NormalizedUri == yadisResult.RequestUri, OpenIdStrings.RealmCausedRedirectUponDiscovery, yadisResult.RequestUri); if (yadisResult.IsXrds) { try { XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText); return(xrds.FindRelyingPartyReceivingEndpoints()); } catch (XmlException ex) { throw ErrorUtilities.Wrap(ex, XrdsStrings.InvalidXRDSDocument); } } } return(Enumerable.Empty <RelyingPartyEndpointDescription>()); }