public void CtorGoodUri() { var uri = new UriIdentifier(goodUri); Assert.AreEqual(new Uri(goodUri), uri.Uri); Assert.IsFalse(uri.SchemeImplicitlyPrepended); Assert.IsFalse(uri.IsDiscoverySecureEndToEnd); }
IEnumerable<ServiceEndpoint> generateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) { foreach (var service in findClaimedIdentifierServices()) { foreach (var uri in service.UriElements) { yield return ServiceEndpoint.CreateForClaimedIdentifier( claimedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); } } }
void parameterizedOPIdentifierTest(TestSupport.Scenarios scenario, AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult) { ProtocolVersion version = ProtocolVersion.V20; // only this version supports directed identity UriIdentifier claimedIdentifier = TestSupport.GetDirectedIdentityUrl(TestSupport.Scenarios.ApproveOnSetup, version); Identifier opIdentifier = TestSupport.GetMockOPIdentifier(TestSupport.Scenarios.ApproveOnSetup, claimedIdentifier); parameterizedProgrammaticOPIdentifierTest(opIdentifier, version, claimedIdentifier, requestMode, expectedResult, true); parameterizedProgrammaticOPIdentifierTest(opIdentifier, version, claimedIdentifier, requestMode, expectedResult, false); }
internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) { List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>(); endpoints.AddRange(generateOPIdentifierServiceEndpoints(claimedIdentifier)); // If any OP Identifier service elements were found, we must not proceed // to return any Claimed Identifier services. if (endpoints.Count == 0) { endpoints.AddRange(generateClaimedIdentifierServiceEndpoints(claimedIdentifier)); } return endpoints; }
public async Task DiscoveryRequiresSslIgnoresInsecureEndpointsInXrds() { var insecureEndpoint = GetServiceEndpoint(0, ProtocolVersion.V20, 10, false); var secureEndpoint = GetServiceEndpoint(1, ProtocolVersion.V20, 20, true); UriIdentifier secureClaimedId = new UriIdentifier(VanityUriSsl, true); this.RegisterMockXrdsResponse(secureClaimedId, new[] { insecureEndpoint, secureEndpoint }); var discoverResult = await this.DiscoverAsync(secureClaimedId); Assert.AreEqual(secureEndpoint.ProviderLocalIdentifier, discoverResult.Single().ProviderLocalIdentifier); }
public void UnicodeTest() { string unicodeUrl = "http://nerdbank.org/opaffirmative/崎村.aspx"; Assert.IsTrue(UriIdentifier.IsValidUri(unicodeUrl)); Identifier id; Assert.IsTrue(UriIdentifier.TryParse(unicodeUrl, out id)); Assert.AreEqual("/opaffirmative/%E5%B4%8E%E6%9D%91.aspx", ((UriIdentifier)id).Uri.AbsolutePath); Assert.AreEqual(Uri.EscapeUriString(unicodeUrl), id.ToString()); }
internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) { List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>(); endpoints.AddRange(generateOPIdentifierServiceEndpoints(claimedIdentifier)); // If any OP Identifier service elements were found, we must not proceed // to return any Claimed Identifier services. if (endpoints.Count == 0) { endpoints.AddRange(generateClaimedIdentifierServiceEndpoints(claimedIdentifier)); } Logger.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); Logger.Debug(Util.ToString(endpoints, true)); return endpoints; }
internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { IdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, directedIdentityAssignedIdentifier, providerEndpoint.ProviderLocalIdentifier, new ProviderEndpointDescription(providerEndpoint.ProviderEndpoint, providerEndpoint.Capabilities), 10, 10); this.RegisterMockXrdsResponse(identityEndpoint); }
IEnumerable <ServiceEndpoint> generateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) { foreach (var service in findClaimedIdentifierServices()) { foreach (var uri in service.UriElements) { yield return(ServiceEndpoint.CreateForClaimedIdentifier( claimedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority)); } } }
internal static void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, ServiceEndpoint providerEndpoint) { ServiceEndpoint identityEndpoint = ServiceEndpoint.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, directedIdentityAssignedIdentifier, providerEndpoint.ProviderEndpoint, new string[] { providerEndpoint.Protocol.ClaimedIdentifierServiceTypeURI }, 10, 10 ); RegisterMockXrdsResponse(identityEndpoint); }
public void DiscoveryRequireSslWithInsecureXrdsInSecureHtmlHead() { var insecureXrdsSource = this.GetMockIdentifier(ProtocolVersion.V20, false); Uri secureClaimedUri = new Uri("https://localhost/secureId"); string html = string.Format("<html><head><meta http-equiv='X-XRDS-Location' content='{0}'/></head><body></body></html>", insecureXrdsSource); this.MockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); Assert.AreEqual(0, this.Discover(userSuppliedIdentifier).Count()); }
public void DiscoveryRequireSslWithInsecureXrdsInSecureHtmlHead() { var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); string html = string.Format("<html><head><meta http-equiv='X-XRDS-Location' content='{0}'/></head><body></body></html>", insecureXrdsSource); MockHttpRequest.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); Assert.AreEqual(0, userSuppliedIdentifier.Discover().Count()); }
/// <summary> /// Performs YADIS discovery on some identifier. /// </summary> /// <param name="uri">The URI to perform discovery on.</param> /// <param name="requireSsl">Whether discovery should fail if any step of it is not encrypted.</param> /// <returns> /// The result of discovery on the given URL. /// Null may be returned if an error occurs, /// or if <paramref name="requireSsl"/> is true but part of discovery /// is not protected by SSL. /// </returns> public static DiscoveryResult Discover(UriIdentifier uri, bool requireSsl) { UntrustedWebResponse response; try { if (requireSsl && !string.Equals(uri.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { Logger.WarnFormat("Discovery on insecure identifier '{0}' aborted.", uri); return null; } response = UntrustedWebRequest.Request(uri, null, new[] { ContentTypes.Html, ContentTypes.XHtml, ContentTypes.Xrds }, requireSsl, UntrustedWebRequest.IdentifierDiscoveryCachePolicy); if (response.StatusCode != System.Net.HttpStatusCode.OK) { return null; } } catch (ArgumentException ex) { // Unsafe URLs generate this Logger.WarnFormat("Unsafe OpenId URL detected ({0}). Request aborted. {1}", uri, ex); return null; } UntrustedWebResponse response2 = null; if (isXrdsDocument(response)) { Logger.Debug("An XRDS response was received from GET at user-supplied identifier."); response2 = response; } else { string uriString = response.Headers.Get(HeaderName); Uri url = null; if (uriString != null) { if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) { Logger.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url == null && response.ContentType.MediaType == ContentTypes.Html) { url = FindYadisDocumentLocationInHtmlMetaTags(response.ReadResponseString()); if (url != null) { Logger.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url != null) { if (!requireSsl || string.Equals(url.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { response2 = UntrustedWebRequest.Request(url, null, null, requireSsl, UntrustedWebRequest.IdentifierDiscoveryCachePolicy); if (response2.StatusCode != System.Net.HttpStatusCode.OK) { return null; } } else { Logger.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); } } } return new DiscoveryResult(uri, response, response2); }
internal IEnumerable <ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) { List <ServiceEndpoint> endpoints = new List <ServiceEndpoint>(); endpoints.AddRange(generateOPIdentifierServiceEndpoints(claimedIdentifier)); // If any OP Identifier service elements were found, we must not proceed // to return any Claimed Identifier services. if (endpoints.Count == 0) { endpoints.AddRange(generateClaimedIdentifierServiceEndpoints(claimedIdentifier)); } Logger.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); Logger.Debug(Util.ToString(endpoints, true)); return(endpoints); }
public void DiscoveryRequireSslWithInsecureXrdsInSecureHttpHeader() { var insecureXrdsSource = this.GetMockIdentifier(ProtocolVersion.V20, false); string html = "<html><head></head><body></body></html>"; WebHeaderCollection headers = new WebHeaderCollection { { "X-XRDS-Location", insecureXrdsSource } }; this.MockResponder.RegisterMockResponse(VanityUriSsl, VanityUriSsl, "text/html", headers, html); Identifier userSuppliedIdentifier = new UriIdentifier(VanityUriSsl, true); Assert.AreEqual(0, this.Discover(userSuppliedIdentifier).Count()); }
public void DiscoveryWithRedirects() { Identifier claimedId = this.GetMockIdentifier(ProtocolVersion.V20, false); // Add a couple of chained redirect pages that lead to the claimedId. Uri userSuppliedUri = new Uri("https://localhost/someSecurePage"); Uri insecureMidpointUri = new Uri("http://localhost/insecureStop"); this.MockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); this.MockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); // don't require secure SSL discovery for this test. Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, false); Assert.AreEqual(1, this.Discover(userSuppliedIdentifier).Count()); }
public void TrimFragment() { Identifier noFragment = UriIdentifier.Parse("http://a/b"); Identifier fragment = UriIdentifier.Parse("http://a/b#c"); Assert.AreSame(noFragment, noFragment.TrimFragment()); Assert.AreEqual(noFragment.ToString(), fragment.TrimFragment().ToString()); // Try the problematic ones TestAsFullAndPartialTrust(fullTrust => { Identifier noFrag = UriIdentifier.Parse("http://a/b./c"); Identifier frag = UriIdentifier.Parse("http://a/b./c#d"); Assert.AreSame(noFrag, noFrag.TrimFragment()); Assert.AreEqual(noFrag.ToString(), frag.TrimFragment().ToString()); }); }
public void DiscoverRequireSslWithSecureRedirects() { Identifier claimedId = this.GetMockIdentifier(ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // All redirects should be secure. Uri userSuppliedUri = new Uri("https://localhost/someSecurePage"); Uri secureMidpointUri = new Uri("https://localhost/secureStop"); this.MockResponder.RegisterMockRedirect(userSuppliedUri, secureMidpointUri); this.MockResponder.RegisterMockRedirect(secureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); Assert.AreEqual(1, this.Discover(userSuppliedIdentifier).Count()); }
public void DiscoveryRequireSslWithInsecureXrdsInSecureHttpHeader() { var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); string html = "<html><head></head><body></body></html>"; WebHeaderCollection headers = new WebHeaderCollection { { "X-XRDS-Location", insecureXrdsSource } }; MockHttpRequest.RegisterMockResponse(secureClaimedUri, secureClaimedUri, "text/html", headers, html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); Assert.AreEqual(0, userSuppliedIdentifier.Discover().Count()); }
public void DiscoverRequireSslWithSecureRedirects() { MockHttpRequest.Reset(); Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // All redirects should be secure. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri secureMidpointUri = TestSupport.GetFullUrl("/secureStop", null, true); MockHttpRequest.RegisterMockRedirect(userSuppliedUri, secureMidpointUri); MockHttpRequest.RegisterMockRedirect(secureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); Assert.AreEqual(1, userSuppliedIdentifier.Discover().Count()); }
public void DiscoverRequireSslWithInsecureRedirect() { Identifier claimedId = this.GetMockIdentifier(ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // Include an insecure HTTP jump in those redirects to verify that // the ultimate endpoint is never found as a result of high security profile. Uri userSuppliedUri = new Uri("https://localhost/someSecurePage"); Uri insecureMidpointUri = new Uri("http://localhost/insecureStop"); this.MockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); this.MockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); this.Discover(userSuppliedIdentifier); }
public void DiscoveryWithRedirects() { MockHttpRequest.Reset(); Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20); // Add a couple of chained redirect pages that lead to the claimedId. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri insecureMidpointUri = TestSupport.GetFullUrl("/insecureStop"); MockHttpRequest.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); MockHttpRequest.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); // don't require secure SSL discovery for this test. Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, false); Assert.AreEqual(1, userSuppliedIdentifier.Discover().Count()); }
public void ProblematicClaimedId() { var providerEndpoint = new ProviderEndpointDescription(OpenIdTestBase.OPUri, Protocol.Default.Version); string claimed_id = BaseMockUri + "a./b."; var se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimed_id, claimed_id, providerEndpoint, null, null); UriIdentifier identityUri = (UriIdentifier)se.ClaimedIdentifier; var mockId = new MockIdentifier(identityUri, this.MockResponder, new IdentifierDiscoveryResult[] { se }); var positiveAssertion = this.GetPositiveAssertion(); positiveAssertion.ClaimedIdentifier = mockId; positiveAssertion.LocalIdentifier = mockId; var rp = CreateRelyingParty(); var authResponse = new PositiveAuthenticationResponse(positiveAssertion, rp); Assert.AreEqual(AuthenticationStatus.Authenticated, authResponse.Status); Assert.AreEqual(claimed_id, authResponse.ClaimedIdentifier.ToString()); }
public void DiscoverRequireSslWithInsecureRedirect() { MockHttpRequest.Reset(); Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // Include an insecure HTTP jump in those redirects to verify that // the ultimate endpoint is never found as a result of high security profile. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri insecureMidpointUri = TestSupport.GetFullUrl("/insecureStop"); MockHttpRequest.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); MockHttpRequest.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); userSuppliedIdentifier.Discover(); }
/// <summary> /// Verifies that the positive assertion data matches the results of /// discovery on the Claimed Identifier. /// </summary> /// <param name="relyingParty">The relying party.</param> /// <exception cref="ProtocolException"> /// Thrown when the Provider is asserting that a user controls an Identifier /// when discovery on that Identifier contradicts what the Provider says. /// This would be an indication of either a misconfigured Provider or /// an attempt by someone to spoof another user's identity with a rogue Provider. /// </exception> private void VerifyDiscoveryMatchesAssertion(OpenIdRelyingParty relyingParty) { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. Identifier claimedId = this.Response.ClaimedIdentifier; if (relyingParty.SecuritySettings.RequireSsl) { if (!claimedId.TryRequireSsl(out claimedId)) { Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); } } // Check whether this particular identifier presents a problem with HTTP discovery // due to limitations in the .NET Uri class. UriIdentifier claimedIdUri = claimedId as UriIdentifier; if (claimedIdUri != null && claimedIdUri.ProblematicNormalization) { ErrorUtilities.VerifyProtocol(relyingParty.SecuritySettings.AllowApproximateIdentifierDiscovery, OpenIdStrings.ClaimedIdentifierDefiesDotNetNormalization); Logger.OpenId.WarnFormat("Positive assertion for claimed identifier {0} cannot be precisely verified under partial trust hosting due to .NET limitation. An approximate verification will be attempted.", claimedId); } // While it LOOKS like we're performing discovery over HTTP again // Yadis.IdentifierDiscoveryCachePolicy is set to HttpRequestCacheLevel.CacheIfAvailable // which means that the .NET runtime is caching our discoveries for us. This turns out // to be very fast and keeps our code clean and easily verifiable as correct and secure. // CAUTION: if this discovery is ever made to be skipped based on previous discovery // data that was saved to the return_to URL, be careful to verify that that information // is signed by the RP before it's considered reliable. In 1.x stateless mode, this RP // doesn't (and can't) sign its own return_to URL, so its cached discovery information // is merely a hint that must be verified by performing discovery again here. var discoveryResults = relyingParty.Discover(claimedId); ErrorUtilities.VerifyProtocol( discoveryResults.Contains(this.Endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.Endpoint, discoveryResults.ToStringDeferred(true)); }
internal static MockIdentifier GetMockOPIdentifier(Scenarios scenario, UriIdentifier expectedClaimedId, bool useSslOpIdentifier, bool useSslProviderEndpoint) { var fields = new Dictionary <string, string> { { "user", scenario.ToString() }, }; Uri opEndpoint = GetFullUrl(DirectedProviderEndpoint, fields, useSslProviderEndpoint); Uri opIdentifier = GetOPIdentityUrl(scenario, useSslOpIdentifier); ServiceEndpoint se = ServiceEndpoint.CreateForProviderIdentifier( opIdentifier, opEndpoint, new string[] { Protocol.v20.OPIdentifierServiceTypeURI }, 10, 10 ); // Register the Claimed Identifier that directed identity will choose so that RP // discovery on that identifier can be mocked up. MockHttpRequest.RegisterMockXrdsResponse(expectedClaimedId, se); return(new MockIdentifier(opIdentifier, new ServiceEndpoint[] { se })); }
void discover(string url, ProtocolVersion version, Identifier expectedLocalId, bool expectSreg, bool useRedirect, WebHeaderCollection headers) { Protocol protocol = Protocol.Lookup(version); UriIdentifier claimedId = TestSupport.GetFullUrl(url); UriIdentifier userSuppliedIdentifier = TestSupport.GetFullUrl( "Discovery/htmldiscovery/redirect.aspx?target=" + url); if (expectedLocalId == null) { expectedLocalId = claimedId; } Identifier idToDiscover = useRedirect ? userSuppliedIdentifier : claimedId; string contentType; if (url.EndsWith("html")) { contentType = "text/html"; } else if (url.EndsWith("xml")) { contentType = "application/xrds+xml"; } else { throw new InvalidOperationException(); } MockHttpRequest.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, headers ?? new WebHeaderCollection(), TestSupport.LoadEmbeddedFile(url)); ServiceEndpoint se = idToDiscover.Discover().FirstOrDefault(); Assert.IsNotNull(se, url + " failed to be discovered."); Assert.AreSame(protocol, se.Protocol); Assert.AreEqual(claimedId, se.ClaimedIdentifier); Assert.AreEqual(expectedLocalId, se.ProviderLocalIdentifier); Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderSupportedServiceTypeUris.Length); Assert.IsTrue(Array.IndexOf(se.ProviderSupportedServiceTypeUris, protocol.ClaimedIdentifierServiceTypeURI) >= 0); Assert.AreEqual(expectSreg, se.IsExtensionSupported(new ClaimsRequest())); }
public void DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags() { var insecureXrdsSource = this.GetMockIdentifier(ProtocolVersion.V20, false); string html = string.Format( @" <html><head> <meta http-equiv='X-XRDS-Location' content='{0}'/> <!-- this one will be insecure and ignored --> <link rel='openid2.provider' href='{1}' /> <link rel='openid2.local_id' href='{2}' /> </head><body></body></html>" , HttpUtility.HtmlEncode(insecureXrdsSource), HttpUtility.HtmlEncode(OPUriSsl.AbsoluteUri), HttpUtility.HtmlEncode(OPLocalIdentifiersSsl[1].AbsoluteUri)); this.MockResponder.RegisterMockResponse(VanityUriSsl, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(VanityUriSsl, true); // We verify that the XRDS was ignored and the LINK tags were used // because the XRDS OP-LocalIdentifier uses different local identifiers. Assert.AreEqual(OPLocalIdentifiersSsl[1].AbsoluteUri, this.Discover(userSuppliedIdentifier).Single().ProviderLocalIdentifier.ToString()); }
public void TrailingPeriodsNotTrimmed() { TestAsFullAndPartialTrust(fullTrust => { string claimedIdentifier = "https://me.yahoo.com/a/AsDf.#asdf"; Identifier id = claimedIdentifier; Assert.AreEqual(claimedIdentifier, id.OriginalString); Assert.AreEqual(claimedIdentifier, id.ToString()); UriIdentifier idUri = new UriIdentifier(claimedIdentifier); Assert.AreEqual(claimedIdentifier, idUri.OriginalString); Assert.AreEqual(claimedIdentifier, idUri.ToString()); if (fullTrust) { Assert.AreEqual(claimedIdentifier, idUri.Uri.AbsoluteUri); } Assert.AreEqual(Uri.UriSchemeHttps, idUri.Uri.Scheme); // in case custom scheme tricks are played, this must still match Assert.AreEqual("https://me.yahoo.com/a/AsDf.", idUri.TrimFragment().ToString()); Assert.AreEqual("https://me.yahoo.com/a/AsDf.", idUri.TrimFragment().OriginalString); Assert.AreEqual(id.ToString(), new UriIdentifier((Uri)idUri).ToString(), "Round tripping UriIdentifier->Uri->UriIdentifier failed."); idUri = new UriIdentifier(new Uri(claimedIdentifier)); Assert.AreEqual(claimedIdentifier, idUri.OriginalString); Assert.AreEqual(claimedIdentifier, idUri.ToString()); if (fullTrust) { Assert.AreEqual(claimedIdentifier, idUri.Uri.AbsoluteUri); } Assert.AreEqual(Uri.UriSchemeHttps, idUri.Uri.Scheme); // in case custom scheme tricks are played, this must still match Assert.AreEqual("https://me.yahoo.com/a/AsDf.", idUri.TrimFragment().ToString()); Assert.AreEqual("https://me.yahoo.com/a/AsDf.", idUri.TrimFragment().OriginalString); Assert.AreEqual(id.ToString(), new UriIdentifier((Uri)idUri).ToString(), "Round tripping UriIdentifier->Uri->UriIdentifier failed."); claimedIdentifier = "https://me.yahoo.com:443/a/AsDf.#asdf"; id = claimedIdentifier; Assert.AreEqual(claimedIdentifier, id.OriginalString); Assert.AreEqual("https://me.yahoo.com/a/AsDf.#asdf", id.ToString()); }); }
public void DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags() { var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); Identifier localIdForLinkTag = TestSupport.GetDelegateUrl(TestSupport.Scenarios.AlwaysDeny, true); string html = string.Format(@" <html><head> <meta http-equiv='X-XRDS-Location' content='{0}'/> <!-- this one will be insecure and ignored --> <link rel='openid2.provider' href='{1}' /> <link rel='openid2.local_id' href='{2}' /> </head><body></body></html>" , HttpUtility.HtmlEncode(insecureXrdsSource), HttpUtility.HtmlEncode(TestSupport.GetFullUrl("/" + TestSupport.ProviderPage, null, true).AbsoluteUri), HttpUtility.HtmlEncode(localIdForLinkTag.ToString()) ); MockHttpRequest.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); Assert.AreEqual(localIdForLinkTag, userSuppliedIdentifier.Discover().Single().ProviderLocalIdentifier); }
//ERIC'S CODE //private async Task VerifyDiscoveryMatchesAssertionAsync_ccp(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) public async Task VerifyDiscoveryMatchesAssertionAsync_ccp(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. Identifier claimedId = this.Response.ClaimedIdentifier; /* * if (relyingParty.SecuritySettings.RequireSsl) * { * if (!claimedId.TryRequireSsl(out claimedId)) * { * Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); * ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); * } * } */ // Check whether this particular identifier presents a problem with HTTP discovery // due to limitations in the .NET Uri class. UriIdentifier claimedIdUri = claimedId as UriIdentifier; /* * if (claimedIdUri != null && claimedIdUri.ProblematicNormalization) * { * ErrorUtilities.VerifyProtocol(relyingParty.SecuritySettings.AllowApproximateIdentifierDiscovery, OpenIdStrings.ClaimedIdentifierDefiesDotNetNormalization); * Logger.OpenId.WarnFormat("Positive assertion for claimed identifier {0} cannot be precisely verified under partial trust hosting due to .NET limitation. An approximate verification will be attempted.", claimedId); * } */ var discoveryResults = await relyingParty.DiscoverAsync(claimedId, cancellationToken); ErrorUtilities.VerifyProtocol( discoveryResults.Contains(this.Endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.Endpoint, discoveryResults.ToStringDeferred(true)); }
/// <summary> /// Performs YADIS discovery on some identifier. /// </summary> /// <param name="hostFactories">The host factories.</param> /// <param name="uri">The URI to perform discovery on.</param> /// <param name="requireSsl">Whether discovery should fail if any step of it is not encrypted.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The result of discovery on the given URL. /// Null may be returned if an error occurs, /// or if <paramref name="requireSsl" /> is true but part of discovery /// is not protected by SSL. /// </returns> public static async Task <DiscoveryResult> DiscoverAsync(IHostFactories hostFactories, UriIdentifier uri, bool requireSsl, CancellationToken cancellationToken) { Requires.NotNull(hostFactories, "hostFactories"); Requires.NotNull(uri, "uri"); HttpResponseMessage response; try { if (requireSsl && !string.Equals(uri.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { Logger.Yadis.WarnFormat("Discovery on insecure identifier '{0}' aborted.", uri); return(null); } response = await RequestAsync(uri, requireSsl, hostFactories, cancellationToken, ContentTypes.Html, ContentTypes.XHtml, ContentTypes.Xrds); if (response.StatusCode != System.Net.HttpStatusCode.OK) { Logger.Yadis.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response.StatusCode, response.StatusCode, uri); return(null); } await response.Content.LoadIntoBufferAsync(); } catch (ArgumentException ex) { // Unsafe URLs generate this Logger.Yadis.WarnFormat("Unsafe OpenId URL detected ({0}). Request aborted. {1}", uri, ex); return(null); } HttpResponseMessage response2 = null; if (await IsXrdsDocumentAsync(response)) { Logger.Yadis.Debug("An XRDS response was received from GET at user-supplied identifier."); Reporting.RecordEventOccurrence("Yadis", "XRDS in initial response"); response2 = response; } else { IEnumerable <string> uriStrings; string uriString = null; if (response.Headers.TryGetValues(HeaderName, out uriStrings)) { uriString = uriStrings.FirstOrDefault(); } Uri url = null; if (uriString != null) { if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) { Logger.Yadis.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); Reporting.RecordEventOccurrence("Yadis", "XRDS referenced in HTTP header"); } } var contentType = response.Content.Headers.ContentType; if (url == null && contentType != null && (contentType.MediaType == ContentTypes.Html || contentType.MediaType == ContentTypes.XHtml)) { url = FindYadisDocumentLocationInHtmlMetaTags(await response.Content.ReadAsStringAsync()); if (url != null) { Logger.Yadis.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); Reporting.RecordEventOccurrence("Yadis", "XRDS referenced in HTML"); } } if (url != null) { if (!requireSsl || string.Equals(url.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { response2 = await RequestAsync(url, requireSsl, hostFactories, cancellationToken, ContentTypes.Xrds); if (response2.StatusCode != HttpStatusCode.OK) { Logger.Yadis.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response2.StatusCode, response2.StatusCode, uri); } } else { Logger.Yadis.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); } } } return(await DiscoveryResult.CreateAsync(uri, response, response2)); }
public void UnicodeHostSupport() { var id = new UriIdentifier("http://server崎/村"); Assert.AreEqual("server崎", id.Uri.Host); }
//[Test, Ignore("The spec says http:// must be prepended in this case, but that just creates an invalid URI. Our UntrustedWebRequest will stop disallowed schemes.")] public void CtorDisallowedScheme() { UriIdentifier id = new UriIdentifier(new Uri("ftp://host/path")); Assert.AreEqual("http://ftp://host/path", id.ToString()); Assert.IsTrue(id.SchemeImplicitlyPrepended); }
public void HttpSchemePrepended() { UriIdentifier id = new UriIdentifier("www.yahoo.com"); Assert.AreEqual("http://www.yahoo.com/", id.ToString()); Assert.IsTrue(id.SchemeImplicitlyPrepended); }
public void TryRequireSslAdjustsIdentifier() { Identifier secureId; // Try Parse and ctor without explicit scheme var id = Identifier.Parse("www.yahoo.com"); Assert.AreEqual("http://www.yahoo.com/", id.ToString()); Assert.IsTrue(id.TryRequireSsl(out secureId)); Assert.IsTrue(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("https://www.yahoo.com/", secureId.ToString()); id = new UriIdentifier("www.yahoo.com"); Assert.AreEqual("http://www.yahoo.com/", id.ToString()); Assert.IsTrue(id.TryRequireSsl(out secureId)); Assert.IsTrue(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("https://www.yahoo.com/", secureId.ToString()); // Try Parse and ctor with explicit http:// scheme id = Identifier.Parse("http://www.yahoo.com"); Assert.IsFalse(id.TryRequireSsl(out secureId)); Assert.IsFalse(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("http://www.yahoo.com/", secureId.ToString()); Assert.AreEqual(0, secureId.Discover().Count()); id = new UriIdentifier("http://www.yahoo.com"); Assert.IsFalse(id.TryRequireSsl(out secureId)); Assert.IsFalse(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("http://www.yahoo.com/", secureId.ToString()); Assert.AreEqual(0, secureId.Discover().Count()); }
public void IsValid() { Assert.IsTrue(UriIdentifier.IsValidUri(this.goodUri)); Assert.IsFalse(UriIdentifier.IsValidUri(this.badUri)); Assert.IsTrue(UriIdentifier.IsValidUri(this.relativeUri), "URL lacking http:// prefix should have worked anyway."); }
public void DiscoveryRequiresSslIgnoresInsecureEndpointsInXrds() { var insecureEndpoint = TestSupport.GetServiceEndpoint(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, 10, false); var secureEndpoint = TestSupport.GetServiceEndpoint(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20, 20, true); UriIdentifier secureClaimedId = new UriIdentifier(TestSupport.GetFullUrl("/claimedId", null, true), true); MockHttpRequest.RegisterMockXrdsResponse(secureClaimedId, new ServiceEndpoint[] { insecureEndpoint, secureEndpoint }); Assert.AreEqual(secureEndpoint.ProviderLocalIdentifier, secureClaimedId.Discover().Single().ProviderLocalIdentifier); }
public void CtorUriHttpsSchemeSecure() { var uri = new UriIdentifier(new Uri("https://host/path"), true); Assert.AreEqual("https://host/path", uri.Uri.AbsoluteUri); Assert.IsTrue(uri.IsDiscoverySecureEndToEnd); }
public void DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags() { var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); Identifier localIdForLinkTag = TestSupport.GetDelegateUrl(TestSupport.Scenarios.AlwaysDeny, true); string html = string.Format(@" <html><head> <meta http-equiv='X-XRDS-Location' content='{0}'/> <!-- this one will be insecure and ignored --> <link rel='openid2.provider' href='{1}' /> <link rel='openid2.local_id' href='{2}' /> </head><body></body></html>", HttpUtility.HtmlEncode(insecureXrdsSource), HttpUtility.HtmlEncode(TestSupport.GetFullUrl("/" + TestSupport.ProviderPage, null, true).AbsoluteUri), HttpUtility.HtmlEncode(localIdForLinkTag.ToString()) ); MockHttpRequest.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); Assert.AreEqual(localIdForLinkTag, userSuppliedIdentifier.Discover().Single().ProviderLocalIdentifier); }
/// <summary> /// Performs YADIS discovery on some identifier. /// </summary> /// <param name="requestHandler">The mechanism to use for sending HTTP requests.</param> /// <param name="uri">The URI to perform discovery on.</param> /// <param name="requireSsl">Whether discovery should fail if any step of it is not encrypted.</param> /// <returns> /// The result of discovery on the given URL. /// Null may be returned if an error occurs, /// or if <paramref name="requireSsl"/> is true but part of discovery /// is not protected by SSL. /// </returns> public static DiscoveryResult Discover(IDirectWebRequestHandler requestHandler, UriIdentifier uri, bool requireSsl) { CachedDirectWebResponse response; try { if (requireSsl && !string.Equals(uri.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { Logger.WarnFormat("Discovery on insecure identifier '{0}' aborted.", uri); return(null); } response = Request(requestHandler, uri, requireSsl, ContentTypes.Html, ContentTypes.XHtml, ContentTypes.Xrds).GetSnapshot(MaximumResultToScan); if (response.Status != System.Net.HttpStatusCode.OK) { Logger.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response.Status, response.Status, uri); return(null); } } catch (ArgumentException ex) { // Unsafe URLs generate this Logger.WarnFormat("Unsafe OpenId URL detected ({0}). Request aborted. {1}", uri, ex); return(null); } CachedDirectWebResponse response2 = null; if (IsXrdsDocument(response)) { Logger.Debug("An XRDS response was received from GET at user-supplied identifier."); response2 = response; } else { string uriString = response.Headers.Get(HeaderName); Uri url = null; if (uriString != null) { if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) { Logger.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url == null && response.ContentType.MediaType == ContentTypes.Html) { url = FindYadisDocumentLocationInHtmlMetaTags(response.Body); if (url != null) { Logger.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url != null) { if (!requireSsl || string.Equals(url.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { response2 = Request(requestHandler, url, requireSsl, ContentTypes.Xrds).GetSnapshot(MaximumResultToScan); if (response2.Status != HttpStatusCode.OK) { Logger.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response2.Status, response2.Status, uri); return(null); } } else { Logger.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); } } } return(new DiscoveryResult(uri, response, response2)); }
public void DoesNotStripFragment() { Uri original = new Uri("http://a/b#c"); UriIdentifier identifier = new UriIdentifier(original); Assert.AreEqual(original.Fragment, identifier.Uri.Fragment); }
internal IdentityEndpointNormalizationEventArgs(UriIdentifier userSuppliedIdentifier) { UserSuppliedIdentifier = userSuppliedIdentifier; }