summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs')
-rw-r--r--src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs230
1 files changed, 199 insertions, 31 deletions
diff --git a/src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs b/src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs
index 2503207..fb36e71 100644
--- a/src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs
+++ b/src/DotNetOpenId.Test/RelyingParty/OpenIdRelyingPartyTest.cs
@@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using DotNetOpenId.RelyingParty;
+using DotNetOpenId.Test.Mocks;
using NUnit.Framework;
-using ProviderMemoryStore = DotNetOpenId.AssociationMemoryStore<DotNetOpenId.AssociationRelyingPartyType>;
+using OpenIdProvider = DotNetOpenId.Provider.OpenIdProvider;
namespace DotNetOpenId.Test.RelyingParty {
[TestFixture]
public class OpenIdRelyingPartyTest {
- IRelyingPartyApplicationStore store;
UriIdentifier simpleOpenId = new UriIdentifier("http://nonexistant.openid.com");
readonly Realm realm = new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri);
readonly Uri returnTo = TestSupport.GetFullUrl(TestSupport.ConsumerPage);
@@ -17,14 +17,13 @@ namespace DotNetOpenId.Test.RelyingParty {
[SetUp]
public void Setup() {
- store = new ApplicationMemoryStore();
if (!UntrustedWebRequest.WhitelistHosts.Contains("localhost"))
UntrustedWebRequest.WhitelistHosts.Add("localhost");
}
[TearDown]
public void TearDown() {
- UntrustedWebRequest.MockRequests = null;
+ MockHttpRequest.Reset();
}
[Test]
@@ -35,7 +34,7 @@ namespace DotNetOpenId.Test.RelyingParty {
[Test]
public void CtorWithNullRequestUri() {
- new OpenIdRelyingParty(store, null, null);
+ new OpenIdRelyingParty(new ApplicationMemoryStore(), null, null);
}
[Test]
@@ -46,59 +45,64 @@ namespace DotNetOpenId.Test.RelyingParty {
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void CreateRequestWithoutContext1() {
- var consumer = new OpenIdRelyingParty(store, simpleNonOpenIdRequest, new NameValueCollection());
+ var consumer = new OpenIdRelyingParty(new ApplicationMemoryStore(), simpleNonOpenIdRequest, new NameValueCollection());
consumer.CreateRequest(simpleOpenId);
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void CreateRequestWithoutContext2() {
- var consumer = new OpenIdRelyingParty(store, simpleNonOpenIdRequest, new NameValueCollection());
+ var consumer = new OpenIdRelyingParty(new ApplicationMemoryStore(), simpleNonOpenIdRequest, new NameValueCollection());
consumer.CreateRequest(simpleOpenId, realm);
}
[Test]
public void CreateRequestStripsFragment() {
- var consumer = new OpenIdRelyingParty(store, simpleNonOpenIdRequest, new NameValueCollection());
+ var consumer = TestSupport.CreateRelyingParty(null);
UriBuilder userSuppliedIdentifier = new UriBuilder((Uri)TestSupport.GetIdentityUrl(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20));
userSuppliedIdentifier.Fragment = "c";
- IAuthenticationRequest request = consumer.CreateRequest(userSuppliedIdentifier.Uri, realm, returnTo);
+ Identifier mockIdentifer = new MockIdentifier(userSuppliedIdentifier.Uri,
+ TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20).Discover());
+ Assert.IsTrue(mockIdentifer.ToString().EndsWith("#c"), "Test broken");
+ IAuthenticationRequest request = consumer.CreateRequest(mockIdentifer, TestSupport.Realm, TestSupport.ReturnTo);
Assert.AreEqual(0, new Uri(request.ClaimedIdentifier).Fragment.Length);
}
[Test]
public void AssociationCreationWithStore() {
- var providerStore = new ProviderMemoryStore();
+ TestSupport.ResetStores(); // get rid of existing associations so a new one is created
- OpenIdRelyingParty rp = new OpenIdRelyingParty(new ApplicationMemoryStore(), null, null);
- var idUrl = TestSupport.GetIdentityUrl(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
+ OpenIdRelyingParty rp = TestSupport.CreateRelyingParty(null);
+ var directMessageSniffer = new DirectMessageSniffWrapper(rp.DirectMessageChannel);
+ rp.DirectMessageChannel = directMessageSniffer;
+ var idUrl = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
DotNetOpenId.RelyingParty.IAuthenticationRequest req;
bool associationMade = false;
- TestSupport.Interceptor.SigningMessage = m => {
- if (m.EncodedFields.ContainsKey("assoc_handle") && m.EncodedFields.ContainsKey("session_type"))
+ directMessageSniffer.Receiving += (provider, fields) => {
+ if (fields.ContainsKey("assoc_handle") && fields.ContainsKey("session_type"))
associationMade = true;
};
req = rp.CreateRequest(idUrl, realm, returnTo);
- TestSupport.Interceptor.SigningMessage = null;
Assert.IsTrue(associationMade);
}
[Test]
public void NoAssociationRequestWithoutStore() {
- var providerStore = new ProviderMemoryStore();
+ TestSupport.ResetStores(); // get rid of existing associations so a new one is created
- OpenIdRelyingParty rp = new OpenIdRelyingParty(null, null, null);
- var idUrl = TestSupport.GetIdentityUrl(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
+ OpenIdRelyingParty rp = TestSupport.CreateRelyingParty(null, null);
+ var directMessageSniffer = new DirectMessageSniffWrapper(rp.DirectMessageChannel);
+ rp.DirectMessageChannel = directMessageSniffer;
+ var idUrl = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
DotNetOpenId.RelyingParty.IAuthenticationRequest req;
bool associationMade = false;
- TestSupport.Interceptor.SigningMessage = m => {
- if (m.EncodedFields.ContainsKey("assoc_handle") && m.EncodedFields.ContainsKey("session_type"))
+ directMessageSniffer.Receiving += (provider, fields) => {
+ if (fields.ContainsKey("assoc_handle") && fields.ContainsKey("session_type"))
associationMade = true;
};
req = rp.CreateRequest(idUrl, realm, returnTo);
- TestSupport.Interceptor.SigningMessage = null;
Assert.IsFalse(associationMade);
}
@@ -128,9 +132,7 @@ namespace DotNetOpenId.Test.RelyingParty {
}
private static void testExplicitPortOnRealmAndReturnTo(Uri returnTo, Realm realm) {
- var identityUrl = TestSupport.GetIdentityUrl(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
- var consumer = new OpenIdRelyingParty(null, null, null);
- var request = consumer.CreateRequest(identityUrl, realm, returnTo);
+ var request = TestSupport.CreateRelyingPartyRequest(true, TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
Protocol protocol = Protocol.Lookup(request.Provider.Version);
var nvc = HttpUtility.ParseQueryString(request.RedirectingResponse.ExtractUrl().Query);
string realmString = nvc[protocol.openid.Realm];
@@ -147,10 +149,7 @@ namespace DotNetOpenId.Test.RelyingParty {
[Test]
public void ReturnToUrlEncodingTest() {
- Uri origin = TestSupport.GetFullUrl(TestSupport.ConsumerPage);
- var identityUrl = TestSupport.GetIdentityUrl(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
- var consumer = new OpenIdRelyingParty(null, null, null);
- var request = consumer.CreateRequest(identityUrl, origin, origin);
+ var request = TestSupport.CreateRelyingPartyRequest(true, TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
Protocol protocol = Protocol.Lookup(request.Provider.Version);
request.AddCallbackArguments("a+b", "c+d");
var requestArgs = HttpUtility.ParseQueryString(request.RedirectingResponse.ExtractUrl().Query);
@@ -205,6 +204,7 @@ namespace DotNetOpenId.Test.RelyingParty {
string xrds = @"<?xml version='1.0' encoding='UTF-8'?>
<XRD xmlns='xri://$xrd*($v*2.0)'>
<Query>=MultipleEndpoint</Query>
+ <Status cid='verified' code='100' />
<ProviderID>=!91F2.8153.F600.AE24</ProviderID>
<CanonicalID>=!91F2.8153.F600.AE24</CanonicalID>
<Service>
@@ -236,9 +236,8 @@ namespace DotNetOpenId.Test.RelyingParty {
</Service>
<ServedBy>OpenXRI</ServedBy>
</XRD>";
- UntrustedWebRequest.MockRequests = TestSupport.GenerateMockXrdsResponses(new Dictionary<string, string> {
+ MockHttpRequest.RegisterMockXrdsResponses(new Dictionary<string, string> {
{"https://xri.net/=MultipleEndpoint?_xrd_r=application/xrd%2Bxml;sep=false", xrds},
- {"https://xri.net/=!91F2.8153.F600.AE24?_xrd_r=application/xrd%2Bxml;sep=false", xrds},
});
OpenIdRelyingParty rp = new OpenIdRelyingParty(null, null, null);
Realm realm = new Realm("http://somerealm");
@@ -248,12 +247,181 @@ namespace DotNetOpenId.Test.RelyingParty {
rp.EndpointOrder = (se1, se2) => -se1.ServicePriority.Value.CompareTo(se2.ServicePriority.Value);
request = rp.CreateRequest("=MultipleEndpoint", realm, return_to);
Assert.AreEqual("https://authn.freexri.com/auth10/", request.Provider.Uri.AbsoluteUri);
-
+
// Now test the filter. Auth20 would come out on top, if we didn't select it out with the filter.
rp.EndpointOrder = OpenIdRelyingParty.DefaultEndpointOrder;
rp.EndpointFilter = (se) => se.Uri.AbsoluteUri == "https://authn.freexri.com/auth10/";
request = rp.CreateRequest("=MultipleEndpoint", realm, return_to);
Assert.AreEqual("https://authn.freexri.com/auth10/", request.Provider.Uri.AbsoluteUri);
}
+
+ private string stripScheme(string identifier) {
+ return identifier.Substring(identifier.IndexOf("://") + 3);
+ }
+
+ [Test]
+ public void RequireSslPrependsHttpsScheme() {
+ MockHttpRequest.Reset();
+ OpenIdRelyingParty rp = TestSupport.CreateRelyingParty(null);
+ rp.Settings.RequireSsl = true;
+ Identifier mockId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, true);
+ string noSchemeId = stripScheme(mockId);
+ var request = rp.CreateRequest(noSchemeId, TestSupport.Realm, TestSupport.ReturnTo);
+ Assert.IsTrue(request.ClaimedIdentifier.ToString().StartsWith("https://", StringComparison.OrdinalIgnoreCase));
+ }
+
+ [Test]
+ public void DirectedIdentityWithRequireSslSucceeds() {
+ Uri claimedId = TestSupport.GetFullUrl("/secureClaimedId", null, true);
+ Identifier opIdentifier = TestSupport.GetMockOPIdentifier(TestSupport.Scenarios.AutoApproval, claimedId, true, true);
+ var rp = TestSupport.CreateRelyingParty(null);
+ rp.Settings.RequireSsl = true;
+ var rpRequest = rp.CreateRequest(opIdentifier, TestSupport.Realm, TestSupport.ReturnTo);
+ var rpResponse = TestSupport.CreateRelyingPartyResponseThroughProvider(rpRequest, opRequest => {
+ opRequest.IsAuthenticated = true;
+ opRequest.ClaimedIdentifier = claimedId;
+ });
+ Assert.AreEqual(AuthenticationStatus.Authenticated, rpResponse.Status);
+ }
+
+ [Test]
+ public void DirectedIdentityWithRequireSslFailsWithoutSecureIdentity() {
+ Uri claimedId = TestSupport.GetFullUrl("/insecureClaimedId", null, false);
+ Identifier opIdentifier = TestSupport.GetMockOPIdentifier(TestSupport.Scenarios.AutoApproval, claimedId, true, true);
+ var rp = TestSupport.CreateRelyingParty(null);
+ rp.Settings.RequireSsl = true;
+ var rpRequest = rp.CreateRequest(opIdentifier, TestSupport.Realm, TestSupport.ReturnTo);
+ var rpResponse = TestSupport.CreateRelyingPartyResponseThroughProvider(rpRequest, opRequest => {
+ opRequest.IsAuthenticated = true;
+ opRequest.ClaimedIdentifier = claimedId;
+ });
+ Assert.AreEqual(AuthenticationStatus.Failed, rpResponse.Status);
+ }
+
+ [Test]
+ public void DirectedIdentityWithRequireSslFailsWithoutSecureProviderEndpoint() {
+ Uri claimedId = TestSupport.GetFullUrl("/secureClaimedId", null, true);
+ // We want to generate an OP Identifier that itself is secure, but whose
+ // XRDS doc describes an insecure provider endpoint.
+ Identifier opIdentifier = TestSupport.GetMockOPIdentifier(TestSupport.Scenarios.AutoApproval, claimedId, true, false);
+ var rp = TestSupport.CreateRelyingParty(null);
+ rp.Settings.RequireSsl = true;
+ var rpRequest = rp.CreateRequest(opIdentifier, TestSupport.Realm, TestSupport.ReturnTo);
+ var rpResponse = TestSupport.CreateRelyingPartyResponseThroughProvider(rpRequest, opRequest => {
+ opRequest.IsAuthenticated = true;
+ opRequest.ClaimedIdentifier = claimedId;
+ });
+ Assert.AreEqual(AuthenticationStatus.Failed, rpResponse.Status);
+ }
+
+ [Test]
+ public void UnsolicitedAssertionWithRequireSsl() {
+ MockHttpRequest.Reset();
+ Mocks.MockHttpRequest.RegisterMockRPDiscovery();
+ TestSupport.Scenarios scenario = TestSupport.Scenarios.AutoApproval;
+ Identifier claimedId = TestSupport.GetMockIdentifier(scenario, ProtocolVersion.V20, true);
+ Identifier localId = TestSupport.GetDelegateUrl(scenario, true);
+
+ OpenIdProvider op = TestSupport.CreateProvider(null, true);
+ IResponse assertion = op.PrepareUnsolicitedAssertion(TestSupport.Realm, claimedId, localId);
+
+ var opAuthWebResponse = (Response)assertion;
+ var opAuthResponse = (DotNetOpenId.Provider.EncodableResponse)opAuthWebResponse.EncodableMessage;
+ var rp = TestSupport.CreateRelyingParty(TestSupport.RelyingPartyStore, opAuthResponse.RedirectUrl,
+ opAuthResponse.EncodedFields.ToNameValueCollection());
+ rp.Settings.RequireSsl = true;
+
+ Assert.AreEqual(AuthenticationStatus.Authenticated, rp.Response.Status);
+ Assert.AreEqual(claimedId, rp.Response.ClaimedIdentifier);
+ }
+
+ [Test]
+ public void UnsolicitedAssertionWithRequireSslWithoutSecureIdentityUrl() {
+ MockHttpRequest.Reset();
+ Mocks.MockHttpRequest.RegisterMockRPDiscovery();
+ TestSupport.Scenarios scenario = TestSupport.Scenarios.AutoApproval;
+ Identifier claimedId = TestSupport.GetMockIdentifier(scenario, ProtocolVersion.V20);
+ Identifier localId = TestSupport.GetDelegateUrl(scenario);
+
+ OpenIdProvider op = TestSupport.CreateProvider(null);
+ IResponse assertion = op.PrepareUnsolicitedAssertion(TestSupport.Realm, claimedId, localId);
+
+ var opAuthWebResponse = (Response)assertion;
+ var opAuthResponse = (DotNetOpenId.Provider.EncodableResponse)opAuthWebResponse.EncodableMessage;
+ var rp = TestSupport.CreateRelyingParty(TestSupport.RelyingPartyStore, opAuthResponse.RedirectUrl,
+ opAuthResponse.EncodedFields.ToNameValueCollection());
+ rp.Settings.RequireSsl = true;
+
+ Assert.AreEqual(AuthenticationStatus.Failed, rp.Response.Status);
+ Assert.IsNull(rp.Response.ClaimedIdentifier);
+ }
+
+ [Test]
+ public void UnsolicitedAssertionWithRequireSslWithSecureIdentityButInsecureProviderEndpoint() {
+ MockHttpRequest.Reset();
+ Mocks.MockHttpRequest.RegisterMockRPDiscovery();
+ TestSupport.Scenarios scenario = TestSupport.Scenarios.AutoApproval;
+ ProtocolVersion version = ProtocolVersion.V20;
+ ServiceEndpoint providerEndpoint = TestSupport.GetServiceEndpoint(scenario, version, 10, false);
+ Identifier claimedId = new MockIdentifier(TestSupport.GetIdentityUrl(scenario, version, true),
+ new ServiceEndpoint[] { providerEndpoint });
+ Identifier localId = TestSupport.GetDelegateUrl(scenario, true);
+
+ OpenIdProvider op = TestSupport.CreateProvider(null, false);
+ IResponse assertion = op.PrepareUnsolicitedAssertion(TestSupport.Realm, claimedId, localId);
+
+ var opAuthWebResponse = (Response)assertion;
+ var opAuthResponse = (DotNetOpenId.Provider.EncodableResponse)opAuthWebResponse.EncodableMessage;
+ var rp = TestSupport.CreateRelyingParty(TestSupport.RelyingPartyStore, opAuthResponse.RedirectUrl,
+ opAuthResponse.EncodedFields.ToNameValueCollection());
+ rp.Settings.RequireSsl = true;
+
+ Assert.AreEqual(AuthenticationStatus.Failed, rp.Response.Status);
+ Assert.IsNull(rp.Response.ClaimedIdentifier);
+ }
+
+ /// <summary>
+ /// Verifies that an RP will not "discover" endpoints below OpenID 2.0 when appropriate.
+ /// </summary>
+ [Test, ExpectedException(typeof(OpenIdException))]
+ public void MinimumOPVersion20() {
+ MockIdentifier id = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V11);
+
+ var rp = TestSupport.CreateRelyingParty(null);
+ rp.Settings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20;
+ rp.CreateRequest(id, TestSupport.Realm, TestSupport.ReturnTo);
+ }
+
+ /// <summary>
+ /// Verifies that an RP configured to require 2.0 OPs will fail on communicating with 1.x OPs
+ /// that merely advertise 2.0 support but don't really have it.
+ /// </summary>
+ [Test]
+ public void MinimumOPVersion20WithDeceptiveEndpointRealizedAtAuthentication() {
+ // Create an identifier that claims to have a 2.0 OP endpoint.
+ MockIdentifier id = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
+
+ var rp = TestSupport.CreateRelyingParty(null, null);
+
+ IAuthenticationRequest req = rp.CreateRequest(id, TestSupport.Realm, TestSupport.ReturnTo);
+ IResponse providerResponse = TestSupport.CreateProviderResponseToRequest(req, opReq => {
+ opReq.IsAuthenticated = true;
+ });
+
+ var opAuthWebResponse = (Response)providerResponse;
+ var opAuthResponse = (DotNetOpenId.Provider.EncodableResponse)opAuthWebResponse.EncodableMessage;
+ var rp2 =TestSupport. CreateRelyingParty(null, opAuthResponse.RedirectUrl,
+ opAuthResponse.EncodedFields.ToNameValueCollection());
+ rp2.Settings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20;
+ // Rig an intercept between the provider and RP to make our own Provider LOOK like a 1.x provider.
+ var sniffer = new DirectMessageSniffWrapper(rp2.DirectMessageChannel);
+ rp2.DirectMessageChannel = sniffer;
+ sniffer.Receiving += (endpoint, fields) => {
+ fields.Remove(Protocol.v20.openidnp.ns);
+ };
+ var resp = rp2.Response;
+
+ Assert.AreEqual(AuthenticationStatus.Failed, resp.Status, "Authentication should have failed since OP is really a 1.x OP masquerading as a 2.0 OP.");
+ }
}
}