summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs376
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs332
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs210
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestBase.cs136
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Messages/IndirectErrorResponseTests.cs88
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj614
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs942
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/CheckIdRequest.cs132
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs80
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs354
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs666
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.resx418
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequestMode.cs50
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs220
15 files changed, 2312 insertions, 2312 deletions
diff --git a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
index 1f54b32..ba98f08 100644
--- a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
@@ -1,188 +1,188 @@
-//-----------------------------------------------------------------------
-// <copyright file="AssociationHandshakeTests.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OpenId {
- using System;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.Messages;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class AssociationHandshakeTests : OpenIdTestBase {
- [TestInitialize]
- public override void SetUp() {
- base.SetUp();
- }
-
- [TestMethod]
- public void AssociateUnencrypted() {
- this.ParameterizedAssociationTest(new Uri("https://host"));
- }
-
- [TestMethod]
- public void AssociateDiffieHellmanOverHttp() {
- this.ParameterizedAssociationTest(new Uri("http://host"));
- }
-
- [TestMethod, Ignore]
- public void AssociateDiffieHellmanOverHttps() {
- // TODO: test the RP and OP agreeing to use Diffie-Hellman over HTTPS.
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies that the RP and OP can renegotiate an association type if the RP's
- /// initial request for an association is for a type the OP doesn't support.
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateRenegotiateBitLength() {
- // TODO: test where the RP asks for an association type that the OP doesn't support
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies that the RP cannot get caught in an infinite loop if a bad OP
- /// keeps sending it association retry messages.
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateRenegotiateBitLengthRPStopsAfterOneRetry() {
- // TODO: code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies security settings limit RP's initial associate request
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateRequestDeterminedBySecuritySettings() {
- // TODO: Code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies security settings limit RP's acceptance of OP's counter-suggestion
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateRenegotiateLimitedByRPSecuritySettings() {
- // TODO: Code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies security settings limit OP's set of acceptable association types.
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateLimitedByOPSecuritySettings() {
- // TODO: Code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies the RP can recover with no association after receiving an
- /// associate error response from the OP when no suggested association
- /// type is included.
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateContinueAfterOpenIdError() {
- // TODO: Code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Verifies that the RP can recover from an invalid or non-existent
- /// response from the OP, for example in the HTTP timeout case.
- /// </summary>
- [TestMethod, Ignore]
- public void AssociateContinueAfterHttpError() {
- // TODO: Code here
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Runs a parameterized association flow test using all supported OpenID versions.
- /// </summary>
- /// <param name="opEndpoint">The OP endpoint to simulate using.</param>
- private void ParameterizedAssociationTest(Uri opEndpoint) {
- foreach (Protocol protocol in Protocol.AllPracticalVersions) {
- var endpoint = new ProviderEndpointDescription(opEndpoint, protocol.Version);
- var associationType = protocol.Version.Major < 2 ? protocol.Args.SignatureAlgorithm.HMAC_SHA1 : protocol.Args.SignatureAlgorithm.HMAC_SHA256;
- this.ParameterizedAssociationTest(endpoint, associationType);
- }
- }
-
- /// <summary>
- /// Runs a parameterized association flow test.
- /// </summary>
- /// <param name="opDescription">
- /// The description of the Provider that the relying party uses to formulate the request.
- /// The specific host is not used, but the scheme is significant.
- /// </param>
- /// <param name="expectedAssociationType">
- /// The value of the openid.assoc_type parameter expected,
- /// or null if a failure is anticipated.
- /// </param>
- private void ParameterizedAssociationTest(
- ProviderEndpointDescription opDescription,
- string expectedAssociationType) {
- Protocol protocol = Protocol.Lookup(opDescription.ProtocolVersion);
- bool expectSuccess = expectedAssociationType != null;
- bool expectDiffieHellman = !opDescription.Endpoint.IsTransportSecure();
- Association rpAssociation = null, opAssociation;
- AssociateSuccessfulResponse associateSuccessfulResponse = null;
- AssociateUnsuccessfulResponse associateUnsuccessfulResponse = null;
- OpenIdCoordinator coordinator = new OpenIdCoordinator(
- rp => {
- rp.SecuritySettings = this.RelyingPartySecuritySettings;
- rpAssociation = rp.GetAssociation(opDescription);
- },
- op => {
- op.SecuritySettings = this.ProviderSecuritySettings;
- op.AutoRespond();
- });
- coordinator.IncomingMessageFilter = message => {
- Assert.AreSame(opDescription.ProtocolVersion, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, opDescription.ProtocolVersion);
- var associateSuccess = message as AssociateSuccessfulResponse;
- var associateFailed = message as AssociateUnsuccessfulResponse;
- if (associateSuccess != null) {
- associateSuccessfulResponse = associateSuccess;
- }
- if (associateFailed != null) {
- associateUnsuccessfulResponse = associateFailed;
- }
- };
- coordinator.OutgoingMessageFilter = message => {
- Assert.AreSame(opDescription.ProtocolVersion, message.Version, "The message was for version {0} but was expected to be for {1}.", message.Version, opDescription.ProtocolVersion);
- };
- coordinator.Run();
-
- if (expectSuccess) {
- Assert.IsNotNull(rpAssociation);
- Assert.AreSame(rpAssociation, coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint, rpAssociation.Handle));
- opAssociation = coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart, rpAssociation.Handle);
- Assert.IsNotNull(opAssociation, "The Provider should have stored the association.");
-
- Assert.AreEqual(opAssociation.Handle, rpAssociation.Handle);
- Assert.AreEqual(expectedAssociationType, rpAssociation.GetAssociationType(protocol));
- Assert.AreEqual(expectedAssociationType, opAssociation.GetAssociationType(protocol));
- Assert.IsTrue(Math.Abs(opAssociation.SecondsTillExpiration - rpAssociation.SecondsTillExpiration) < 60);
- Assert.IsTrue(MessagingUtilities.AreEquivalent(opAssociation.SecretKey, rpAssociation.SecretKey));
-
- if (expectDiffieHellman) {
- Assert.IsInstanceOfType(associateSuccessfulResponse, typeof(AssociateDiffieHellmanResponse));
- var diffieHellmanResponse = (AssociateDiffieHellmanResponse)associateSuccessfulResponse;
- Assert.IsFalse(MessagingUtilities.AreEquivalent(diffieHellmanResponse.EncodedMacKey, rpAssociation.SecretKey), "Key should have been encrypted.");
- } else {
- Assert.IsInstanceOfType(associateSuccessfulResponse, typeof(AssociateUnencryptedResponse));
- var unencryptedResponse = (AssociateUnencryptedResponse)associateSuccessfulResponse;
- }
- } else {
- Assert.IsNull(coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint));
- Assert.IsNull(coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart));
- }
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="AssociationHandshakeTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Messages;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class AssociationHandshakeTests : OpenIdTestBase {
+ [TestInitialize]
+ public override void SetUp() {
+ base.SetUp();
+ }
+
+ [TestMethod]
+ public void AssociateUnencrypted() {
+ this.ParameterizedAssociationTest(new Uri("https://host"));
+ }
+
+ [TestMethod]
+ public void AssociateDiffieHellmanOverHttp() {
+ this.ParameterizedAssociationTest(new Uri("http://host"));
+ }
+
+ [TestMethod, Ignore]
+ public void AssociateDiffieHellmanOverHttps() {
+ // TODO: test the RP and OP agreeing to use Diffie-Hellman over HTTPS.
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies that the RP and OP can renegotiate an association type if the RP's
+ /// initial request for an association is for a type the OP doesn't support.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateRenegotiateBitLength() {
+ // TODO: test where the RP asks for an association type that the OP doesn't support
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies that the RP cannot get caught in an infinite loop if a bad OP
+ /// keeps sending it association retry messages.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateRenegotiateBitLengthRPStopsAfterOneRetry() {
+ // TODO: code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies security settings limit RP's initial associate request
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateRequestDeterminedBySecuritySettings() {
+ // TODO: Code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies security settings limit RP's acceptance of OP's counter-suggestion
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateRenegotiateLimitedByRPSecuritySettings() {
+ // TODO: Code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies security settings limit OP's set of acceptable association types.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateLimitedByOPSecuritySettings() {
+ // TODO: Code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies the RP can recover with no association after receiving an
+ /// associate error response from the OP when no suggested association
+ /// type is included.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateContinueAfterOpenIdError() {
+ // TODO: Code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Verifies that the RP can recover from an invalid or non-existent
+ /// response from the OP, for example in the HTTP timeout case.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void AssociateContinueAfterHttpError() {
+ // TODO: Code here
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Runs a parameterized association flow test using all supported OpenID versions.
+ /// </summary>
+ /// <param name="opEndpoint">The OP endpoint to simulate using.</param>
+ private void ParameterizedAssociationTest(Uri opEndpoint) {
+ foreach (Protocol protocol in Protocol.AllPracticalVersions) {
+ var endpoint = new ProviderEndpointDescription(opEndpoint, protocol.Version);
+ var associationType = protocol.Version.Major < 2 ? protocol.Args.SignatureAlgorithm.HMAC_SHA1 : protocol.Args.SignatureAlgorithm.HMAC_SHA256;
+ this.ParameterizedAssociationTest(endpoint, associationType);
+ }
+ }
+
+ /// <summary>
+ /// Runs a parameterized association flow test.
+ /// </summary>
+ /// <param name="opDescription">
+ /// The description of the Provider that the relying party uses to formulate the request.
+ /// The specific host is not used, but the scheme is significant.
+ /// </param>
+ /// <param name="expectedAssociationType">
+ /// The value of the openid.assoc_type parameter expected,
+ /// or null if a failure is anticipated.
+ /// </param>
+ private void ParameterizedAssociationTest(
+ ProviderEndpointDescription opDescription,
+ string expectedAssociationType) {
+ Protocol protocol = Protocol.Lookup(opDescription.ProtocolVersion);
+ bool expectSuccess = expectedAssociationType != null;
+ bool expectDiffieHellman = !opDescription.Endpoint.IsTransportSecure();
+ Association rpAssociation = null, opAssociation;
+ AssociateSuccessfulResponse associateSuccessfulResponse = null;
+ AssociateUnsuccessfulResponse associateUnsuccessfulResponse = null;
+ OpenIdCoordinator coordinator = new OpenIdCoordinator(
+ rp => {
+ rp.SecuritySettings = this.RelyingPartySecuritySettings;
+ rpAssociation = rp.GetAssociation(opDescription);
+ },
+ op => {
+ op.SecuritySettings = this.ProviderSecuritySettings;
+ op.AutoRespond();
+ });
+ coordinator.IncomingMessageFilter = message => {
+ Assert.AreSame(opDescription.ProtocolVersion, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, opDescription.ProtocolVersion);
+ var associateSuccess = message as AssociateSuccessfulResponse;
+ var associateFailed = message as AssociateUnsuccessfulResponse;
+ if (associateSuccess != null) {
+ associateSuccessfulResponse = associateSuccess;
+ }
+ if (associateFailed != null) {
+ associateUnsuccessfulResponse = associateFailed;
+ }
+ };
+ coordinator.OutgoingMessageFilter = message => {
+ Assert.AreSame(opDescription.ProtocolVersion, message.Version, "The message was for version {0} but was expected to be for {1}.", message.Version, opDescription.ProtocolVersion);
+ };
+ coordinator.Run();
+
+ if (expectSuccess) {
+ Assert.IsNotNull(rpAssociation);
+ Assert.AreSame(rpAssociation, coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint, rpAssociation.Handle));
+ opAssociation = coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart, rpAssociation.Handle);
+ Assert.IsNotNull(opAssociation, "The Provider should have stored the association.");
+
+ Assert.AreEqual(opAssociation.Handle, rpAssociation.Handle);
+ Assert.AreEqual(expectedAssociationType, rpAssociation.GetAssociationType(protocol));
+ Assert.AreEqual(expectedAssociationType, opAssociation.GetAssociationType(protocol));
+ Assert.IsTrue(Math.Abs(opAssociation.SecondsTillExpiration - rpAssociation.SecondsTillExpiration) < 60);
+ Assert.IsTrue(MessagingUtilities.AreEquivalent(opAssociation.SecretKey, rpAssociation.SecretKey));
+
+ if (expectDiffieHellman) {
+ Assert.IsInstanceOfType(associateSuccessfulResponse, typeof(AssociateDiffieHellmanResponse));
+ var diffieHellmanResponse = (AssociateDiffieHellmanResponse)associateSuccessfulResponse;
+ Assert.IsFalse(MessagingUtilities.AreEquivalent(diffieHellmanResponse.EncodedMacKey, rpAssociation.SecretKey), "Key should have been encrypted.");
+ } else {
+ Assert.IsInstanceOfType(associateSuccessfulResponse, typeof(AssociateUnencryptedResponse));
+ var unencryptedResponse = (AssociateUnencryptedResponse)associateSuccessfulResponse;
+ }
+ } else {
+ Assert.IsNull(coordinator.RelyingParty.AssociationStore.GetAssociation(opDescription.Endpoint));
+ Assert.IsNull(coordinator.Provider.AssociationStore.GetAssociation(AssociationRelyingPartyType.Smart));
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
index 99c3ad1..d05ddd8 100644
--- a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
@@ -1,166 +1,166 @@
-//-----------------------------------------------------------------------
-// <copyright file="AuthenticationTests.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OpenId {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.ChannelElements;
- using DotNetOpenAuth.OpenId.Messages;
- using DotNetOpenAuth.OpenId.RelyingParty;
- using DotNetOpenAuth.Test.Mocks;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class AuthenticationTests : OpenIdTestBase {
- [TestInitialize]
- public override void SetUp() {
- base.SetUp();
- }
-
- [TestMethod]
- public void SharedAssociationPositive() {
- this.ParameterizedPositiveAuthenticationTest(true, true, false);
- }
-
- /// <summary>
- /// Verifies that a shared association protects against tampering.
- /// </summary>
- [TestMethod]
- public void SharedAssociationTampered() {
- this.ParameterizedPositiveAuthenticationTest(true, true, true);
- }
-
- [TestMethod]
- public void SharedAssociationNegative() {
- this.ParameterizedPositiveAuthenticationTest(true, false, false);
- }
-
- [TestMethod]
- public void PrivateAssociationPositive() {
- this.ParameterizedPositiveAuthenticationTest(false, true, false);
- }
-
- /// <summary>
- /// Verifies that a private association protects against tampering.
- /// </summary>
- [TestMethod]
- public void PrivateAssociationTampered() {
- this.ParameterizedPositiveAuthenticationTest(false, true, true);
- }
-
- [TestMethod]
- public void NoAssociationNegative() {
- this.ParameterizedPositiveAuthenticationTest(false, false, false);
- }
-
- private void ParameterizedPositiveAuthenticationTest(bool sharedAssociation, bool positive, bool tamper) {
- foreach (Protocol protocol in Protocol.AllPracticalVersions) {
- this.ParameterizedPositiveAuthenticationTest(protocol, sharedAssociation, positive, tamper);
- }
- }
-
- private void ParameterizedPositiveAuthenticationTest(Protocol protocol, bool sharedAssociation, bool positive, bool tamper) {
- ErrorUtilities.VerifyArgument(positive || !tamper, "Cannot tamper with a negative response.");
- Uri userSetupUrl = protocol.Version.Major < 2 ? new Uri("http://usersetupurl") : null;
- Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart) : null;
- var coordinator = new OpenIdCoordinator(
- rp => {
- var request = new CheckIdRequest(protocol.Version, ProviderUri, AuthenticationRequestMode.Immediate);
-
- if (association != null) {
- rp.AssociationStore.StoreAssociation(ProviderUri, association);
- request.AssociationHandle = association.Handle;
- }
-
- request.ClaimedIdentifier = "http://claimedid";
- request.LocalIdentifier = "http://localid";
- request.ReturnTo = RPUri;
- rp.Channel.Send(request);
- if (positive) {
- if (tamper) {
- try {
- rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
- Assert.Fail("Expected exception {0} not thrown.", typeof(InvalidSignatureException).Name);
- } catch (InvalidSignatureException) {
- TestLogger.InfoFormat("Caught expected {0} exception after tampering with signed data.", typeof(InvalidSignatureException).Name);
- }
- } else {
- var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
- Assert.IsNotNull(response);
- Assert.AreEqual(request.ClaimedIdentifier, response.ClaimedIdentifier);
- Assert.AreEqual(request.LocalIdentifier, response.LocalIdentifier);
- Assert.AreEqual(request.ReturnTo, response.ReturnTo);
-
- // Attempt to replay the message and verify that it fails.
- // Because in various scenarios and protocol versions different components
- // notice the replay, we can get one of two exceptions thrown.
- // When the OP notices the replay we get a generic InvalidSignatureException.
- // When the RP notices the replay we get a specific ReplayMessageException.
- Type expectedExceptionType = sharedAssociation || protocol.Version.Major < 2 ? typeof(ReplayedMessageException) : typeof(InvalidSignatureException);
- try {
- CoordinatingChannel channel = (CoordinatingChannel)rp.Channel;
- channel.Replay(response);
- Assert.Fail("Expected exception {0} was not thrown.", expectedExceptionType.Name);
- } catch (ProtocolException ex) {
- Assert.IsInstanceOfType(ex, expectedExceptionType);
- }
- }
- } else {
- var response = rp.Channel.ReadFromRequest<NegativeAssertionResponse>();
- Assert.IsNotNull(response);
- Assert.AreEqual(userSetupUrl, response.UserSetupUrl);
- }
- },
- op => {
- if (association != null) {
- op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association);
- }
-
- var request = op.Channel.ReadFromRequest<CheckIdRequest>();
- Assert.IsNotNull(request);
- IProtocolMessage response;
- if (positive) {
- response = new PositiveAssertionResponse(request);
- } else {
- response = new NegativeAssertionResponse(request) { UserSetupUrl = userSetupUrl };
- }
- op.Channel.Send(response);
-
- if (positive && !sharedAssociation) {
- var checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
- var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest);
- checkauthResponse.IsValid = checkauthRequest.IsValid;
- op.Channel.Send(checkauthResponse);
-
- if (!tamper) {
- // Respond to the replay attack.
- checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
- checkauthResponse = new CheckAuthenticationResponse(checkauthRequest);
- checkauthResponse.IsValid = checkauthRequest.IsValid;
- op.Channel.Send(checkauthResponse);
- }
- }
- });
- if (tamper) {
- coordinator.IncomingMessageFilter = message => {
- var assertion = message as PositiveAssertionResponse;
- if (assertion != null) {
- // Alter the Local Identifier between the Provider and the Relying Party.
- // If the signature binding element does its job, this should cause the RP
- // to throw.
- assertion.LocalIdentifier = "http://victim";
- }
- };
- }
- coordinator.Run();
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="AuthenticationTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.ChannelElements;
+ using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using DotNetOpenAuth.Test.Mocks;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class AuthenticationTests : OpenIdTestBase {
+ [TestInitialize]
+ public override void SetUp() {
+ base.SetUp();
+ }
+
+ [TestMethod]
+ public void SharedAssociationPositive() {
+ this.ParameterizedPositiveAuthenticationTest(true, true, false);
+ }
+
+ /// <summary>
+ /// Verifies that a shared association protects against tampering.
+ /// </summary>
+ [TestMethod]
+ public void SharedAssociationTampered() {
+ this.ParameterizedPositiveAuthenticationTest(true, true, true);
+ }
+
+ [TestMethod]
+ public void SharedAssociationNegative() {
+ this.ParameterizedPositiveAuthenticationTest(true, false, false);
+ }
+
+ [TestMethod]
+ public void PrivateAssociationPositive() {
+ this.ParameterizedPositiveAuthenticationTest(false, true, false);
+ }
+
+ /// <summary>
+ /// Verifies that a private association protects against tampering.
+ /// </summary>
+ [TestMethod]
+ public void PrivateAssociationTampered() {
+ this.ParameterizedPositiveAuthenticationTest(false, true, true);
+ }
+
+ [TestMethod]
+ public void NoAssociationNegative() {
+ this.ParameterizedPositiveAuthenticationTest(false, false, false);
+ }
+
+ private void ParameterizedPositiveAuthenticationTest(bool sharedAssociation, bool positive, bool tamper) {
+ foreach (Protocol protocol in Protocol.AllPracticalVersions) {
+ this.ParameterizedPositiveAuthenticationTest(protocol, sharedAssociation, positive, tamper);
+ }
+ }
+
+ private void ParameterizedPositiveAuthenticationTest(Protocol protocol, bool sharedAssociation, bool positive, bool tamper) {
+ ErrorUtilities.VerifyArgument(positive || !tamper, "Cannot tamper with a negative response.");
+ Uri userSetupUrl = protocol.Version.Major < 2 ? new Uri("http://usersetupurl") : null;
+ Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart) : null;
+ var coordinator = new OpenIdCoordinator(
+ rp => {
+ var request = new CheckIdRequest(protocol.Version, ProviderUri, AuthenticationRequestMode.Immediate);
+
+ if (association != null) {
+ rp.AssociationStore.StoreAssociation(ProviderUri, association);
+ request.AssociationHandle = association.Handle;
+ }
+
+ request.ClaimedIdentifier = "http://claimedid";
+ request.LocalIdentifier = "http://localid";
+ request.ReturnTo = RPUri;
+ rp.Channel.Send(request);
+ if (positive) {
+ if (tamper) {
+ try {
+ rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
+ Assert.Fail("Expected exception {0} not thrown.", typeof(InvalidSignatureException).Name);
+ } catch (InvalidSignatureException) {
+ TestLogger.InfoFormat("Caught expected {0} exception after tampering with signed data.", typeof(InvalidSignatureException).Name);
+ }
+ } else {
+ var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
+ Assert.IsNotNull(response);
+ Assert.AreEqual(request.ClaimedIdentifier, response.ClaimedIdentifier);
+ Assert.AreEqual(request.LocalIdentifier, response.LocalIdentifier);
+ Assert.AreEqual(request.ReturnTo, response.ReturnTo);
+
+ // Attempt to replay the message and verify that it fails.
+ // Because in various scenarios and protocol versions different components
+ // notice the replay, we can get one of two exceptions thrown.
+ // When the OP notices the replay we get a generic InvalidSignatureException.
+ // When the RP notices the replay we get a specific ReplayMessageException.
+ Type expectedExceptionType = sharedAssociation || protocol.Version.Major < 2 ? typeof(ReplayedMessageException) : typeof(InvalidSignatureException);
+ try {
+ CoordinatingChannel channel = (CoordinatingChannel)rp.Channel;
+ channel.Replay(response);
+ Assert.Fail("Expected exception {0} was not thrown.", expectedExceptionType.Name);
+ } catch (ProtocolException ex) {
+ Assert.IsInstanceOfType(ex, expectedExceptionType);
+ }
+ }
+ } else {
+ var response = rp.Channel.ReadFromRequest<NegativeAssertionResponse>();
+ Assert.IsNotNull(response);
+ Assert.AreEqual(userSetupUrl, response.UserSetupUrl);
+ }
+ },
+ op => {
+ if (association != null) {
+ op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association);
+ }
+
+ var request = op.Channel.ReadFromRequest<CheckIdRequest>();
+ Assert.IsNotNull(request);
+ IProtocolMessage response;
+ if (positive) {
+ response = new PositiveAssertionResponse(request);
+ } else {
+ response = new NegativeAssertionResponse(request) { UserSetupUrl = userSetupUrl };
+ }
+ op.Channel.Send(response);
+
+ if (positive && !sharedAssociation) {
+ var checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
+ var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest);
+ checkauthResponse.IsValid = checkauthRequest.IsValid;
+ op.Channel.Send(checkauthResponse);
+
+ if (!tamper) {
+ // Respond to the replay attack.
+ checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
+ checkauthResponse = new CheckAuthenticationResponse(checkauthRequest);
+ checkauthResponse.IsValid = checkauthRequest.IsValid;
+ op.Channel.Send(checkauthResponse);
+ }
+ }
+ });
+ if (tamper) {
+ coordinator.IncomingMessageFilter = message => {
+ var assertion = message as PositiveAssertionResponse;
+ if (assertion != null) {
+ // Alter the Local Identifier between the Provider and the Relying Party.
+ // If the signature binding element does its job, this should cause the RP
+ // to throw.
+ assertion.LocalIdentifier = "http://victim";
+ }
+ };
+ }
+ coordinator.Run();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
index 6ab27b4..298b6d4 100644
--- a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
@@ -1,105 +1,105 @@
-//-----------------------------------------------------------------------
-// <copyright file="ExtensionsBindingElementTests.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.RegularExpressions;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.ChannelElements;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Messages;
- using DotNetOpenAuth.OpenId.RelyingParty;
- using DotNetOpenAuth.Test.Mocks;
- using DotNetOpenAuth.Test.OpenId.Extensions;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class ExtensionsBindingElementTests : OpenIdTestBase {
- private OpenIdExtensionFactory factory;
- private ExtensionsBindingElement element;
- private IProtocolMessageWithExtensions request;
-
- [TestInitialize]
- public override void SetUp() {
- base.SetUp();
-
- this.factory = new OpenIdExtensionFactory();
- this.factory.RegisterExtension(MockOpenIdExtension.Factory);
- this.element = new ExtensionsBindingElement(this.factory);
- this.request = new SignedResponseRequest(Protocol.Default.Version, OpenIdTestBase.ProviderUri, AuthenticationRequestMode.Immediate);
- }
-
- [TestMethod]
- public void RoundTripFullStackTest() {
- IOpenIdMessageExtension request = new MockOpenIdExtension("requestPart", "requestData");
- IOpenIdMessageExtension response = new MockOpenIdExtension("responsePart", "responseData");
- ExtensionTestUtilities.Roundtrip(
- Protocol.Default,
- new IOpenIdMessageExtension[] { request },
- new IOpenIdMessageExtension[] { response });
- }
-
- [TestMethod]
- public void ExtensionFactory() {
- Assert.AreSame(this.factory, this.element.ExtensionFactory);
- }
-
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void PrepareMessageForSendingNull() {
- this.element.PrepareMessageForSending(null);
- }
-
- /// <summary>
- /// Verifies that false is returned when a non-extendable message is sent.
- /// </summary>
- [TestMethod]
- public void PrepareMessageForSendingNonExtendableMessage() {
- IProtocolMessage request = new AssociateDiffieHellmanRequest(Protocol.Default.Version, OpenIdTestBase.ProviderUri);
- Assert.IsFalse(this.element.PrepareMessageForSending(request));
- }
-
- [TestMethod]
- public void PrepareMessageForSending() {
- this.request.Extensions.Add(new MockOpenIdExtension("part", "extra"));
- Assert.IsTrue(this.element.PrepareMessageForSending(this.request));
-
- string alias = GetAliases(this.request.ExtraData).Single();
- Assert.AreEqual(MockOpenIdExtension.MockTypeUri, this.request.ExtraData["openid.ns." + alias]);
- Assert.AreEqual("part", this.request.ExtraData["openid." + alias + ".Part"]);
- Assert.AreEqual("extra", this.request.ExtraData["openid." + alias + ".data"]);
- }
-
- [TestMethod]
- public void PrepareMessageForReceiving() {
- this.request.ExtraData["openid.ns.mock"] = MockOpenIdExtension.MockTypeUri;
- this.request.ExtraData["openid.mock.Part"] = "part";
- this.request.ExtraData["openid.mock.data"] = "extra";
- Assert.IsTrue(this.element.PrepareMessageForReceiving(this.request));
- MockOpenIdExtension ext = this.request.Extensions.OfType<MockOpenIdExtension>().Single();
- Assert.AreEqual("part", ext.Part);
- Assert.AreEqual("extra", ext.Data);
- }
-
- /// <summary>
- /// Verifies that unsigned extension responses (where any or all fields are unsigned) are ignored.
- /// </summary>
- [TestMethod, Ignore]
- public void UnsignedExtensionsAreIgnored() {
- Assert.Inconclusive("Not yet implemented.");
- }
-
- private static IEnumerable<string> GetAliases(IDictionary<string, string> extraData) {
- Regex regex = new Regex(@"^openid\.ns\.(\w+)");
- return from key in extraData.Keys
- let m = regex.Match(key)
- where m.Success
- select m.Groups[1].Value;
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="ExtensionsBindingElementTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text.RegularExpressions;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.ChannelElements;
+ using DotNetOpenAuth.OpenId.Extensions;
+ using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using DotNetOpenAuth.Test.Mocks;
+ using DotNetOpenAuth.Test.OpenId.Extensions;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class ExtensionsBindingElementTests : OpenIdTestBase {
+ private OpenIdExtensionFactory factory;
+ private ExtensionsBindingElement element;
+ private IProtocolMessageWithExtensions request;
+
+ [TestInitialize]
+ public override void SetUp() {
+ base.SetUp();
+
+ this.factory = new OpenIdExtensionFactory();
+ this.factory.RegisterExtension(MockOpenIdExtension.Factory);
+ this.element = new ExtensionsBindingElement(this.factory);
+ this.request = new SignedResponseRequest(Protocol.Default.Version, OpenIdTestBase.ProviderUri, AuthenticationRequestMode.Immediate);
+ }
+
+ [TestMethod]
+ public void RoundTripFullStackTest() {
+ IOpenIdMessageExtension request = new MockOpenIdExtension("requestPart", "requestData");
+ IOpenIdMessageExtension response = new MockOpenIdExtension("responsePart", "responseData");
+ ExtensionTestUtilities.Roundtrip(
+ Protocol.Default,
+ new IOpenIdMessageExtension[] { request },
+ new IOpenIdMessageExtension[] { response });
+ }
+
+ [TestMethod]
+ public void ExtensionFactory() {
+ Assert.AreSame(this.factory, this.element.ExtensionFactory);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void PrepareMessageForSendingNull() {
+ this.element.PrepareMessageForSending(null);
+ }
+
+ /// <summary>
+ /// Verifies that false is returned when a non-extendable message is sent.
+ /// </summary>
+ [TestMethod]
+ public void PrepareMessageForSendingNonExtendableMessage() {
+ IProtocolMessage request = new AssociateDiffieHellmanRequest(Protocol.Default.Version, OpenIdTestBase.ProviderUri);
+ Assert.IsFalse(this.element.PrepareMessageForSending(request));
+ }
+
+ [TestMethod]
+ public void PrepareMessageForSending() {
+ this.request.Extensions.Add(new MockOpenIdExtension("part", "extra"));
+ Assert.IsTrue(this.element.PrepareMessageForSending(this.request));
+
+ string alias = GetAliases(this.request.ExtraData).Single();
+ Assert.AreEqual(MockOpenIdExtension.MockTypeUri, this.request.ExtraData["openid.ns." + alias]);
+ Assert.AreEqual("part", this.request.ExtraData["openid." + alias + ".Part"]);
+ Assert.AreEqual("extra", this.request.ExtraData["openid." + alias + ".data"]);
+ }
+
+ [TestMethod]
+ public void PrepareMessageForReceiving() {
+ this.request.ExtraData["openid.ns.mock"] = MockOpenIdExtension.MockTypeUri;
+ this.request.ExtraData["openid.mock.Part"] = "part";
+ this.request.ExtraData["openid.mock.data"] = "extra";
+ Assert.IsTrue(this.element.PrepareMessageForReceiving(this.request));
+ MockOpenIdExtension ext = this.request.Extensions.OfType<MockOpenIdExtension>().Single();
+ Assert.AreEqual("part", ext.Part);
+ Assert.AreEqual("extra", ext.Data);
+ }
+
+ /// <summary>
+ /// Verifies that unsigned extension responses (where any or all fields are unsigned) are ignored.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void UnsignedExtensionsAreIgnored() {
+ Assert.Inconclusive("Not yet implemented.");
+ }
+
+ private static IEnumerable<string> GetAliases(IDictionary<string, string> extraData) {
+ Regex regex = new Regex(@"^openid\.ns\.(\w+)");
+ return from key in extraData.Keys
+ let m = regex.Match(key)
+ where m.Success
+ select m.Groups[1].Value;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestBase.cs
index fe518f3..c616ed3 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestBase.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestBase.cs
@@ -1,68 +1,68 @@
-//-----------------------------------------------------------------------
-// <copyright file="ExtensionTestBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OpenId.Extensions {
- using System.Collections.Generic;
- using System.Linq;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.ChannelElements;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Messages;
- using DotNetOpenAuth.OpenId.RelyingParty;
- using DotNetOpenAuth.Test.Messaging;
-
- public static class ExtensionTestUtilities {
- internal static void Roundtrip(
- Protocol protocol,
- IEnumerable<IOpenIdMessageExtension> requests,
- IEnumerable<IOpenIdMessageExtension> responses) {
- Association association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart);
- var coordinator = new OpenIdCoordinator(
- rp => {
- RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
- var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.ProviderUri, AuthenticationRequestMode.Immediate);
- rp.AssociationStore.StoreAssociation(OpenIdTestBase.ProviderUri, association);
- requestBase.AssociationHandle = association.Handle;
- requestBase.ClaimedIdentifier = "http://claimedid";
- requestBase.LocalIdentifier = "http://localid";
- requestBase.ReturnTo = OpenIdTestBase.RPUri;
-
- foreach (IOpenIdMessageExtension extension in requests) {
- requestBase.Extensions.Add(extension);
- }
-
- rp.Channel.Send(requestBase);
- var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
-
- var receivedResponses = response.Extensions.Cast<IOpenIdMessageExtension>();
- CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(responses.ToArray(), receivedResponses.ToArray());
- },
- op => {
- RegisterExtension(op.Channel, Mocks.MockOpenIdExtension.Factory);
- op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association);
- var request = op.Channel.ReadFromRequest<CheckIdRequest>();
- var response = new PositiveAssertionResponse(request);
- var receivedRequests = request.Extensions.Cast<IOpenIdMessageExtension>();
- CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(requests.ToArray(), receivedRequests.ToArray());
-
- foreach (var extensionResponse in responses) {
- response.Extensions.Add(extensionResponse);
- }
-
- op.Channel.Send(response);
- });
- coordinator.Run();
- }
-
- internal static void RegisterExtension(Channel channel, OpenIdExtensionFactory.CreateDelegate extensionFactory) {
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
-
- OpenIdExtensionFactory factory = (OpenIdExtensionFactory)channel.BindingElements.OfType<ExtensionsBindingElement>().Single().ExtensionFactory;
- factory.RegisterExtension(extensionFactory);
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="ExtensionTestBase.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.Extensions {
+ using System.Collections.Generic;
+ using System.Linq;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.ChannelElements;
+ using DotNetOpenAuth.OpenId.Extensions;
+ using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using DotNetOpenAuth.Test.Messaging;
+
+ public static class ExtensionTestUtilities {
+ internal static void Roundtrip(
+ Protocol protocol,
+ IEnumerable<IOpenIdMessageExtension> requests,
+ IEnumerable<IOpenIdMessageExtension> responses) {
+ Association association = HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart);
+ var coordinator = new OpenIdCoordinator(
+ rp => {
+ RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
+ var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.ProviderUri, AuthenticationRequestMode.Immediate);
+ rp.AssociationStore.StoreAssociation(OpenIdTestBase.ProviderUri, association);
+ requestBase.AssociationHandle = association.Handle;
+ requestBase.ClaimedIdentifier = "http://claimedid";
+ requestBase.LocalIdentifier = "http://localid";
+ requestBase.ReturnTo = OpenIdTestBase.RPUri;
+
+ foreach (IOpenIdMessageExtension extension in requests) {
+ requestBase.Extensions.Add(extension);
+ }
+
+ rp.Channel.Send(requestBase);
+ var response = rp.Channel.ReadFromRequest<PositiveAssertionResponse>();
+
+ var receivedResponses = response.Extensions.Cast<IOpenIdMessageExtension>();
+ CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(responses.ToArray(), receivedResponses.ToArray());
+ },
+ op => {
+ RegisterExtension(op.Channel, Mocks.MockOpenIdExtension.Factory);
+ op.AssociationStore.StoreAssociation(AssociationRelyingPartyType.Smart, association);
+ var request = op.Channel.ReadFromRequest<CheckIdRequest>();
+ var response = new PositiveAssertionResponse(request);
+ var receivedRequests = request.Extensions.Cast<IOpenIdMessageExtension>();
+ CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(requests.ToArray(), receivedRequests.ToArray());
+
+ foreach (var extensionResponse in responses) {
+ response.Extensions.Add(extensionResponse);
+ }
+
+ op.Channel.Send(response);
+ });
+ coordinator.Run();
+ }
+
+ internal static void RegisterExtension(Channel channel, OpenIdExtensionFactory.CreateDelegate extensionFactory) {
+ ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+
+ OpenIdExtensionFactory factory = (OpenIdExtensionFactory)channel.BindingElements.OfType<ExtensionsBindingElement>().Single().ExtensionFactory;
+ factory.RegisterExtension(extensionFactory);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectErrorResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectErrorResponseTests.cs
index d12aa29..093518d 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectErrorResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectErrorResponseTests.cs
@@ -1,45 +1,45 @@
-//-----------------------------------------------------------------------
-// <copyright file="IndirectErrorResponseTests.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OpenId.Messages {
- using System;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.Messages;
- using DotNetOpenAuth.OpenId.RelyingParty;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class IndirectErrorResponseTests : OpenIdTestBase {
- private IndirectErrorResponse response;
-
- [TestInitialize]
- public void Setup() {
- CheckIdRequest request = new CheckIdRequest(Protocol.V20.Version, ProviderUri, AuthenticationRequestMode.Immediate);
- request.ReturnTo = RPUri;
- this.response = new IndirectErrorResponse(request);
- }
-
- [TestMethod]
- public void Ctor() {
- Assert.AreEqual(RPUri, this.response.Recipient);
- }
-
- [TestMethod]
- public void ParameterNames() {
- this.response.ErrorMessage = "Some Error";
- this.response.Contact = "Andrew Arnott";
- this.response.Reference = "http://blog.nerdbank.net/";
-
- MessageSerializer serializer = MessageSerializer.Get(this.response.GetType());
- var fields = serializer.Serialize(this.response);
- Assert.AreEqual(Protocol.OpenId2Namespace, fields["openid.ns"]);
- Assert.AreEqual("Some Error", fields["openid.error"]);
- Assert.AreEqual("Andrew Arnott", fields["openid.contact"]);
- Assert.AreEqual("http://blog.nerdbank.net/", fields["openid.reference"]);
- }
- }
+//-----------------------------------------------------------------------
+// <copyright file="IndirectErrorResponseTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.Messages {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class IndirectErrorResponseTests : OpenIdTestBase {
+ private IndirectErrorResponse response;
+
+ [TestInitialize]
+ public void Setup() {
+ CheckIdRequest request = new CheckIdRequest(Protocol.V20.Version, ProviderUri, AuthenticationRequestMode.Immediate);
+ request.ReturnTo = RPUri;
+ this.response = new IndirectErrorResponse(request);
+ }
+
+ [TestMethod]
+ public void Ctor() {
+ Assert.AreEqual(RPUri, this.response.Recipient);
+ }
+
+ [TestMethod]
+ public void ParameterNames() {
+ this.response.ErrorMessage = "Some Error";
+ this.response.Contact = "Andrew Arnott";
+ this.response.Reference = "http://blog.nerdbank.net/";
+
+ MessageSerializer serializer = MessageSerializer.Get(this.response.GetType());
+ var fields = serializer.Serialize(this.response);
+ Assert.AreEqual(Protocol.OpenId2Namespace, fields["openid.ns"]);
+ Assert.AreEqual("Some Error", fields["openid.error"]);
+ Assert.AreEqual("Andrew Arnott", fields["openid.contact"]);
+ Assert.AreEqual("http://blog.nerdbank.net/", fields["openid.reference"]);
+ }
+ }
} \ No newline at end of file
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index fa89999..994548a 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -1,308 +1,308 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>DotNetOpenAuth</RootNamespace>
- <AssemblyName>DotNetOpenAuth</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\..\bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile>
- <RunCodeAnalysis>false</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>..\..\bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <DocumentationFile>..\..\bin\debug\DotNetOpenAuth.xml</DocumentationFile>
- <RunCodeAnalysis>true</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
- <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\lib\log4net.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.configuration" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.ServiceModel">
- <RequiredTargetFramework>3.0</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Web" />
- <Reference Include="System.XML" />
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Configuration\ProviderSection.cs" />
- <Compile Include="Configuration\ProviderSecuritySettingsElement.cs" />
- <Compile Include="Configuration\RelyingPartySection.cs" />
- <Compile Include="Configuration\RelyingPartySecuritySettingsElement.cs" />
- <Compile Include="Configuration\TypeConfigurationElement.cs" />
- <Compile Include="Configuration\UntrustedWebRequestSection.cs" />
- <Compile Include="Configuration\HostNameOrRegexCollection.cs" />
- <Compile Include="Configuration\HostNameElement.cs" />
- <Compile Include="Messaging\IExtensionMessage.cs" />
- <Compile Include="Messaging\IMessage.cs" />
- <Compile Include="Messaging\DirectWebResponse.cs" />
- <Compile Include="Messaging\IDirectResponseProtocolMessage.cs" />
- <Compile Include="Messaging\EmptyDictionary.cs" />
- <Compile Include="Messaging\EmptyEnumerator.cs" />
- <Compile Include="Messaging\EmptyList.cs" />
- <Compile Include="Messaging\ErrorUtilities.cs" />
- <Compile Include="Messaging\IDirectSslWebRequestHandler.cs" />
- <Compile Include="Messaging\IProtocolMessageWithExtensions.cs" />
- <Compile Include="Messaging\InternalErrorException.cs" />
- <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthConsumerMessageFactory.cs" />
- <Compile Include="OAuth\ChannelElements\ITokenGenerator.cs" />
- <Compile Include="OAuth\ChannelElements\ITokenManager.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthHttpMethodBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElement.cs" />
- <Compile Include="OAuth\ChannelElements\SigningBindingElementChain.cs" />
- <Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" />
- <Compile Include="OAuth\ChannelElements\TokenType.cs" />
- <Compile Include="OAuth\ConsumerBase.cs" />
- <Compile Include="OAuth\DesktopConsumer.cs" />
- <Compile Include="GlobalSuppressions.cs" />
- <Compile Include="OAuth\Messages\ITokenSecretContainingMessage.cs" />
- <Compile Include="Messaging\ChannelEventArgs.cs" />
- <Compile Include="Messaging\ITamperProtectionChannelBindingElement.cs" />
- <Compile Include="OAuth\OAuthStrings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>OAuthStrings.resx</DependentUpon>
- </Compile>
- <Compile Include="OAuth\ServiceProviderDescription.cs" />
- <Compile Include="OAuth\Messages\ITokenContainingMessage.cs" />
- <Compile Include="OAuth\Messages\SignedMessageBase.cs" />
- <Compile Include="Messaging\Bindings\NonceMemoryStore.cs" />
- <Compile Include="OAuth\ChannelElements\SigningBindingElementBase.cs" />
- <Compile Include="OAuth\WebConsumer.cs" />
- <Compile Include="Messaging\IDirectWebRequestHandler.cs" />
- <Compile Include="OAuth\ChannelElements\ITamperResistantOAuthMessage.cs" />
- <Compile Include="OAuth\Messages\MessageBase.cs" />
- <Compile Include="OAuth\Messages\AuthorizedTokenRequest.cs" />
- <Compile Include="Messaging\Bindings\INonceStore.cs" />
- <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElement.cs" />
- <Compile Include="Messaging\MessagePartAttribute.cs" />
- <Compile Include="Messaging\MessageProtections.cs" />
- <Compile Include="Messaging\IChannelBindingElement.cs" />
- <Compile Include="Messaging\Bindings\ReplayedMessageException.cs" />
- <Compile Include="Messaging\Bindings\ExpiredMessageException.cs" />
- <Compile Include="Messaging\Bindings\InvalidSignatureException.cs" />
- <Compile Include="Messaging\Bindings\IReplayProtectedProtocolMessage.cs" />
- <Compile Include="Messaging\Bindings\IExpiringProtocolMessage.cs" />
- <Compile Include="OAuth\Messages\AccessProtectedResourceRequest.cs" />
- <Compile Include="OAuth\Messages\AuthorizedTokenResponse.cs" />
- <Compile Include="OAuth\Messages\UserAuthorizationResponse.cs" />
- <Compile Include="OAuth\Messages\UserAuthorizationRequest.cs" />
- <Compile Include="OAuth\Messages\UnauthorizedTokenResponse.cs" />
- <Compile Include="Messaging\Channel.cs" />
- <Compile Include="Messaging\HttpRequestInfo.cs" />
- <Compile Include="Messaging\IDirectedProtocolMessage.cs" />
- <Compile Include="Messaging\IMessageFactory.cs" />
- <Compile Include="Messaging\ITamperResistantProtocolMessage.cs" />
- <Compile Include="Messaging\MessageSerializer.cs" />
- <Compile Include="Messaging\MessagingStrings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>MessagingStrings.resx</DependentUpon>
- </Compile>
- <Compile Include="Messaging\MessagingUtilities.cs" />
- <Compile Include="Messaging\Bindings\StandardExpirationBindingElement.cs" />
- <Compile Include="Messaging\Reflection\ValueMapping.cs" />
- <Compile Include="Messaging\Reflection\MessageDescription.cs" />
- <Compile Include="Messaging\Reflection\MessageDictionary.cs" />
- <Compile Include="Messaging\Reflection\MessagePart.cs" />
- <Compile Include="Messaging\UnprotectedMessageException.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthChannel.cs" />
- <Compile Include="Messaging\UserAgentResponse.cs" />
- <Compile Include="Messaging\IProtocolMessage.cs" />
- <Compile Include="Logger.cs" />
- <Compile Include="Loggers\ILog.cs" />
- <Compile Include="Loggers\Log4NetLogger.cs" />
- <Compile Include="Loggers\NoOpLogger.cs" />
- <Compile Include="Loggers\TraceLogger.cs" />
- <Compile Include="Messaging\HttpDeliveryMethods.cs" />
- <Compile Include="Messaging\MessageTransport.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs" />
- <Compile Include="Messaging\ProtocolException.cs" />
- <Compile Include="OpenId\Association.cs" />
- <Compile Include="OpenId\AssociationMemoryStore.cs" />
- <Compile Include="OpenId\Associations.cs" />
- <Compile Include="OpenId\ChannelElements\BackwardCompatibilityBindingElement.cs" />
- <Compile Include="OpenId\ChannelElements\ExtensionsBindingElement.cs" />
- <Compile Include="OpenId\ChannelElements\IOpenIdExtensionFactory.cs" />
- <Compile Include="OpenId\ChannelElements\IPrivateSecretStore.cs" />
- <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" />
- <Compile Include="OpenId\ChannelElements\OriginalStringUriEncoder.cs" />
- <Compile Include="OpenId\ChannelElements\ReturnToNonceBindingElement.cs" />
- <Compile Include="OpenId\ChannelElements\SigningBindingElement.cs" />
- <Compile Include="OpenId\ChannelElements\KeyValueFormEncoding.cs" />
- <Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" />
- <Compile Include="OpenId\ChannelElements\OpenIdMessageFactory.cs" />
- <Compile Include="OpenId\ChannelElements\ReturnToSignatureBindingElement.cs" />
- <Compile Include="OpenId\Configuration.cs" />
- <Compile Include="OpenId\Extensions\AliasManager.cs" />
- <Compile Include="OpenId\Extensions\ExtensionBase.cs" />
- <Compile Include="OpenId\Extensions\ExtensionArgumentsManager.cs" />
- <Compile Include="OpenId\Extensions\OpenIdExtensionFactory.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsRequest.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsResponse.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\Constants.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\DemandLevel.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\Gender.cs" />
- <Compile Include="OpenId\Identifier.cs" />
- <Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" />
- <Compile Include="OpenId\Messages\CheckAuthenticationResponse.cs" />
- <Compile Include="OpenId\Messages\CheckIdRequest.cs" />
- <Compile Include="OpenId\Messages\IndirectResponseBase.cs" />
- <Compile Include="OpenId\Messages\IndirectSignedResponse.cs" />
- <Compile Include="OpenId\Messages\IOpenIdMessageExtension.cs" />
- <Compile Include="OpenId\Messages\NegativeAssertionResponse.cs" />
- <Compile Include="OpenId\Messages\PositiveAssertionResponse.cs" />
- <Compile Include="OpenId\Messages\SignedResponseRequest.cs" />
- <Compile Include="OpenId\NoDiscoveryIdentifier.cs" />
- <Compile Include="OpenId\OpenIdUtilities.cs" />
- <Compile Include="OpenId\PrivateSecretMemoryStore.cs" />
- <Compile Include="OpenId\Realm.cs" />
- <Compile Include="OpenId\RelyingPartyDescription.cs" />
- <Compile Include="OpenId\DiffieHellmanUtilities.cs" />
- <Compile Include="OpenId\DiffieHellman\DHKeyGeneration.cs" />
- <Compile Include="OpenId\DiffieHellman\DHParameters.cs" />
- <Compile Include="OpenId\DiffieHellman\DiffieHellman.cs" />
- <Compile Include="OpenId\DiffieHellman\DiffieHellmanManaged.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\BigInteger.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\ConfidenceFactor.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\NextPrimeFinder.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\PrimalityTests.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\PrimeGeneratorBase.cs" />
- <Compile Include="OpenId\DiffieHellman\mono\SequentialSearchPrimeGeneratorBase.cs" />
- <Compile Include="OpenId\HmacShaAssociation.cs" />
- <Compile Include="OpenId\IAssociationStore.cs" />
- <Compile Include="OpenId\Messages\AssociateUnencryptedRequest.cs" />
- <Compile Include="OpenId\Provider\OpenIdProvider.cs" />
- <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequest.cs" />
- <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateRequest.cs" />
- <Compile Include="OpenId\Messages\AssociateSuccessfulResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateUnencryptedResponse.cs" />
- <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponse.cs" />
- <Compile Include="OpenId\Messages\IndirectErrorResponse.cs" />
- <Compile Include="OpenId\Messages\DirectErrorResponse.cs" />
- <Compile Include="OpenId\Messages\RequestBase.cs" />
- <Compile Include="OpenId\Messages\DirectResponseBase.cs" />
- <Compile Include="OpenId\RelyingParty\AuthenticationRequestMode.cs" />
- <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" />
- <Compile Include="OpenId\RelyingParty\IXrdsProviderEndpoint.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdRelyingParty.cs" />
- <Compile Include="OpenId\OpenIdStrings.Designer.cs">
- <DependentUpon>OpenIdStrings.resx</DependentUpon>
- <DesignTime>True</DesignTime>
- <AutoGen>True</AutoGen>
- </Compile>
- <Compile Include="OpenId\Protocol.cs" />
- <Compile Include="OpenId\ProviderEndpointDescription.cs" />
- <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" />
- <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" />
- <Compile Include="OpenId\RelyingParty\ServiceEndpoint.cs" />
- <Compile Include="OpenId\OpenIdXrdsHelper.cs" />
- <Compile Include="OpenId\SecuritySettings.cs" />
- <Compile Include="Messaging\UntrustedWebRequestHandler.cs" />
- <Compile Include="OpenId\UriIdentifier.cs" />
- <Compile Include="OpenId\XriIdentifier.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" />
- <Compile Include="OAuth\ChannelElements\RsaSha1SigningBindingElement.cs" />
- <Compile Include="Messaging\StandardWebRequestHandler.cs" />
- <Compile Include="Messaging\MessageReceivingEndpoint.cs" />
- <Compile Include="Util.cs" />
- <Compile Include="OAuth\Protocol.cs" />
- <Compile Include="OAuth\ServiceProvider.cs" />
- <Compile Include="Strings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>Strings.resx</DependentUpon>
- </Compile>
- <Compile Include="UriUtil.cs" />
- <Compile Include="Xrds\XrdsStrings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>XrdsStrings.resx</DependentUpon>
- </Compile>
- <Compile Include="Yadis\ContentTypes.cs" />
- <Compile Include="Yadis\DiscoveryResult.cs" />
- <Compile Include="Yadis\HtmlParser.cs" />
- <Compile Include="Xrds\ServiceElement.cs" />
- <Compile Include="Xrds\TypeElement.cs" />
- <Compile Include="Xrds\UriElement.cs" />
- <Compile Include="Xrds\XrdElement.cs" />
- <Compile Include="Xrds\XrdsDocument.cs" />
- <Compile Include="Xrds\XrdsNode.cs" />
- <Compile Include="Yadis\Yadis.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="OAuth\ClassDiagram.cd" />
- <None Include="OAuth\Messages\OAuth Messages.cd" />
- <None Include="Messaging\Bindings\Bindings.cd" />
- <None Include="Messaging\Exceptions.cd" />
- <None Include="Messaging\Messaging.cd" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Messaging\MessagingStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>MessagingStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="OAuth\OAuthStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>OAuthStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="OpenId\OpenIdStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>OpenIdStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- <EmbeddedResource Include="Strings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Strings.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <EmbeddedResource Include="Xrds\XrdsStrings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>XrdsStrings.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DotNetOpenAuth</RootNamespace>
+ <AssemblyName>DotNetOpenAuth</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <DocumentationFile>..\..\bin\debug\DotNetOpenAuth.xml</DocumentationFile>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
+ <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\lib\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web" />
+ <Reference Include="System.XML" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Configuration\ProviderSection.cs" />
+ <Compile Include="Configuration\ProviderSecuritySettingsElement.cs" />
+ <Compile Include="Configuration\RelyingPartySection.cs" />
+ <Compile Include="Configuration\RelyingPartySecuritySettingsElement.cs" />
+ <Compile Include="Configuration\TypeConfigurationElement.cs" />
+ <Compile Include="Configuration\UntrustedWebRequestSection.cs" />
+ <Compile Include="Configuration\HostNameOrRegexCollection.cs" />
+ <Compile Include="Configuration\HostNameElement.cs" />
+ <Compile Include="Messaging\IExtensionMessage.cs" />
+ <Compile Include="Messaging\IMessage.cs" />
+ <Compile Include="Messaging\DirectWebResponse.cs" />
+ <Compile Include="Messaging\IDirectResponseProtocolMessage.cs" />
+ <Compile Include="Messaging\EmptyDictionary.cs" />
+ <Compile Include="Messaging\EmptyEnumerator.cs" />
+ <Compile Include="Messaging\EmptyList.cs" />
+ <Compile Include="Messaging\ErrorUtilities.cs" />
+ <Compile Include="Messaging\IDirectSslWebRequestHandler.cs" />
+ <Compile Include="Messaging\IProtocolMessageWithExtensions.cs" />
+ <Compile Include="Messaging\InternalErrorException.cs" />
+ <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" />
+ <Compile Include="OAuth\ChannelElements\OAuthConsumerMessageFactory.cs" />
+ <Compile Include="OAuth\ChannelElements\ITokenGenerator.cs" />
+ <Compile Include="OAuth\ChannelElements\ITokenManager.cs" />
+ <Compile Include="OAuth\ChannelElements\OAuthHttpMethodBindingElement.cs" />
+ <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElement.cs" />
+ <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElement.cs" />
+ <Compile Include="OAuth\ChannelElements\SigningBindingElementChain.cs" />
+ <Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" />
+ <Compile Include="OAuth\ChannelElements\TokenType.cs" />
+ <Compile Include="OAuth\ConsumerBase.cs" />
+ <Compile Include="OAuth\DesktopConsumer.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="OAuth\Messages\ITokenSecretContainingMessage.cs" />
+ <Compile Include="Messaging\ChannelEventArgs.cs" />
+ <Compile Include="Messaging\ITamperProtectionChannelBindingElement.cs" />
+ <Compile Include="OAuth\OAuthStrings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>OAuthStrings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="OAuth\ServiceProviderDescription.cs" />
+ <Compile Include="OAuth\Messages\ITokenContainingMessage.cs" />
+ <Compile Include="OAuth\Messages\SignedMessageBase.cs" />
+ <Compile Include="Messaging\Bindings\NonceMemoryStore.cs" />
+ <Compile Include="OAuth\ChannelElements\SigningBindingElementBase.cs" />
+ <Compile Include="OAuth\WebConsumer.cs" />
+ <Compile Include="Messaging\IDirectWebRequestHandler.cs" />
+ <Compile Include="OAuth\ChannelElements\ITamperResistantOAuthMessage.cs" />
+ <Compile Include="OAuth\Messages\MessageBase.cs" />
+ <Compile Include="OAuth\Messages\AuthorizedTokenRequest.cs" />
+ <Compile Include="Messaging\Bindings\INonceStore.cs" />
+ <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElement.cs" />
+ <Compile Include="Messaging\MessagePartAttribute.cs" />
+ <Compile Include="Messaging\MessageProtections.cs" />
+ <Compile Include="Messaging\IChannelBindingElement.cs" />
+ <Compile Include="Messaging\Bindings\ReplayedMessageException.cs" />
+ <Compile Include="Messaging\Bindings\ExpiredMessageException.cs" />
+ <Compile Include="Messaging\Bindings\InvalidSignatureException.cs" />
+ <Compile Include="Messaging\Bindings\IReplayProtectedProtocolMessage.cs" />
+ <Compile Include="Messaging\Bindings\IExpiringProtocolMessage.cs" />
+ <Compile Include="OAuth\Messages\AccessProtectedResourceRequest.cs" />
+ <Compile Include="OAuth\Messages\AuthorizedTokenResponse.cs" />
+ <Compile Include="OAuth\Messages\UserAuthorizationResponse.cs" />
+ <Compile Include="OAuth\Messages\UserAuthorizationRequest.cs" />
+ <Compile Include="OAuth\Messages\UnauthorizedTokenResponse.cs" />
+ <Compile Include="Messaging\Channel.cs" />
+ <Compile Include="Messaging\HttpRequestInfo.cs" />
+ <Compile Include="Messaging\IDirectedProtocolMessage.cs" />
+ <Compile Include="Messaging\IMessageFactory.cs" />
+ <Compile Include="Messaging\ITamperResistantProtocolMessage.cs" />
+ <Compile Include="Messaging\MessageSerializer.cs" />
+ <Compile Include="Messaging\MessagingStrings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>MessagingStrings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Messaging\MessagingUtilities.cs" />
+ <Compile Include="Messaging\Bindings\StandardExpirationBindingElement.cs" />
+ <Compile Include="Messaging\Reflection\ValueMapping.cs" />
+ <Compile Include="Messaging\Reflection\MessageDescription.cs" />
+ <Compile Include="Messaging\Reflection\MessageDictionary.cs" />
+ <Compile Include="Messaging\Reflection\MessagePart.cs" />
+ <Compile Include="Messaging\UnprotectedMessageException.cs" />
+ <Compile Include="OAuth\ChannelElements\OAuthChannel.cs" />
+ <Compile Include="Messaging\UserAgentResponse.cs" />
+ <Compile Include="Messaging\IProtocolMessage.cs" />
+ <Compile Include="Logger.cs" />
+ <Compile Include="Loggers\ILog.cs" />
+ <Compile Include="Loggers\Log4NetLogger.cs" />
+ <Compile Include="Loggers\NoOpLogger.cs" />
+ <Compile Include="Loggers\TraceLogger.cs" />
+ <Compile Include="Messaging\HttpDeliveryMethods.cs" />
+ <Compile Include="Messaging\MessageTransport.cs" />
+ <Compile Include="OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs" />
+ <Compile Include="Messaging\ProtocolException.cs" />
+ <Compile Include="OpenId\Association.cs" />
+ <Compile Include="OpenId\AssociationMemoryStore.cs" />
+ <Compile Include="OpenId\Associations.cs" />
+ <Compile Include="OpenId\ChannelElements\BackwardCompatibilityBindingElement.cs" />
+ <Compile Include="OpenId\ChannelElements\ExtensionsBindingElement.cs" />
+ <Compile Include="OpenId\ChannelElements\IOpenIdExtensionFactory.cs" />
+ <Compile Include="OpenId\ChannelElements\IPrivateSecretStore.cs" />
+ <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" />
+ <Compile Include="OpenId\ChannelElements\OriginalStringUriEncoder.cs" />
+ <Compile Include="OpenId\ChannelElements\ReturnToNonceBindingElement.cs" />
+ <Compile Include="OpenId\ChannelElements\SigningBindingElement.cs" />
+ <Compile Include="OpenId\ChannelElements\KeyValueFormEncoding.cs" />
+ <Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" />
+ <Compile Include="OpenId\ChannelElements\OpenIdMessageFactory.cs" />
+ <Compile Include="OpenId\ChannelElements\ReturnToSignatureBindingElement.cs" />
+ <Compile Include="OpenId\Configuration.cs" />
+ <Compile Include="OpenId\Extensions\AliasManager.cs" />
+ <Compile Include="OpenId\Extensions\ExtensionBase.cs" />
+ <Compile Include="OpenId\Extensions\ExtensionArgumentsManager.cs" />
+ <Compile Include="OpenId\Extensions\OpenIdExtensionFactory.cs" />
+ <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsRequest.cs" />
+ <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsResponse.cs" />
+ <Compile Include="OpenId\Extensions\SimpleRegistration\Constants.cs" />
+ <Compile Include="OpenId\Extensions\SimpleRegistration\DemandLevel.cs" />
+ <Compile Include="OpenId\Extensions\SimpleRegistration\Gender.cs" />
+ <Compile Include="OpenId\Identifier.cs" />
+ <Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" />
+ <Compile Include="OpenId\Messages\CheckAuthenticationResponse.cs" />
+ <Compile Include="OpenId\Messages\CheckIdRequest.cs" />
+ <Compile Include="OpenId\Messages\IndirectResponseBase.cs" />
+ <Compile Include="OpenId\Messages\IndirectSignedResponse.cs" />
+ <Compile Include="OpenId\Messages\IOpenIdMessageExtension.cs" />
+ <Compile Include="OpenId\Messages\NegativeAssertionResponse.cs" />
+ <Compile Include="OpenId\Messages\PositiveAssertionResponse.cs" />
+ <Compile Include="OpenId\Messages\SignedResponseRequest.cs" />
+ <Compile Include="OpenId\NoDiscoveryIdentifier.cs" />
+ <Compile Include="OpenId\OpenIdUtilities.cs" />
+ <Compile Include="OpenId\PrivateSecretMemoryStore.cs" />
+ <Compile Include="OpenId\Realm.cs" />
+ <Compile Include="OpenId\RelyingPartyDescription.cs" />
+ <Compile Include="OpenId\DiffieHellmanUtilities.cs" />
+ <Compile Include="OpenId\DiffieHellman\DHKeyGeneration.cs" />
+ <Compile Include="OpenId\DiffieHellman\DHParameters.cs" />
+ <Compile Include="OpenId\DiffieHellman\DiffieHellman.cs" />
+ <Compile Include="OpenId\DiffieHellman\DiffieHellmanManaged.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\BigInteger.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\ConfidenceFactor.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\NextPrimeFinder.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\PrimalityTests.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\PrimeGeneratorBase.cs" />
+ <Compile Include="OpenId\DiffieHellman\mono\SequentialSearchPrimeGeneratorBase.cs" />
+ <Compile Include="OpenId\HmacShaAssociation.cs" />
+ <Compile Include="OpenId\IAssociationStore.cs" />
+ <Compile Include="OpenId\Messages\AssociateUnencryptedRequest.cs" />
+ <Compile Include="OpenId\Provider\OpenIdProvider.cs" />
+ <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequest.cs" />
+ <Compile Include="OpenId\Messages\AssociateDiffieHellmanResponse.cs" />
+ <Compile Include="OpenId\Messages\AssociateRequest.cs" />
+ <Compile Include="OpenId\Messages\AssociateSuccessfulResponse.cs" />
+ <Compile Include="OpenId\Messages\AssociateUnencryptedResponse.cs" />
+ <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponse.cs" />
+ <Compile Include="OpenId\Messages\IndirectErrorResponse.cs" />
+ <Compile Include="OpenId\Messages\DirectErrorResponse.cs" />
+ <Compile Include="OpenId\Messages\RequestBase.cs" />
+ <Compile Include="OpenId\Messages\DirectResponseBase.cs" />
+ <Compile Include="OpenId\RelyingParty\AuthenticationRequestMode.cs" />
+ <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" />
+ <Compile Include="OpenId\RelyingParty\IXrdsProviderEndpoint.cs" />
+ <Compile Include="OpenId\RelyingParty\OpenIdRelyingParty.cs" />
+ <Compile Include="OpenId\OpenIdStrings.Designer.cs">
+ <DependentUpon>OpenIdStrings.resx</DependentUpon>
+ <DesignTime>True</DesignTime>
+ <AutoGen>True</AutoGen>
+ </Compile>
+ <Compile Include="OpenId\Protocol.cs" />
+ <Compile Include="OpenId\ProviderEndpointDescription.cs" />
+ <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" />
+ <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" />
+ <Compile Include="OpenId\RelyingParty\ServiceEndpoint.cs" />
+ <Compile Include="OpenId\OpenIdXrdsHelper.cs" />
+ <Compile Include="OpenId\SecuritySettings.cs" />
+ <Compile Include="Messaging\UntrustedWebRequestHandler.cs" />
+ <Compile Include="OpenId\UriIdentifier.cs" />
+ <Compile Include="OpenId\XriIdentifier.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" />
+ <Compile Include="OAuth\ChannelElements\RsaSha1SigningBindingElement.cs" />
+ <Compile Include="Messaging\StandardWebRequestHandler.cs" />
+ <Compile Include="Messaging\MessageReceivingEndpoint.cs" />
+ <Compile Include="Util.cs" />
+ <Compile Include="OAuth\Protocol.cs" />
+ <Compile Include="OAuth\ServiceProvider.cs" />
+ <Compile Include="Strings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Strings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="UriUtil.cs" />
+ <Compile Include="Xrds\XrdsStrings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>XrdsStrings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Yadis\ContentTypes.cs" />
+ <Compile Include="Yadis\DiscoveryResult.cs" />
+ <Compile Include="Yadis\HtmlParser.cs" />
+ <Compile Include="Xrds\ServiceElement.cs" />
+ <Compile Include="Xrds\TypeElement.cs" />
+ <Compile Include="Xrds\UriElement.cs" />
+ <Compile Include="Xrds\XrdElement.cs" />
+ <Compile Include="Xrds\XrdsDocument.cs" />
+ <Compile Include="Xrds\XrdsNode.cs" />
+ <Compile Include="Yadis\Yadis.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="OAuth\ClassDiagram.cd" />
+ <None Include="OAuth\Messages\OAuth Messages.cd" />
+ <None Include="Messaging\Bindings\Bindings.cd" />
+ <None Include="Messaging\Exceptions.cd" />
+ <None Include="Messaging\Messaging.cd" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Messaging\MessagingStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>MessagingStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <EmbeddedResource Include="OAuth\OAuthStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>OAuthStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <EmbeddedResource Include="OpenId\OpenIdStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>OpenIdStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Strings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Xrds\XrdsStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>XrdsStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 4191f28..6234153 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -1,471 +1,471 @@
-//-----------------------------------------------------------------------
-// <copyright file="MessagingUtilities.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Messaging {
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Diagnostics.CodeAnalysis;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Security.Cryptography;
- using System.Text;
- using System.Web;
- using DotNetOpenAuth.Messaging.Reflection;
-
- /// <summary>
- /// A grab-bag of utility methods useful for the channel stack of the protocol.
- /// </summary>
- public static class MessagingUtilities {
- /// <summary>
- /// The cryptographically strong random data generator used for creating secrets.
- /// </summary>
- /// <remarks>The random number generator is thread-safe.</remarks>
- internal static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
-
- /// <summary>
- /// Gets the original request URL, as seen from the browser before any URL rewrites on the server if any.
- /// Cookieless session directory (if applicable) is also included.
- /// </summary>
- /// <returns>The URL in the user agent's Location bar.</returns>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "The Uri merging requires use of a string value.")]
- [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Expensive call should not be a property.")]
- public static Uri GetRequestUrlFromContext() {
- HttpContext context = HttpContext.Current;
- if (context == null) {
- throw new InvalidOperationException(MessagingStrings.CurrentHttpContextRequired);
- }
-
- // We use Request.Url for the full path to the server, and modify it
- // with Request.RawUrl to capture both the cookieless session "directory" if it exists
- // and the original path in case URL rewriting is going on. We don't want to be
- // fooled by URL rewriting because we're comparing the actual URL with what's in
- // the return_to parameter in some cases.
- // Response.ApplyAppPathModifier(builder.Path) would have worked for the cookieless
- // session, but not the URL rewriting problem.
- return new Uri(context.Request.Url, context.Request.RawUrl);
- }
-
- /// <summary>
- /// Strips any and all URI query parameters that start with some prefix.
- /// </summary>
- /// <param name="uri">The URI that may have a query with parameters to remove.</param>
- /// <param name="prefix">The prefix for parameters to remove.</param>
- /// <returns>Either a new Uri with the parameters removed if there were any to remove, or the same Uri instance if no parameters needed to be removed.</returns>
- public static Uri StripQueryArgumentsWithPrefix(this Uri uri, string prefix) {
- NameValueCollection queryArgs = HttpUtility.ParseQueryString(uri.Query);
- var matchingKeys = queryArgs.Keys.OfType<string>().Where(key => key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)).ToList();
- if (matchingKeys.Count > 0) {
- UriBuilder builder = new UriBuilder(uri);
- foreach (string key in matchingKeys) {
- queryArgs.Remove(key);
- }
- builder.Query = CreateQueryString(queryArgs.ToDictionary());
- return builder.Uri;
- } else {
- return uri;
- }
- }
-
- /// <summary>
- /// Gets a cryptographically strong random sequence of values.
- /// </summary>
- /// <param name="length">The length of the sequence to generate.</param>
- /// <returns>The generated values, which may contain zeros.</returns>
- internal static byte[] GetCryptoRandomData(int length) {
- byte[] buffer = new byte[length];
- CryptoRandomDataGenerator.GetBytes(buffer);
- return buffer;
- }
-
- /// <summary>
- /// Gets a cryptographically strong random sequence of values.
- /// </summary>
- /// <param name="binaryLength">The length of the byte sequence to generate.</param>
- /// <returns>A base64 encoding of the generated random data,
- /// whose length in characters will likely be greater than <paramref name="binaryLength"/>.</returns>
- internal static string GetCryptoRandomDataAsBase64(int binaryLength) {
- byte[] uniq_bytes = GetCryptoRandomData(binaryLength);
- string uniq = Convert.ToBase64String(uniq_bytes);
- return uniq;
- }
-
- /// <summary>
- /// Adds a set of HTTP headers to an <see cref="HttpResponse"/> instance,
- /// taking care to set some headers to the appropriate properties of
- /// <see cref="HttpResponse" />
- /// </summary>
- /// <param name="headers">The headers to add.</param>
- /// <param name="response">The <see cref="HttpResponse"/> instance to set the appropriate values to.</param>
- internal static void ApplyHeadersToResponse(WebHeaderCollection headers, HttpResponse response) {
- if (headers == null) {
- throw new ArgumentNullException("headers");
- }
- if (response == null) {
- throw new ArgumentNullException("response");
- }
- foreach (string headerName in headers) {
- switch (headerName) {
- case "Content-Type":
- response.ContentType = headers[HttpResponseHeader.ContentType];
- break;
-
- // Add more special cases here as necessary.
- default:
- response.AddHeader(headerName, headers[headerName]);
- break;
- }
- }
- }
-
- /// <summary>
- /// Copies the contents of one stream to another.
- /// </summary>
- /// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param>
- /// <param name="copyTo">The stream to copy to, at the position where bytes should be written.</param>
- /// <returns>The total number of bytes copied.</returns>
- /// <remarks>
- /// Copying begins at the streams' current positions.
- /// The positions are NOT reset after copying is complete.
- /// </remarks>
- internal static int CopyTo(this Stream copyFrom, Stream copyTo) {
- return CopyTo(copyFrom, copyTo, int.MaxValue);
- }
-
- /// <summary>
- /// Copies the contents of one stream to another.
- /// </summary>
- /// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param>
- /// <param name="copyTo">The stream to copy to, at the position where bytes should be written.</param>
- /// <param name="maximumBytesToCopy">The maximum bytes to copy.</param>
- /// <returns>The total number of bytes copied.</returns>
- /// <remarks>
- /// Copying begins at the streams' current positions.
- /// The positions are NOT reset after copying is complete.
- /// </remarks>
- internal static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) {
- ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
- ErrorUtilities.VerifyArgumentNotNull(copyTo, "copyTo");
- ErrorUtilities.VerifyArgument(copyFrom.CanRead, MessagingStrings.StreamUnreadable);
- ErrorUtilities.VerifyArgument(copyTo.CanWrite, MessagingStrings.StreamUnwritable, "copyTo");
-
- byte[] buffer = new byte[1024];
- int readBytes;
- int totalCopiedBytes = 0;
- while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(1024, maximumBytesToCopy))) > 0) {
- int writeBytes = Math.Min(maximumBytesToCopy, readBytes);
- copyTo.Write(buffer, 0, writeBytes);
- totalCopiedBytes += writeBytes;
- maximumBytesToCopy -= writeBytes;
- }
-
- return totalCopiedBytes;
- }
-
- /// <summary>
- /// Creates a snapshot of some stream so it is seekable, and the original can be closed.
- /// </summary>
- /// <param name="copyFrom">The stream to copy bytes from.</param>
- /// <returns>A seekable stream with the same contents as the original.</returns>
- internal static Stream CreateSnapshot(this Stream copyFrom) {
- ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
-
- MemoryStream copyTo = new MemoryStream(copyFrom.CanSeek ? (int)copyFrom.Length : 4 * 1024);
- copyFrom.CopyTo(copyTo);
- copyTo.Position = 0;
- return copyTo;
- }
-
- /// <summary>
- /// Clones an <see cref="HttpWebRequest"/> in order to send it again.
- /// </summary>
- /// <param name="request">The request to clone.</param>
- /// <returns>The newly created instance.</returns>
- internal static HttpWebRequest Clone(this HttpWebRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- return Clone(request, request.RequestUri);
- }
-
- /// <summary>
- /// Clones an <see cref="HttpWebRequest"/> in order to send it again.
- /// </summary>
- /// <param name="request">The request to clone.</param>
- /// <param name="newRequestUri">The new recipient of the request.</param>
- /// <returns>The newly created instance.</returns>
- internal static HttpWebRequest Clone(this HttpWebRequest request, Uri newRequestUri) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(newRequestUri, "newRequestUri");
-
- var newRequest = (HttpWebRequest)WebRequest.Create(newRequestUri);
- newRequest.Accept = request.Accept;
- newRequest.AllowAutoRedirect = request.AllowAutoRedirect;
- newRequest.AllowWriteStreamBuffering = request.AllowWriteStreamBuffering;
- newRequest.AuthenticationLevel = request.AuthenticationLevel;
- newRequest.AutomaticDecompression = request.AutomaticDecompression;
- newRequest.CachePolicy = request.CachePolicy;
- newRequest.ClientCertificates = request.ClientCertificates;
- newRequest.ConnectionGroupName = request.ConnectionGroupName;
- if (request.ContentLength >= 0) {
- newRequest.ContentLength = request.ContentLength;
- }
- newRequest.ContentType = request.ContentType;
- newRequest.ContinueDelegate = request.ContinueDelegate;
- newRequest.CookieContainer = request.CookieContainer;
- newRequest.Credentials = request.Credentials;
- newRequest.Expect = request.Expect;
- newRequest.IfModifiedSince = request.IfModifiedSince;
- newRequest.ImpersonationLevel = request.ImpersonationLevel;
- newRequest.KeepAlive = request.KeepAlive;
- newRequest.MaximumAutomaticRedirections = request.MaximumAutomaticRedirections;
- newRequest.MaximumResponseHeadersLength = request.MaximumResponseHeadersLength;
- newRequest.MediaType = request.MediaType;
- newRequest.Method = request.Method;
- newRequest.Pipelined = request.Pipelined;
- newRequest.PreAuthenticate = request.PreAuthenticate;
- newRequest.ProtocolVersion = request.ProtocolVersion;
- newRequest.Proxy = request.Proxy;
- newRequest.ReadWriteTimeout = request.ReadWriteTimeout;
- newRequest.Referer = request.Referer;
- newRequest.SendChunked = request.SendChunked;
- newRequest.Timeout = request.Timeout;
- newRequest.TransferEncoding = request.TransferEncoding;
- newRequest.UnsafeAuthenticatedConnectionSharing = request.UnsafeAuthenticatedConnectionSharing;
- newRequest.UseDefaultCredentials = request.UseDefaultCredentials;
- newRequest.UserAgent = request.UserAgent;
-
- // We copy headers last, and only those that do not yet exist as a result
- // of setting these properties, so as to avoid exceptions thrown because
- // there are properties .NET wants us to use rather than direct headers.
- foreach (string header in request.Headers) {
- if (string.IsNullOrEmpty(newRequest.Headers[header])) {
- newRequest.Headers.Add(header, request.Headers[header]);
- }
- }
-
- return newRequest;
- }
-
- /// <summary>
- /// Tests whether two arrays are equal in length and contents.
- /// </summary>
- /// <typeparam name="T">The type of elements in the arrays.</typeparam>
- /// <param name="first">The first array in the comparison. May not be null.</param>
- /// <param name="second">The second array in the comparison. May not be null.</param>
- /// <returns>True if the arrays equal; false otherwise.</returns>
- internal static bool AreEquivalent<T>(T[] first, T[] second) {
- if (first == null) {
- throw new ArgumentNullException("first");
- }
- if (second == null) {
- throw new ArgumentNullException("second");
- }
- if (first.Length != second.Length) {
- return false;
- }
- for (int i = 0; i < first.Length; i++) {
- if (!first[i].Equals(second[i])) {
- return false;
- }
- }
- return true;
- }
-
- /// <summary>
- /// Tests whether two dictionaries are equal in length and contents.
- /// </summary>
- /// <typeparam name="TKey">The type of keys in the dictionaries.</typeparam>
- /// <typeparam name="TValue">The type of values in the dictionaries.</typeparam>
- /// <param name="first">The first dictionary in the comparison. May not be null.</param>
- /// <param name="second">The second dictionary in the comparison. May not be null.</param>
- /// <returns>True if the arrays equal; false otherwise.</returns>
- internal static bool AreEquivalent<TKey, TValue>(IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second) {
- return AreEquivalent(first.ToArray(), second.ToArray());
- }
-
- /// <summary>
- /// Concatenates a list of name-value pairs as key=value&amp;key=value,
- /// taking care to properly encode each key and value for URL
- /// transmission. No ? is prefixed to the string.
- /// </summary>
- /// <param name="args">The dictionary of key/values to read from.</param>
- /// <returns>The formulated querystring style string.</returns>
- internal static string CreateQueryString(IEnumerable<KeyValuePair<string, string>> args) {
- ErrorUtilities.VerifyArgumentNotNull(args, "args");
- if (args.Count() == 0) {
- return string.Empty;
- }
- StringBuilder sb = new StringBuilder(args.Count() * 10);
-
- foreach (var p in args) {
- ErrorUtilities.VerifyArgument(p.Key != null, MessagingStrings.UnexpectedNullValue);
- ErrorUtilities.VerifyArgument(p.Value != null, MessagingStrings.UnexpectedNullValue);
- sb.Append(HttpUtility.UrlEncode(p.Key));
- sb.Append('=');
- sb.Append(HttpUtility.UrlEncode(p.Value));
- sb.Append('&');
- }
- sb.Length--; // remove trailing &
-
- return sb.ToString();
- }
-
- /// <summary>
- /// Adds a set of name-value pairs to the end of a given URL
- /// as part of the querystring piece. Prefixes a ? or &amp; before
- /// first element as necessary.
- /// </summary>
- /// <param name="builder">The UriBuilder to add arguments to.</param>
- /// <param name="args">
- /// The arguments to add to the query.
- /// If null, <paramref name="builder"/> is not changed.
- /// </param>
- internal static void AppendQueryArgs(this UriBuilder builder, IEnumerable<KeyValuePair<string, string>> args) {
- if (builder == null) {
- throw new ArgumentNullException("builder");
- }
-
- if (args != null && args.Count() > 0) {
- StringBuilder sb = new StringBuilder(50 + (args.Count() * 10));
- if (!string.IsNullOrEmpty(builder.Query)) {
- sb.Append(builder.Query.Substring(1));
- sb.Append('&');
- }
- sb.Append(CreateQueryString(args));
-
- builder.Query = sb.ToString();
- }
- }
-
- /// <summary>
- /// Extracts the recipient from an HttpRequestInfo.
- /// </summary>
- /// <param name="request">The request to get recipient information from.</param>
- /// <returns>The recipient.</returns>
- internal static MessageReceivingEndpoint GetRecipient(this HttpRequestInfo request) {
- return new MessageReceivingEndpoint(request.Url, request.HttpMethod == "GET" ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest);
- }
-
- /// <summary>
- /// Copies some extra parameters into a message.
- /// </summary>
- /// <param name="message">The message to copy the extra data into.</param>
- /// <param name="extraParameters">The extra data to copy into the message. May be null to do nothing.</param>
- internal static void AddExtraParameters(this IMessage message, IDictionary<string, string> extraParameters) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
-
- if (extraParameters != null) {
- MessageDictionary messageDictionary = new MessageDictionary(message);
- foreach (var pair in extraParameters) {
- messageDictionary.Add(pair);
- }
- }
- }
-
- /// <summary>
- /// Converts a <see cref="NameValueCollection"/> to an IDictionary&lt;string, string&gt;.
- /// </summary>
- /// <param name="nvc">The NameValueCollection to convert. May be null.</param>
- /// <returns>The generated dictionary, or null if <paramref name="nvc"/> is null.</returns>
- internal static Dictionary<string, string> ToDictionary(this NameValueCollection nvc) {
- if (nvc == null) {
- return null;
- }
-
- var dictionary = new Dictionary<string, string>();
- foreach (string key in nvc) {
- dictionary.Add(key, nvc[key]);
- }
-
- return dictionary;
- }
-
- /// <summary>
- /// Sorts the elements of a sequence in ascending order by using a specified comparer.
- /// </summary>
- /// <typeparam name="TSource">The type of the elements of source.</typeparam>
- /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
- /// <param name="source">A sequence of values to order.</param>
- /// <param name="keySelector">A function to extract a key from an element.</param>
- /// <param name="comparer">A comparison function to compare keys.</param>
- /// <returns>An System.Linq.IOrderedEnumerable&lt;TElement&gt; whose elements are sorted according to a key.</returns>
- internal static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Comparison<TKey> comparer) {
- return System.Linq.Enumerable.OrderBy<TSource, TKey>(source, keySelector, new ComparisonHelper<TKey>(comparer));
- }
-
- /// <summary>
- /// Determines whether the specified message is a request (indirect message or direct request).
- /// </summary>
- /// <param name="message">The message in question.</param>
- /// <returns>
- /// <c>true</c> if the specified message is a request; otherwise, <c>false</c>.
- /// </returns>
- /// <remarks>
- /// Although an <see cref="IProtocolMessage"/> may implement the <see cref="IDirectedProtocolMessage"/>
- /// interface, it may only be doing that for its derived classes. These objects are only requests
- /// if their <see cref="IDirectedProtocolMessage.Recipient"/> property is non-null.
- /// </remarks>
- internal static bool IsRequest(this IDirectedProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- return message.Recipient != null;
- }
-
- /// <summary>
- /// Determines whether the specified message is a direct response.
- /// </summary>
- /// <param name="message">The message in question.</param>
- /// <returns>
- /// <c>true</c> if the specified message is a direct response; otherwise, <c>false</c>.
- /// </returns>
- /// <remarks>
- /// Although an <see cref="IProtocolMessage"/> may implement the
- /// <see cref="IDirectResponseProtocolMessage"/> interface, it may only be doing
- /// that for its derived classes. These objects are only requests if their
- /// <see cref="IDirectResponseProtocolMessage.OriginatingRequest"/> property is non-null.
- /// </remarks>
- internal static bool IsDirectResponse(this IDirectResponseProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- return message.OriginatingRequest != null;
- }
-
- /// <summary>
- /// A class to convert a <see cref="Comparison&lt;T&gt;"/> into an <see cref="IComparer&lt;T&gt;"/>.
- /// </summary>
- /// <typeparam name="T">The type of objects being compared.</typeparam>
- private class ComparisonHelper<T> : IComparer<T> {
- /// <summary>
- /// The comparison method to use.
- /// </summary>
- private Comparison<T> comparison;
-
- /// <summary>
- /// Initializes a new instance of the ComparisonHelper class.
- /// </summary>
- /// <param name="comparison">The comparison method to use.</param>
- internal ComparisonHelper(Comparison<T> comparison) {
- if (comparison == null) {
- throw new ArgumentNullException("comparison");
- }
-
- this.comparison = comparison;
- }
-
- #region IComparer<T> Members
-
- /// <summary>
- /// Compares two instances of <typeparamref name="T"/>.
- /// </summary>
- /// <param name="x">The first object to compare.</param>
- /// <param name="y">The second object to compare.</param>
- /// <returns>Any of -1, 0, or 1 according to standard comparison rules.</returns>
- public int Compare(T x, T y) {
- return this.comparison(x, y);
- }
-
- #endregion
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="MessagingUtilities.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Messaging {
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Specialized;
+ using System.Diagnostics.CodeAnalysis;
+ using System.IO;
+ using System.Linq;
+ using System.Net;
+ using System.Security.Cryptography;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.Messaging.Reflection;
+
+ /// <summary>
+ /// A grab-bag of utility methods useful for the channel stack of the protocol.
+ /// </summary>
+ public static class MessagingUtilities {
+ /// <summary>
+ /// The cryptographically strong random data generator used for creating secrets.
+ /// </summary>
+ /// <remarks>The random number generator is thread-safe.</remarks>
+ internal static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
+
+ /// <summary>
+ /// Gets the original request URL, as seen from the browser before any URL rewrites on the server if any.
+ /// Cookieless session directory (if applicable) is also included.
+ /// </summary>
+ /// <returns>The URL in the user agent's Location bar.</returns>
+ [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "The Uri merging requires use of a string value.")]
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Expensive call should not be a property.")]
+ public static Uri GetRequestUrlFromContext() {
+ HttpContext context = HttpContext.Current;
+ if (context == null) {
+ throw new InvalidOperationException(MessagingStrings.CurrentHttpContextRequired);
+ }
+
+ // We use Request.Url for the full path to the server, and modify it
+ // with Request.RawUrl to capture both the cookieless session "directory" if it exists
+ // and the original path in case URL rewriting is going on. We don't want to be
+ // fooled by URL rewriting because we're comparing the actual URL with what's in
+ // the return_to parameter in some cases.
+ // Response.ApplyAppPathModifier(builder.Path) would have worked for the cookieless
+ // session, but not the URL rewriting problem.
+ return new Uri(context.Request.Url, context.Request.RawUrl);
+ }
+
+ /// <summary>
+ /// Strips any and all URI query parameters that start with some prefix.
+ /// </summary>
+ /// <param name="uri">The URI that may have a query with parameters to remove.</param>
+ /// <param name="prefix">The prefix for parameters to remove.</param>
+ /// <returns>Either a new Uri with the parameters removed if there were any to remove, or the same Uri instance if no parameters needed to be removed.</returns>
+ public static Uri StripQueryArgumentsWithPrefix(this Uri uri, string prefix) {
+ NameValueCollection queryArgs = HttpUtility.ParseQueryString(uri.Query);
+ var matchingKeys = queryArgs.Keys.OfType<string>().Where(key => key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)).ToList();
+ if (matchingKeys.Count > 0) {
+ UriBuilder builder = new UriBuilder(uri);
+ foreach (string key in matchingKeys) {
+ queryArgs.Remove(key);
+ }
+ builder.Query = CreateQueryString(queryArgs.ToDictionary());
+ return builder.Uri;
+ } else {
+ return uri;
+ }
+ }
+
+ /// <summary>
+ /// Gets a cryptographically strong random sequence of values.
+ /// </summary>
+ /// <param name="length">The length of the sequence to generate.</param>
+ /// <returns>The generated values, which may contain zeros.</returns>
+ internal static byte[] GetCryptoRandomData(int length) {
+ byte[] buffer = new byte[length];
+ CryptoRandomDataGenerator.GetBytes(buffer);
+ return buffer;
+ }
+
+ /// <summary>
+ /// Gets a cryptographically strong random sequence of values.
+ /// </summary>
+ /// <param name="binaryLength">The length of the byte sequence to generate.</param>
+ /// <returns>A base64 encoding of the generated random data,
+ /// whose length in characters will likely be greater than <paramref name="binaryLength"/>.</returns>
+ internal static string GetCryptoRandomDataAsBase64(int binaryLength) {
+ byte[] uniq_bytes = GetCryptoRandomData(binaryLength);
+ string uniq = Convert.ToBase64String(uniq_bytes);
+ return uniq;
+ }
+
+ /// <summary>
+ /// Adds a set of HTTP headers to an <see cref="HttpResponse"/> instance,
+ /// taking care to set some headers to the appropriate properties of
+ /// <see cref="HttpResponse" />
+ /// </summary>
+ /// <param name="headers">The headers to add.</param>
+ /// <param name="response">The <see cref="HttpResponse"/> instance to set the appropriate values to.</param>
+ internal static void ApplyHeadersToResponse(WebHeaderCollection headers, HttpResponse response) {
+ if (headers == null) {
+ throw new ArgumentNullException("headers");
+ }
+ if (response == null) {
+ throw new ArgumentNullException("response");
+ }
+ foreach (string headerName in headers) {
+ switch (headerName) {
+ case "Content-Type":
+ response.ContentType = headers[HttpResponseHeader.ContentType];
+ break;
+
+ // Add more special cases here as necessary.
+ default:
+ response.AddHeader(headerName, headers[headerName]);
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Copies the contents of one stream to another.
+ /// </summary>
+ /// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param>
+ /// <param name="copyTo">The stream to copy to, at the position where bytes should be written.</param>
+ /// <returns>The total number of bytes copied.</returns>
+ /// <remarks>
+ /// Copying begins at the streams' current positions.
+ /// The positions are NOT reset after copying is complete.
+ /// </remarks>
+ internal static int CopyTo(this Stream copyFrom, Stream copyTo) {
+ return CopyTo(copyFrom, copyTo, int.MaxValue);
+ }
+
+ /// <summary>
+ /// Copies the contents of one stream to another.
+ /// </summary>
+ /// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param>
+ /// <param name="copyTo">The stream to copy to, at the position where bytes should be written.</param>
+ /// <param name="maximumBytesToCopy">The maximum bytes to copy.</param>
+ /// <returns>The total number of bytes copied.</returns>
+ /// <remarks>
+ /// Copying begins at the streams' current positions.
+ /// The positions are NOT reset after copying is complete.
+ /// </remarks>
+ internal static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) {
+ ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
+ ErrorUtilities.VerifyArgumentNotNull(copyTo, "copyTo");
+ ErrorUtilities.VerifyArgument(copyFrom.CanRead, MessagingStrings.StreamUnreadable);
+ ErrorUtilities.VerifyArgument(copyTo.CanWrite, MessagingStrings.StreamUnwritable, "copyTo");
+
+ byte[] buffer = new byte[1024];
+ int readBytes;
+ int totalCopiedBytes = 0;
+ while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(1024, maximumBytesToCopy))) > 0) {
+ int writeBytes = Math.Min(maximumBytesToCopy, readBytes);
+ copyTo.Write(buffer, 0, writeBytes);
+ totalCopiedBytes += writeBytes;
+ maximumBytesToCopy -= writeBytes;
+ }
+
+ return totalCopiedBytes;
+ }
+
+ /// <summary>
+ /// Creates a snapshot of some stream so it is seekable, and the original can be closed.
+ /// </summary>
+ /// <param name="copyFrom">The stream to copy bytes from.</param>
+ /// <returns>A seekable stream with the same contents as the original.</returns>
+ internal static Stream CreateSnapshot(this Stream copyFrom) {
+ ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
+
+ MemoryStream copyTo = new MemoryStream(copyFrom.CanSeek ? (int)copyFrom.Length : 4 * 1024);
+ copyFrom.CopyTo(copyTo);
+ copyTo.Position = 0;
+ return copyTo;
+ }
+
+ /// <summary>
+ /// Clones an <see cref="HttpWebRequest"/> in order to send it again.
+ /// </summary>
+ /// <param name="request">The request to clone.</param>
+ /// <returns>The newly created instance.</returns>
+ internal static HttpWebRequest Clone(this HttpWebRequest request) {
+ ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ return Clone(request, request.RequestUri);
+ }
+
+ /// <summary>
+ /// Clones an <see cref="HttpWebRequest"/> in order to send it again.
+ /// </summary>
+ /// <param name="request">The request to clone.</param>
+ /// <param name="newRequestUri">The new recipient of the request.</param>
+ /// <returns>The newly created instance.</returns>
+ internal static HttpWebRequest Clone(this HttpWebRequest request, Uri newRequestUri) {
+ ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ ErrorUtilities.VerifyArgumentNotNull(newRequestUri, "newRequestUri");
+
+ var newRequest = (HttpWebRequest)WebRequest.Create(newRequestUri);
+ newRequest.Accept = request.Accept;
+ newRequest.AllowAutoRedirect = request.AllowAutoRedirect;
+ newRequest.AllowWriteStreamBuffering = request.AllowWriteStreamBuffering;
+ newRequest.AuthenticationLevel = request.AuthenticationLevel;
+ newRequest.AutomaticDecompression = request.AutomaticDecompression;
+ newRequest.CachePolicy = request.CachePolicy;
+ newRequest.ClientCertificates = request.ClientCertificates;
+ newRequest.ConnectionGroupName = request.ConnectionGroupName;
+ if (request.ContentLength >= 0) {
+ newRequest.ContentLength = request.ContentLength;
+ }
+ newRequest.ContentType = request.ContentType;
+ newRequest.ContinueDelegate = request.ContinueDelegate;
+ newRequest.CookieContainer = request.CookieContainer;
+ newRequest.Credentials = request.Credentials;
+ newRequest.Expect = request.Expect;
+ newRequest.IfModifiedSince = request.IfModifiedSince;
+ newRequest.ImpersonationLevel = request.ImpersonationLevel;
+ newRequest.KeepAlive = request.KeepAlive;
+ newRequest.MaximumAutomaticRedirections = request.MaximumAutomaticRedirections;
+ newRequest.MaximumResponseHeadersLength = request.MaximumResponseHeadersLength;
+ newRequest.MediaType = request.MediaType;
+ newRequest.Method = request.Method;
+ newRequest.Pipelined = request.Pipelined;
+ newRequest.PreAuthenticate = request.PreAuthenticate;
+ newRequest.ProtocolVersion = request.ProtocolVersion;
+ newRequest.Proxy = request.Proxy;
+ newRequest.ReadWriteTimeout = request.ReadWriteTimeout;
+ newRequest.Referer = request.Referer;
+ newRequest.SendChunked = request.SendChunked;
+ newRequest.Timeout = request.Timeout;
+ newRequest.TransferEncoding = request.TransferEncoding;
+ newRequest.UnsafeAuthenticatedConnectionSharing = request.UnsafeAuthenticatedConnectionSharing;
+ newRequest.UseDefaultCredentials = request.UseDefaultCredentials;
+ newRequest.UserAgent = request.UserAgent;
+
+ // We copy headers last, and only those that do not yet exist as a result
+ // of setting these properties, so as to avoid exceptions thrown because
+ // there are properties .NET wants us to use rather than direct headers.
+ foreach (string header in request.Headers) {
+ if (string.IsNullOrEmpty(newRequest.Headers[header])) {
+ newRequest.Headers.Add(header, request.Headers[header]);
+ }
+ }
+
+ return newRequest;
+ }
+
+ /// <summary>
+ /// Tests whether two arrays are equal in length and contents.
+ /// </summary>
+ /// <typeparam name="T">The type of elements in the arrays.</typeparam>
+ /// <param name="first">The first array in the comparison. May not be null.</param>
+ /// <param name="second">The second array in the comparison. May not be null.</param>
+ /// <returns>True if the arrays equal; false otherwise.</returns>
+ internal static bool AreEquivalent<T>(T[] first, T[] second) {
+ if (first == null) {
+ throw new ArgumentNullException("first");
+ }
+ if (second == null) {
+ throw new ArgumentNullException("second");
+ }
+ if (first.Length != second.Length) {
+ return false;
+ }
+ for (int i = 0; i < first.Length; i++) {
+ if (!first[i].Equals(second[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Tests whether two dictionaries are equal in length and contents.
+ /// </summary>
+ /// <typeparam name="TKey">The type of keys in the dictionaries.</typeparam>
+ /// <typeparam name="TValue">The type of values in the dictionaries.</typeparam>
+ /// <param name="first">The first dictionary in the comparison. May not be null.</param>
+ /// <param name="second">The second dictionary in the comparison. May not be null.</param>
+ /// <returns>True if the arrays equal; false otherwise.</returns>
+ internal static bool AreEquivalent<TKey, TValue>(IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second) {
+ return AreEquivalent(first.ToArray(), second.ToArray());
+ }
+
+ /// <summary>
+ /// Concatenates a list of name-value pairs as key=value&amp;key=value,
+ /// taking care to properly encode each key and value for URL
+ /// transmission. No ? is prefixed to the string.
+ /// </summary>
+ /// <param name="args">The dictionary of key/values to read from.</param>
+ /// <returns>The formulated querystring style string.</returns>
+ internal static string CreateQueryString(IEnumerable<KeyValuePair<string, string>> args) {
+ ErrorUtilities.VerifyArgumentNotNull(args, "args");
+ if (args.Count() == 0) {
+ return string.Empty;
+ }
+ StringBuilder sb = new StringBuilder(args.Count() * 10);
+
+ foreach (var p in args) {
+ ErrorUtilities.VerifyArgument(p.Key != null, MessagingStrings.UnexpectedNullValue);
+ ErrorUtilities.VerifyArgument(p.Value != null, MessagingStrings.UnexpectedNullValue);
+ sb.Append(HttpUtility.UrlEncode(p.Key));
+ sb.Append('=');
+ sb.Append(HttpUtility.UrlEncode(p.Value));
+ sb.Append('&');
+ }
+ sb.Length--; // remove trailing &
+
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Adds a set of name-value pairs to the end of a given URL
+ /// as part of the querystring piece. Prefixes a ? or &amp; before
+ /// first element as necessary.
+ /// </summary>
+ /// <param name="builder">The UriBuilder to add arguments to.</param>
+ /// <param name="args">
+ /// The arguments to add to the query.
+ /// If null, <paramref name="builder"/> is not changed.
+ /// </param>
+ internal static void AppendQueryArgs(this UriBuilder builder, IEnumerable<KeyValuePair<string, string>> args) {
+ if (builder == null) {
+ throw new ArgumentNullException("builder");
+ }
+
+ if (args != null && args.Count() > 0) {
+ StringBuilder sb = new StringBuilder(50 + (args.Count() * 10));
+ if (!string.IsNullOrEmpty(builder.Query)) {
+ sb.Append(builder.Query.Substring(1));
+ sb.Append('&');
+ }
+ sb.Append(CreateQueryString(args));
+
+ builder.Query = sb.ToString();
+ }
+ }
+
+ /// <summary>
+ /// Extracts the recipient from an HttpRequestInfo.
+ /// </summary>
+ /// <param name="request">The request to get recipient information from.</param>
+ /// <returns>The recipient.</returns>
+ internal static MessageReceivingEndpoint GetRecipient(this HttpRequestInfo request) {
+ return new MessageReceivingEndpoint(request.Url, request.HttpMethod == "GET" ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest);
+ }
+
+ /// <summary>
+ /// Copies some extra parameters into a message.
+ /// </summary>
+ /// <param name="message">The message to copy the extra data into.</param>
+ /// <param name="extraParameters">The extra data to copy into the message. May be null to do nothing.</param>
+ internal static void AddExtraParameters(this IMessage message, IDictionary<string, string> extraParameters) {
+ ErrorUtilities.VerifyArgumentNotNull(message, "message");
+
+ if (extraParameters != null) {
+ MessageDictionary messageDictionary = new MessageDictionary(message);
+ foreach (var pair in extraParameters) {
+ messageDictionary.Add(pair);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Converts a <see cref="NameValueCollection"/> to an IDictionary&lt;string, string&gt;.
+ /// </summary>
+ /// <param name="nvc">The NameValueCollection to convert. May be null.</param>
+ /// <returns>The generated dictionary, or null if <paramref name="nvc"/> is null.</returns>
+ internal static Dictionary<string, string> ToDictionary(this NameValueCollection nvc) {
+ if (nvc == null) {
+ return null;
+ }
+
+ var dictionary = new Dictionary<string, string>();
+ foreach (string key in nvc) {
+ dictionary.Add(key, nvc[key]);
+ }
+
+ return dictionary;
+ }
+
+ /// <summary>
+ /// Sorts the elements of a sequence in ascending order by using a specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements of source.</typeparam>
+ /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
+ /// <param name="source">A sequence of values to order.</param>
+ /// <param name="keySelector">A function to extract a key from an element.</param>
+ /// <param name="comparer">A comparison function to compare keys.</param>
+ /// <returns>An System.Linq.IOrderedEnumerable&lt;TElement&gt; whose elements are sorted according to a key.</returns>
+ internal static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Comparison<TKey> comparer) {
+ return System.Linq.Enumerable.OrderBy<TSource, TKey>(source, keySelector, new ComparisonHelper<TKey>(comparer));
+ }
+
+ /// <summary>
+ /// Determines whether the specified message is a request (indirect message or direct request).
+ /// </summary>
+ /// <param name="message">The message in question.</param>
+ /// <returns>
+ /// <c>true</c> if the specified message is a request; otherwise, <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// Although an <see cref="IProtocolMessage"/> may implement the <see cref="IDirectedProtocolMessage"/>
+ /// interface, it may only be doing that for its derived classes. These objects are only requests
+ /// if their <see cref="IDirectedProtocolMessage.Recipient"/> property is non-null.
+ /// </remarks>
+ internal static bool IsRequest(this IDirectedProtocolMessage message) {
+ ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ return message.Recipient != null;
+ }
+
+ /// <summary>
+ /// Determines whether the specified message is a direct response.
+ /// </summary>
+ /// <param name="message">The message in question.</param>
+ /// <returns>
+ /// <c>true</c> if the specified message is a direct response; otherwise, <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// Although an <see cref="IProtocolMessage"/> may implement the
+ /// <see cref="IDirectResponseProtocolMessage"/> interface, it may only be doing
+ /// that for its derived classes. These objects are only requests if their
+ /// <see cref="IDirectResponseProtocolMessage.OriginatingRequest"/> property is non-null.
+ /// </remarks>
+ internal static bool IsDirectResponse(this IDirectResponseProtocolMessage message) {
+ ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ return message.OriginatingRequest != null;
+ }
+
+ /// <summary>
+ /// A class to convert a <see cref="Comparison&lt;T&gt;"/> into an <see cref="IComparer&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="T">The type of objects being compared.</typeparam>
+ private class ComparisonHelper<T> : IComparer<T> {
+ /// <summary>
+ /// The comparison method to use.
+ /// </summary>
+ private Comparison<T> comparison;
+
+ /// <summary>
+ /// Initializes a new instance of the ComparisonHelper class.
+ /// </summary>
+ /// <param name="comparison">The comparison method to use.</param>
+ internal ComparisonHelper(Comparison<T> comparison) {
+ if (comparison == null) {
+ throw new ArgumentNullException("comparison");
+ }
+
+ this.comparison = comparison;
+ }
+
+ #region IComparer<T> Members
+
+ /// <summary>
+ /// Compares two instances of <typeparamref name="T"/>.
+ /// </summary>
+ /// <param name="x">The first object to compare.</param>
+ /// <param name="y">The second object to compare.</param>
+ /// <returns>Any of -1, 0, or 1 according to standard comparison rules.</returns>
+ public int Compare(T x, T y) {
+ return this.comparison(x, y);
+ }
+
+ #endregion
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
index 956aae0..73d8830 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
@@ -10,7 +10,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Messages;
+ using DotNetOpenAuth.OpenId.Messages;
using DotNetOpenAuth.OpenId.RelyingParty;
/// <summary>
@@ -54,9 +54,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
} else if (string.Equals(mode, protocol.Args.Mode.checkid_setup) ||
string.Equals(mode, protocol.Args.Mode.checkid_immediate)) {
bool immediate = string.Equals(mode, protocol.Args.Mode.checkid_immediate);
- if (fields.ContainsKey(protocol.openid.identity)) {
+ if (fields.ContainsKey(protocol.openid.identity)) {
message = new CheckIdRequest(protocol.Version, recipient.Location, AuthenticationRequestMode.Immediate);
- } else {
+ } else {
message = new SignedResponseRequest(protocol.Version, recipient.Location, AuthenticationRequestMode.Immediate);
}
} else if (string.Equals(mode, protocol.Args.Mode.cancel) ||
diff --git a/src/DotNetOpenAuth/OpenId/Messages/CheckIdRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/CheckIdRequest.cs
index 038a12e..6d54504 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/CheckIdRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/CheckIdRequest.cs
@@ -1,66 +1,66 @@
-//-----------------------------------------------------------------------
-// <copyright file="CheckIdRequest.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.Messages {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.RelyingParty;
-
- /// <summary>
- /// An authentication request from a Relying Party to a Provider.
- /// </summary>
- /// <remarks>
- /// This message type satisfies OpenID 2.0 section 9.1.
- /// </remarks>
- [DebuggerDisplay("OpenID {Version} {Mode} {ClaimedIdentifier}")]
- internal class CheckIdRequest : SignedResponseRequest {
- /// <summary>
- /// Initializes a new instance of the <see cref="CheckIdRequest"/> class.
- /// </summary>
- /// <param name="version">The OpenID version to use.</param>
- /// <param name="providerEndpoint">The Provider endpoint that receives this message.</param>
- /// <param name="mode">
- /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
- /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
- /// </param>
- internal CheckIdRequest(Version version, Uri providerEndpoint, AuthenticationRequestMode mode) :
- base(version, providerEndpoint, mode) {
- }
-
- /// <summary>
- /// Gets or sets the Claimed Identifier.
- /// </summary>
- /// <remarks>
- /// <para>"openid.claimed_id" and "openid.identity" SHALL be either both present or both absent.
- /// If neither value is present, the assertion is not about an identifier,
- /// and will contain other information in its payload, using extensions (Extensions). </para>
- /// <para>It is RECOMMENDED that OPs accept XRI identifiers with or without the "xri://" prefix, as specified in the Normalization (Normalization) section. </para>
- /// </remarks>
- [MessagePart("openid.claimed_id", IsRequired = true, AllowEmpty = false, MinVersion = "2.0")]
- internal Identifier ClaimedIdentifier { get; set; }
-
- /// <summary>
- /// Gets or sets the OP Local Identifier.
- /// </summary>
- /// <value>The OP-Local Identifier. </value>
- /// <remarks>
- /// <para>If a different OP-Local Identifier is not specified, the claimed
- /// identifier MUST be used as the value for openid.identity.</para>
- /// <para>Note: If this is set to the special value
- /// "http://specs.openid.net/auth/2.0/identifier_select" then the OP SHOULD
- /// choose an Identifier that belongs to the end user. This parameter MAY
- /// be omitted if the request is not about an identifier (for instance if
- /// an extension is in use that makes the request meaningful without it;
- /// see openid.claimed_id above). </para>
- /// </remarks>
- [MessagePart("openid.identity", IsRequired = true, AllowEmpty = false)]
- internal Identifier LocalIdentifier { get; set; }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="CheckIdRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ /// <summary>
+ /// An authentication request from a Relying Party to a Provider.
+ /// </summary>
+ /// <remarks>
+ /// This message type satisfies OpenID 2.0 section 9.1.
+ /// </remarks>
+ [DebuggerDisplay("OpenID {Version} {Mode} {ClaimedIdentifier}")]
+ internal class CheckIdRequest : SignedResponseRequest {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CheckIdRequest"/> class.
+ /// </summary>
+ /// <param name="version">The OpenID version to use.</param>
+ /// <param name="providerEndpoint">The Provider endpoint that receives this message.</param>
+ /// <param name="mode">
+ /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
+ /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
+ /// </param>
+ internal CheckIdRequest(Version version, Uri providerEndpoint, AuthenticationRequestMode mode) :
+ base(version, providerEndpoint, mode) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Claimed Identifier.
+ /// </summary>
+ /// <remarks>
+ /// <para>"openid.claimed_id" and "openid.identity" SHALL be either both present or both absent.
+ /// If neither value is present, the assertion is not about an identifier,
+ /// and will contain other information in its payload, using extensions (Extensions). </para>
+ /// <para>It is RECOMMENDED that OPs accept XRI identifiers with or without the "xri://" prefix, as specified in the Normalization (Normalization) section. </para>
+ /// </remarks>
+ [MessagePart("openid.claimed_id", IsRequired = true, AllowEmpty = false, MinVersion = "2.0")]
+ internal Identifier ClaimedIdentifier { get; set; }
+
+ /// <summary>
+ /// Gets or sets the OP Local Identifier.
+ /// </summary>
+ /// <value>The OP-Local Identifier. </value>
+ /// <remarks>
+ /// <para>If a different OP-Local Identifier is not specified, the claimed
+ /// identifier MUST be used as the value for openid.identity.</para>
+ /// <para>Note: If this is set to the special value
+ /// "http://specs.openid.net/auth/2.0/identifier_select" then the OP SHOULD
+ /// choose an Identifier that belongs to the end user. This parameter MAY
+ /// be omitted if the request is not about an identifier (for instance if
+ /// an extension is in use that makes the request meaningful without it;
+ /// see openid.claimed_id above). </para>
+ /// </remarks>
+ [MessagePart("openid.identity", IsRequired = true, AllowEmpty = false)]
+ internal Identifier LocalIdentifier { get; set; }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
index 4fe066b..ef5b86a 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
@@ -1,40 +1,40 @@
-//-----------------------------------------------------------------------
-// <copyright file="IOpenIdMessageExtension.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.Messages {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// The contract any OpenID extension for DotNetOpenId must implement.
- /// </summary>
- internal interface IOpenIdMessageExtension : IExtensionMessage {
- /// <summary>
- /// Gets the TypeURI the extension uses in the OpenID protocol and in XRDS advertisements.
- /// </summary>
- string TypeUri { get; }
-
- /// <summary>
- /// Gets the additional TypeURIs that are supported by this extension, in preferred order.
- /// May be empty if none other than <see cref="TypeUri"/> is supported, but
- /// should not be null.
- /// </summary>
- /// <remarks>
- /// Useful for reading in messages with an older version of an extension.
- /// The value in the <see cref="TypeUri"/> property is always checked before
- /// trying this list.
- /// If you do support multiple versions of an extension using this method,
- /// consider adding a CreateResponse method to your request extension class
- /// so that the response can have the context it needs to remain compatible
- /// given the version of the extension in the request message.
- /// The <see cref="Extensions.SimpleRegistration.ClaimsRequest.CreateResponse"/> for an example.
- /// </remarks>
- IEnumerable<string> AdditionalSupportedTypeUris { get; }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="IOpenIdMessageExtension.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// The contract any OpenID extension for DotNetOpenId must implement.
+ /// </summary>
+ internal interface IOpenIdMessageExtension : IExtensionMessage {
+ /// <summary>
+ /// Gets the TypeURI the extension uses in the OpenID protocol and in XRDS advertisements.
+ /// </summary>
+ string TypeUri { get; }
+
+ /// <summary>
+ /// Gets the additional TypeURIs that are supported by this extension, in preferred order.
+ /// May be empty if none other than <see cref="TypeUri"/> is supported, but
+ /// should not be null.
+ /// </summary>
+ /// <remarks>
+ /// Useful for reading in messages with an older version of an extension.
+ /// The value in the <see cref="TypeUri"/> property is always checked before
+ /// trying this list.
+ /// If you do support multiple versions of an extension using this method,
+ /// consider adding a CreateResponse method to your request extension class
+ /// so that the response can have the context it needs to remain compatible
+ /// given the version of the extension in the request message.
+ /// The <see cref="Extensions.SimpleRegistration.ClaimsRequest.CreateResponse"/> for an example.
+ /// </remarks>
+ IEnumerable<string> AdditionalSupportedTypeUris { get; }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
index f2eae6a..0e21807 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
@@ -1,177 +1,177 @@
-//-----------------------------------------------------------------------
-// <copyright file="SignedResponseRequest.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.Messages {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.RelyingParty;
-
- /// <summary>
- /// An indirect request from a Relying Party to a Provider where the response
- /// is expected to be signed.
- /// </summary>
- internal class SignedResponseRequest : RequestBase, IProtocolMessageWithExtensions {
- /// <summary>
- /// Backing store for the <see cref="Extensions"/> property.
- /// </summary>
- private IList<IExtensionMessage> extensions = new List<IExtensionMessage>();
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SignedResponseRequest"/> class.
- /// </summary>
- /// <param name="version">The OpenID version to use.</param>
- /// <param name="providerEndpoint">The Provider endpoint that receives this message.</param>
- /// <param name="mode">
- /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
- /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
- /// </param>
- internal SignedResponseRequest(Version version, Uri providerEndpoint, AuthenticationRequestMode mode) :
- base(version, providerEndpoint, GetMode(version, mode), DotNetOpenAuth.Messaging.MessageTransport.Indirect) {
- }
-
- #region IProtocolMessageWithExtensions Members
-
- /// <summary>
- /// Gets the list of extensions that are included with this message.
- /// </summary>
- /// <value></value>
- /// <remarks>
- /// Implementations of this interface should ensure that this property never returns null.
- /// </remarks>
- public IList<IExtensionMessage> Extensions {
- get { return this.extensions; }
- }
-
- #endregion
-
- /// <summary>
- /// Gets a value indicating whether the Provider is allowed to interact with the user
- /// as part of authentication.
- /// </summary>
- /// <value><c>true</c> if using OpenID immediate mode; otherwise, <c>false</c>.</value>
- internal bool Immediate {
- get { return String.Equals(this.Mode, Protocol.Args.Mode.checkid_immediate, StringComparison.Ordinal); }
- }
-
- /// <summary>
- /// Gets or sets the handle of the association the RP would like the Provider
- /// to use for signing a positive assertion in the response message.
- /// </summary>
- /// <value>A handle for an association between the Relying Party and the OP
- /// that SHOULD be used to sign the response. </value>
- /// <remarks>
- /// If no association handle is sent, the transaction will take place in Stateless Mode
- /// (Verifying Directly with the OpenID Provider).
- /// </remarks>
- [MessagePart("openid.assoc_handle", IsRequired = false, AllowEmpty = false)]
- internal string AssociationHandle { get; set; }
-
- /// <summary>
- /// Gets or sets the URL the Provider should redirect the user agent to following
- /// the authentication attempt.
- /// </summary>
- /// <value>URL to which the OP SHOULD return the User-Agent with the response
- /// indicating the status of the request.</value>
- /// <remarks>
- /// <para>If this value is not sent in the request it signifies that the Relying Party
- /// does not wish for the end user to be returned. </para>
- /// <para>The return_to URL MAY be used as a mechanism for the Relying Party to attach
- /// context about the authentication request to the authentication response.
- /// This document does not define a mechanism by which the RP can ensure that query
- /// parameters are not modified by outside parties; such a mechanism can be defined
- /// by the RP itself. </para>
- /// </remarks>
- [MessagePart("openid.return_to", IsRequired = true, AllowEmpty = false)]
- [MessagePart("openid.return_to", IsRequired = false, AllowEmpty = false, MinVersion = "2.0")]
- internal Uri ReturnTo { get; set; }
-
- /// <summary>
- /// Gets or sets the Relying Party discovery URL the Provider may use to verify the
- /// source of the authentication request.
- /// </summary>
- /// <value>
- /// URL pattern the OP SHOULD ask the end user to trust. See Section 9.2 (Realms).
- /// This value MUST be sent if openid.return_to is omitted.
- /// Default: The <see cref="ReturnTo"/> URL.
- /// </value>
- [MessagePart("openid.trust_root", IsRequired = false, AllowEmpty = false)]
- [MessagePart("openid.realm", IsRequired = false, AllowEmpty = false, MinVersion = "2.0")]
- internal Realm Realm { get; set; }
-
- /// <summary>
- /// Checks the message state for conformity to the protocol specification
- /// and throws an exception if the message is invalid.
- /// </summary>
- /// <remarks>
- /// <para>Some messages have required fields, or combinations of fields that must relate to each other
- /// in specialized ways. After deserializing a message, this method checks the state of the
- /// message to see if it conforms to the protocol.</para>
- /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
- /// outside this scope of this particular message.</para>
- /// </remarks>
- /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
- public override void EnsureValidMessage() {
- base.EnsureValidMessage();
-
- if (this.Realm == null) {
- // Set the default Realm per the spec if it is not explicitly given.
- this.Realm = this.ReturnTo;
- } else if (this.ReturnTo != null) {
- // Verify that the realm and return_to agree.
- ErrorUtilities.VerifyProtocol(this.Realm.Contains(this.ReturnTo), OpenIdStrings.ReturnToNotUnderRealm, this.ReturnTo, this.Realm);
- }
- }
-
- /// <summary>
- /// Adds parameters to the return_to querystring.
- /// </summary>
- /// <param name="keysValues">The keys=value pairs to add to the return_to query string.</param>
- /// <remarks>
- /// This method is useful if the Relying Party wants to recall some value
- /// when and if a positive assertion comes back from the Provider.
- /// </remarks>
- internal void AddReturnToArguments(IEnumerable<KeyValuePair<string, string>> keysValues) {
- ErrorUtilities.VerifyArgumentNotNull(keysValues, "keysValues");
- UriBuilder returnToBuilder = new UriBuilder(this.ReturnTo);
- returnToBuilder.AppendQueryArgs(keysValues);
- this.ReturnTo = returnToBuilder.Uri;
- }
-
- /// <summary>
- /// Adds a parameter to the return_to querystring.
- /// </summary>
- /// <param name="key">The name of the parameter.</param>
- /// <param name="value">The value of the argument.</param>
- /// <remarks>
- /// This method is useful if the Relying Party wants to recall some value
- /// when and if a positive assertion comes back from the Provider.
- /// </remarks>
- internal void AddReturnToArguments(string key, string value) {
- var pair = new KeyValuePair<string, string>(key, value);
- this.AddReturnToArguments(new[] { pair });
- }
-
- /// <summary>
- /// Gets the value of the openid.mode parameter based on the protocol version and immediate flag.
- /// </summary>
- /// <param name="version">The OpenID version to use.</param>
- /// <param name="mode">
- /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
- /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
- /// </param>
- /// <returns>checkid_immediate or checkid_setup</returns>
- private static string GetMode(Version version, AuthenticationRequestMode mode) {
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
-
- Protocol protocol = Protocol.Lookup(version);
- return mode == AuthenticationRequestMode.Immediate ? protocol.Args.Mode.checkid_immediate : protocol.Args.Mode.checkid_setup;
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="SignedResponseRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ /// <summary>
+ /// An indirect request from a Relying Party to a Provider where the response
+ /// is expected to be signed.
+ /// </summary>
+ internal class SignedResponseRequest : RequestBase, IProtocolMessageWithExtensions {
+ /// <summary>
+ /// Backing store for the <see cref="Extensions"/> property.
+ /// </summary>
+ private IList<IExtensionMessage> extensions = new List<IExtensionMessage>();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SignedResponseRequest"/> class.
+ /// </summary>
+ /// <param name="version">The OpenID version to use.</param>
+ /// <param name="providerEndpoint">The Provider endpoint that receives this message.</param>
+ /// <param name="mode">
+ /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
+ /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
+ /// </param>
+ internal SignedResponseRequest(Version version, Uri providerEndpoint, AuthenticationRequestMode mode) :
+ base(version, providerEndpoint, GetMode(version, mode), DotNetOpenAuth.Messaging.MessageTransport.Indirect) {
+ }
+
+ #region IProtocolMessageWithExtensions Members
+
+ /// <summary>
+ /// Gets the list of extensions that are included with this message.
+ /// </summary>
+ /// <value></value>
+ /// <remarks>
+ /// Implementations of this interface should ensure that this property never returns null.
+ /// </remarks>
+ public IList<IExtensionMessage> Extensions {
+ get { return this.extensions; }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Gets a value indicating whether the Provider is allowed to interact with the user
+ /// as part of authentication.
+ /// </summary>
+ /// <value><c>true</c> if using OpenID immediate mode; otherwise, <c>false</c>.</value>
+ internal bool Immediate {
+ get { return String.Equals(this.Mode, Protocol.Args.Mode.checkid_immediate, StringComparison.Ordinal); }
+ }
+
+ /// <summary>
+ /// Gets or sets the handle of the association the RP would like the Provider
+ /// to use for signing a positive assertion in the response message.
+ /// </summary>
+ /// <value>A handle for an association between the Relying Party and the OP
+ /// that SHOULD be used to sign the response. </value>
+ /// <remarks>
+ /// If no association handle is sent, the transaction will take place in Stateless Mode
+ /// (Verifying Directly with the OpenID Provider).
+ /// </remarks>
+ [MessagePart("openid.assoc_handle", IsRequired = false, AllowEmpty = false)]
+ internal string AssociationHandle { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL the Provider should redirect the user agent to following
+ /// the authentication attempt.
+ /// </summary>
+ /// <value>URL to which the OP SHOULD return the User-Agent with the response
+ /// indicating the status of the request.</value>
+ /// <remarks>
+ /// <para>If this value is not sent in the request it signifies that the Relying Party
+ /// does not wish for the end user to be returned. </para>
+ /// <para>The return_to URL MAY be used as a mechanism for the Relying Party to attach
+ /// context about the authentication request to the authentication response.
+ /// This document does not define a mechanism by which the RP can ensure that query
+ /// parameters are not modified by outside parties; such a mechanism can be defined
+ /// by the RP itself. </para>
+ /// </remarks>
+ [MessagePart("openid.return_to", IsRequired = true, AllowEmpty = false)]
+ [MessagePart("openid.return_to", IsRequired = false, AllowEmpty = false, MinVersion = "2.0")]
+ internal Uri ReturnTo { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Relying Party discovery URL the Provider may use to verify the
+ /// source of the authentication request.
+ /// </summary>
+ /// <value>
+ /// URL pattern the OP SHOULD ask the end user to trust. See Section 9.2 (Realms).
+ /// This value MUST be sent if openid.return_to is omitted.
+ /// Default: The <see cref="ReturnTo"/> URL.
+ /// </value>
+ [MessagePart("openid.trust_root", IsRequired = false, AllowEmpty = false)]
+ [MessagePart("openid.realm", IsRequired = false, AllowEmpty = false, MinVersion = "2.0")]
+ internal Realm Realm { get; set; }
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ /// <remarks>
+ /// <para>Some messages have required fields, or combinations of fields that must relate to each other
+ /// in specialized ways. After deserializing a message, this method checks the state of the
+ /// message to see if it conforms to the protocol.</para>
+ /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
+ /// outside this scope of this particular message.</para>
+ /// </remarks>
+ /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
+ public override void EnsureValidMessage() {
+ base.EnsureValidMessage();
+
+ if (this.Realm == null) {
+ // Set the default Realm per the spec if it is not explicitly given.
+ this.Realm = this.ReturnTo;
+ } else if (this.ReturnTo != null) {
+ // Verify that the realm and return_to agree.
+ ErrorUtilities.VerifyProtocol(this.Realm.Contains(this.ReturnTo), OpenIdStrings.ReturnToNotUnderRealm, this.ReturnTo, this.Realm);
+ }
+ }
+
+ /// <summary>
+ /// Adds parameters to the return_to querystring.
+ /// </summary>
+ /// <param name="keysValues">The keys=value pairs to add to the return_to query string.</param>
+ /// <remarks>
+ /// This method is useful if the Relying Party wants to recall some value
+ /// when and if a positive assertion comes back from the Provider.
+ /// </remarks>
+ internal void AddReturnToArguments(IEnumerable<KeyValuePair<string, string>> keysValues) {
+ ErrorUtilities.VerifyArgumentNotNull(keysValues, "keysValues");
+ UriBuilder returnToBuilder = new UriBuilder(this.ReturnTo);
+ returnToBuilder.AppendQueryArgs(keysValues);
+ this.ReturnTo = returnToBuilder.Uri;
+ }
+
+ /// <summary>
+ /// Adds a parameter to the return_to querystring.
+ /// </summary>
+ /// <param name="key">The name of the parameter.</param>
+ /// <param name="value">The value of the argument.</param>
+ /// <remarks>
+ /// This method is useful if the Relying Party wants to recall some value
+ /// when and if a positive assertion comes back from the Provider.
+ /// </remarks>
+ internal void AddReturnToArguments(string key, string value) {
+ var pair = new KeyValuePair<string, string>(key, value);
+ this.AddReturnToArguments(new[] { pair });
+ }
+
+ /// <summary>
+ /// Gets the value of the openid.mode parameter based on the protocol version and immediate flag.
+ /// </summary>
+ /// <param name="version">The OpenID version to use.</param>
+ /// <param name="mode">
+ /// <see cref="AuthenticationRequestMode.Immediate"/> for asynchronous javascript clients;
+ /// <see cref="AuthenticationRequestMode.Setup"/> to allow the Provider to interact with the user in order to complete authentication.
+ /// </param>
+ /// <returns>checkid_immediate or checkid_setup</returns>
+ private static string GetMode(Version version, AuthenticationRequestMode mode) {
+ ErrorUtilities.VerifyArgumentNotNull(version, "version");
+
+ Protocol protocol = Protocol.Lookup(version);
+ return mode == AuthenticationRequestMode.Immediate ? protocol.Args.Mode.checkid_immediate : protocol.Args.Mode.checkid_setup;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
index ad62c27..c8566f8 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
@@ -1,333 +1,333 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:2.0.50727.3521
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId {
- using System;
-
-
- /// <summary>
- /// A strongly-typed resource class, for looking up localized strings, etc.
- /// </summary>
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class OpenIdStrings {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal OpenIdStrings() {
- }
-
- /// <summary>
- /// Returns the cached ResourceManager instance used by this class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.OpenId.OpenIdStrings", typeof(OpenIdStrings).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- /// <summary>
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The association and nonce stores must either be both null or both non-null..
- /// </summary>
- internal static string AssociationAndNonceStoresMustBeBothNullOrBothNonNull {
- get {
- return ResourceManager.GetString("AssociationAndNonceStoresMustBeBothNullOrBothNonNull", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The length of the shared secret ({0}) does not match the length required by the association type (&apos;{1}&apos;)..
- /// </summary>
- internal static string AssociationSecretAndTypeLengthMismatch {
- get {
- return ResourceManager.GetString("AssociationSecretAndTypeLengthMismatch", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The length of the encrypted shared secret ({0}) does not match the length of the hashing algorithm ({1})..
- /// </summary>
- internal static string AssociationSecretHashLengthMismatch {
- get {
- return ResourceManager.GetString("AssociationSecretHashLengthMismatch", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The private data supplied does not meet the requirements of any known Association type. Its length may be too short, or it may have been corrupted..
- /// </summary>
- internal static string BadAssociationPrivateData {
- get {
- return ResourceManager.GetString("BadAssociationPrivateData", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to A Simple Registration request can only generate a response on the receiving end..
- /// </summary>
- internal static string CallDeserializeBeforeCreateResponse {
- get {
- return ResourceManager.GetString("CallDeserializeBeforeCreateResponse", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The openid.claimed_id and openid.identity parameters must both be present or both be absent..
- /// </summary>
- internal static string ClaimedIdAndLocalIdMustBothPresentOrAbsent {
- get {
- return ResourceManager.GetString("ClaimedIdAndLocalIdMustBothPresentOrAbsent", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The following properties must be set before the Diffie-Hellman algorithm can generate a public key: {0}.
- /// </summary>
- internal static string DiffieHellmanRequiredPropertiesNotSet {
- get {
- return ResourceManager.GetString("DiffieHellmanRequiredPropertiesNotSet", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to URI is not SSL yet requireSslDiscovery is set to true..
- /// </summary>
- internal static string ExplicitHttpUriSuppliedWithSslRequirement {
- get {
- return ResourceManager.GetString("ExplicitHttpUriSuppliedWithSslRequirement", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to An extension sharing namespace &apos;{0}&apos; has already been added. Only one extension per namespace is allowed in a given request..
- /// </summary>
- internal static string ExtensionAlreadyAddedWithSameTypeURI {
- get {
- return ResourceManager.GetString("ExtensionAlreadyAddedWithSameTypeURI", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Cannot encode &apos;{0}&apos; because it contains an illegal character for Key-Value Form encoding. (line {1}: &apos;{2}&apos;).
- /// </summary>
- internal static string InvalidCharacterInKeyValueFormInput {
- get {
- return ResourceManager.GetString("InvalidCharacterInKeyValueFormInput", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Cannot decode Key-Value Form because a line was found without a &apos;{0}&apos; character. (line {1}: &apos;{2}&apos;).
- /// </summary>
- internal static string InvalidKeyValueFormCharacterMissing {
- get {
- return ResourceManager.GetString("InvalidKeyValueFormCharacterMissing", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The scheme must be http or https but was &apos;{0}&apos;..
- /// </summary>
- internal static string InvalidScheme {
- get {
- return ResourceManager.GetString("InvalidScheme", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The value &apos;{0}&apos; is not a valid URI..
- /// </summary>
- internal static string InvalidUri {
- get {
- return ResourceManager.GetString("InvalidUri", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Not a recognized XRI format: &apos;{0}&apos;..
- /// </summary>
- internal static string InvalidXri {
- get {
- return ResourceManager.GetString("InvalidXri", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The list of keys do not match the provided dictionary..
- /// </summary>
- internal static string KeysListAndDictionaryDoNotMatch {
- get {
- return ResourceManager.GetString("KeysListAndDictionaryDoNotMatch", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to No recognized association type matches the requested length of {0}..
- /// </summary>
- internal static string NoAssociationTypeFoundByLength {
- get {
- return ResourceManager.GetString("NoAssociationTypeFoundByLength", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to No recognized association type matches the requested name of &apos;{0}&apos;..
- /// </summary>
- internal static string NoAssociationTypeFoundByName {
- get {
- return ResourceManager.GetString("NoAssociationTypeFoundByName", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Unless using transport layer encryption, &quot;no-encryption&quot; MUST NOT be used..
- /// </summary>
- internal static string NoEncryptionSessionRequiresHttps {
- get {
- return ResourceManager.GetString("NoEncryptionSessionRequiresHttps", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Diffie-Hellman session type &apos;{0}&apos; not found for OpenID {1}..
- /// </summary>
- internal static string NoSessionTypeFound {
- get {
- return ResourceManager.GetString("NoSessionTypeFound", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Unable to determine the version of the OpenID protocol implemented by the Provider at endpoint &apos;{0}&apos;..
- /// </summary>
- internal static string ProviderVersionUnrecognized {
- get {
- return ResourceManager.GetString("ProviderVersionUnrecognized", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to An HTTP request to the realm URL ({0}) resulted in a redirect, which is not allowed during relying party discovery..
- /// </summary>
- internal static string RealmCausedRedirectUponDiscovery {
- get {
- return ResourceManager.GetString("RealmCausedRedirectUponDiscovery", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to return_to &apos;{0}&apos; not under realm &apos;{1}&apos;..
- /// </summary>
- internal static string ReturnToNotUnderRealm {
- get {
- return ResourceManager.GetString("ReturnToNotUnderRealm", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The {0} parameter ({1}) does not match the actual URL ({2}) the request was made with..
- /// </summary>
- internal static string ReturnToParamDoesNotMatchRequestUrl {
- get {
- return ResourceManager.GetString("ReturnToParamDoesNotMatchRequestUrl", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The openid.return_to parameter is required in the request message in order to construct a response, but that parameter was missing..
- /// </summary>
- internal static string ReturnToRequiredForResponse {
- get {
- return ResourceManager.GetString("ReturnToRequiredForResponse", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The following parameter(s) are not included in the signature but must be: {0}.
- /// </summary>
- internal static string SignatureDoesNotIncludeMandatoryParts {
- get {
- return ResourceManager.GetString("SignatureDoesNotIncludeMandatoryParts", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Invalid birthdate value. Must be in the form yyyy-MM-dd..
- /// </summary>
- internal static string SregInvalidBirthdate {
- get {
- return ResourceManager.GetString("SregInvalidBirthdate", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The type must implement {0}..
- /// </summary>
- internal static string TypeMustImplementX {
- get {
- return ResourceManager.GetString("TypeMustImplementX", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Unsolicited assertions are not allowed from 1.0 OpenID Providers..
- /// </summary>
- internal static string UnsolicitedAssertionsNotAllowedFrom1xOPs {
- get {
- return ResourceManager.GetString("UnsolicitedAssertionsNotAllowedFrom1xOPs", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The openid.user_setup_url parameter is required when sending negative assertion messages in response to immediate mode requests..
- /// </summary>
- internal static string UserSetupUrlRequiredInImmediateNegativeResponse {
- get {
- return ResourceManager.GetString("UserSetupUrlRequiredInImmediateNegativeResponse", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to XRI resolution failed..
- /// </summary>
- internal static string XriResolutionFailed {
- get {
- return ResourceManager.GetString("XriResolutionFailed", resourceCulture);
- }
- }
- }
-}
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class OpenIdStrings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal OpenIdStrings() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.OpenId.OpenIdStrings", typeof(OpenIdStrings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The association and nonce stores must either be both null or both non-null..
+ /// </summary>
+ internal static string AssociationAndNonceStoresMustBeBothNullOrBothNonNull {
+ get {
+ return ResourceManager.GetString("AssociationAndNonceStoresMustBeBothNullOrBothNonNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The length of the shared secret ({0}) does not match the length required by the association type (&apos;{1}&apos;)..
+ /// </summary>
+ internal static string AssociationSecretAndTypeLengthMismatch {
+ get {
+ return ResourceManager.GetString("AssociationSecretAndTypeLengthMismatch", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The length of the encrypted shared secret ({0}) does not match the length of the hashing algorithm ({1})..
+ /// </summary>
+ internal static string AssociationSecretHashLengthMismatch {
+ get {
+ return ResourceManager.GetString("AssociationSecretHashLengthMismatch", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The private data supplied does not meet the requirements of any known Association type. Its length may be too short, or it may have been corrupted..
+ /// </summary>
+ internal static string BadAssociationPrivateData {
+ get {
+ return ResourceManager.GetString("BadAssociationPrivateData", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A Simple Registration request can only generate a response on the receiving end..
+ /// </summary>
+ internal static string CallDeserializeBeforeCreateResponse {
+ get {
+ return ResourceManager.GetString("CallDeserializeBeforeCreateResponse", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The openid.claimed_id and openid.identity parameters must both be present or both be absent..
+ /// </summary>
+ internal static string ClaimedIdAndLocalIdMustBothPresentOrAbsent {
+ get {
+ return ResourceManager.GetString("ClaimedIdAndLocalIdMustBothPresentOrAbsent", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The following properties must be set before the Diffie-Hellman algorithm can generate a public key: {0}.
+ /// </summary>
+ internal static string DiffieHellmanRequiredPropertiesNotSet {
+ get {
+ return ResourceManager.GetString("DiffieHellmanRequiredPropertiesNotSet", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to URI is not SSL yet requireSslDiscovery is set to true..
+ /// </summary>
+ internal static string ExplicitHttpUriSuppliedWithSslRequirement {
+ get {
+ return ResourceManager.GetString("ExplicitHttpUriSuppliedWithSslRequirement", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An extension sharing namespace &apos;{0}&apos; has already been added. Only one extension per namespace is allowed in a given request..
+ /// </summary>
+ internal static string ExtensionAlreadyAddedWithSameTypeURI {
+ get {
+ return ResourceManager.GetString("ExtensionAlreadyAddedWithSameTypeURI", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot encode &apos;{0}&apos; because it contains an illegal character for Key-Value Form encoding. (line {1}: &apos;{2}&apos;).
+ /// </summary>
+ internal static string InvalidCharacterInKeyValueFormInput {
+ get {
+ return ResourceManager.GetString("InvalidCharacterInKeyValueFormInput", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot decode Key-Value Form because a line was found without a &apos;{0}&apos; character. (line {1}: &apos;{2}&apos;).
+ /// </summary>
+ internal static string InvalidKeyValueFormCharacterMissing {
+ get {
+ return ResourceManager.GetString("InvalidKeyValueFormCharacterMissing", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The scheme must be http or https but was &apos;{0}&apos;..
+ /// </summary>
+ internal static string InvalidScheme {
+ get {
+ return ResourceManager.GetString("InvalidScheme", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The value &apos;{0}&apos; is not a valid URI..
+ /// </summary>
+ internal static string InvalidUri {
+ get {
+ return ResourceManager.GetString("InvalidUri", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Not a recognized XRI format: &apos;{0}&apos;..
+ /// </summary>
+ internal static string InvalidXri {
+ get {
+ return ResourceManager.GetString("InvalidXri", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The list of keys do not match the provided dictionary..
+ /// </summary>
+ internal static string KeysListAndDictionaryDoNotMatch {
+ get {
+ return ResourceManager.GetString("KeysListAndDictionaryDoNotMatch", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to No recognized association type matches the requested length of {0}..
+ /// </summary>
+ internal static string NoAssociationTypeFoundByLength {
+ get {
+ return ResourceManager.GetString("NoAssociationTypeFoundByLength", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to No recognized association type matches the requested name of &apos;{0}&apos;..
+ /// </summary>
+ internal static string NoAssociationTypeFoundByName {
+ get {
+ return ResourceManager.GetString("NoAssociationTypeFoundByName", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unless using transport layer encryption, &quot;no-encryption&quot; MUST NOT be used..
+ /// </summary>
+ internal static string NoEncryptionSessionRequiresHttps {
+ get {
+ return ResourceManager.GetString("NoEncryptionSessionRequiresHttps", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Diffie-Hellman session type &apos;{0}&apos; not found for OpenID {1}..
+ /// </summary>
+ internal static string NoSessionTypeFound {
+ get {
+ return ResourceManager.GetString("NoSessionTypeFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to determine the version of the OpenID protocol implemented by the Provider at endpoint &apos;{0}&apos;..
+ /// </summary>
+ internal static string ProviderVersionUnrecognized {
+ get {
+ return ResourceManager.GetString("ProviderVersionUnrecognized", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An HTTP request to the realm URL ({0}) resulted in a redirect, which is not allowed during relying party discovery..
+ /// </summary>
+ internal static string RealmCausedRedirectUponDiscovery {
+ get {
+ return ResourceManager.GetString("RealmCausedRedirectUponDiscovery", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to return_to &apos;{0}&apos; not under realm &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReturnToNotUnderRealm {
+ get {
+ return ResourceManager.GetString("ReturnToNotUnderRealm", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The {0} parameter ({1}) does not match the actual URL ({2}) the request was made with..
+ /// </summary>
+ internal static string ReturnToParamDoesNotMatchRequestUrl {
+ get {
+ return ResourceManager.GetString("ReturnToParamDoesNotMatchRequestUrl", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The openid.return_to parameter is required in the request message in order to construct a response, but that parameter was missing..
+ /// </summary>
+ internal static string ReturnToRequiredForResponse {
+ get {
+ return ResourceManager.GetString("ReturnToRequiredForResponse", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The following parameter(s) are not included in the signature but must be: {0}.
+ /// </summary>
+ internal static string SignatureDoesNotIncludeMandatoryParts {
+ get {
+ return ResourceManager.GetString("SignatureDoesNotIncludeMandatoryParts", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Invalid birthdate value. Must be in the form yyyy-MM-dd..
+ /// </summary>
+ internal static string SregInvalidBirthdate {
+ get {
+ return ResourceManager.GetString("SregInvalidBirthdate", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The type must implement {0}..
+ /// </summary>
+ internal static string TypeMustImplementX {
+ get {
+ return ResourceManager.GetString("TypeMustImplementX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unsolicited assertions are not allowed from 1.0 OpenID Providers..
+ /// </summary>
+ internal static string UnsolicitedAssertionsNotAllowedFrom1xOPs {
+ get {
+ return ResourceManager.GetString("UnsolicitedAssertionsNotAllowedFrom1xOPs", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The openid.user_setup_url parameter is required when sending negative assertion messages in response to immediate mode requests..
+ /// </summary>
+ internal static string UserSetupUrlRequiredInImmediateNegativeResponse {
+ get {
+ return ResourceManager.GetString("UserSetupUrlRequiredInImmediateNegativeResponse", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to XRI resolution failed..
+ /// </summary>
+ internal static string XriResolutionFailed {
+ get {
+ return ResourceManager.GetString("XriResolutionFailed", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
index c1d755b..8b5e09f 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
@@ -1,210 +1,210 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="AssociationAndNonceStoresMustBeBothNullOrBothNonNull" xml:space="preserve">
- <value>The association and nonce stores must either be both null or both non-null.</value>
- </data>
- <data name="AssociationSecretAndTypeLengthMismatch" xml:space="preserve">
- <value>The length of the shared secret ({0}) does not match the length required by the association type ('{1}').</value>
- </data>
- <data name="AssociationSecretHashLengthMismatch" xml:space="preserve">
- <value>The length of the encrypted shared secret ({0}) does not match the length of the hashing algorithm ({1}).</value>
- </data>
- <data name="BadAssociationPrivateData" xml:space="preserve">
- <value>The private data supplied does not meet the requirements of any known Association type. Its length may be too short, or it may have been corrupted.</value>
- </data>
- <data name="CallDeserializeBeforeCreateResponse" xml:space="preserve">
- <value>A Simple Registration request can only generate a response on the receiving end.</value>
- </data>
- <data name="ClaimedIdAndLocalIdMustBothPresentOrAbsent" xml:space="preserve">
- <value>The openid.claimed_id and openid.identity parameters must both be present or both be absent.</value>
- </data>
- <data name="DiffieHellmanRequiredPropertiesNotSet" xml:space="preserve">
- <value>The following properties must be set before the Diffie-Hellman algorithm can generate a public key: {0}</value>
- </data>
- <data name="ExplicitHttpUriSuppliedWithSslRequirement" xml:space="preserve">
- <value>URI is not SSL yet requireSslDiscovery is set to true.</value>
- </data>
- <data name="ExtensionAlreadyAddedWithSameTypeURI" xml:space="preserve">
- <value>An extension sharing namespace '{0}' has already been added. Only one extension per namespace is allowed in a given request.</value>
- </data>
- <data name="InvalidCharacterInKeyValueFormInput" xml:space="preserve">
- <value>Cannot encode '{0}' because it contains an illegal character for Key-Value Form encoding. (line {1}: '{2}')</value>
- </data>
- <data name="InvalidKeyValueFormCharacterMissing" xml:space="preserve">
- <value>Cannot decode Key-Value Form because a line was found without a '{0}' character. (line {1}: '{2}')</value>
- </data>
- <data name="InvalidScheme" xml:space="preserve">
- <value>The scheme must be http or https but was '{0}'.</value>
- </data>
- <data name="InvalidUri" xml:space="preserve">
- <value>The value '{0}' is not a valid URI.</value>
- </data>
- <data name="InvalidXri" xml:space="preserve">
- <value>Not a recognized XRI format: '{0}'.</value>
- </data>
- <data name="KeysListAndDictionaryDoNotMatch" xml:space="preserve">
- <value>The list of keys do not match the provided dictionary.</value>
- </data>
- <data name="NoAssociationTypeFoundByLength" xml:space="preserve">
- <value>No recognized association type matches the requested length of {0}.</value>
- </data>
- <data name="NoAssociationTypeFoundByName" xml:space="preserve">
- <value>No recognized association type matches the requested name of '{0}'.</value>
- </data>
- <data name="NoEncryptionSessionRequiresHttps" xml:space="preserve">
- <value>Unless using transport layer encryption, "no-encryption" MUST NOT be used.</value>
- </data>
- <data name="NoSessionTypeFound" xml:space="preserve">
- <value>Diffie-Hellman session type '{0}' not found for OpenID {1}.</value>
- </data>
- <data name="ProviderVersionUnrecognized" xml:space="preserve">
- <value>Unable to determine the version of the OpenID protocol implemented by the Provider at endpoint '{0}'.</value>
- </data>
- <data name="RealmCausedRedirectUponDiscovery" xml:space="preserve">
- <value>An HTTP request to the realm URL ({0}) resulted in a redirect, which is not allowed during relying party discovery.</value>
- </data>
- <data name="ReturnToNotUnderRealm" xml:space="preserve">
- <value>return_to '{0}' not under realm '{1}'.</value>
- </data>
- <data name="ReturnToParamDoesNotMatchRequestUrl" xml:space="preserve">
- <value>The {0} parameter ({1}) does not match the actual URL ({2}) the request was made with.</value>
- </data>
- <data name="ReturnToRequiredForResponse" xml:space="preserve">
- <value>The openid.return_to parameter is required in the request message in order to construct a response, but that parameter was missing.</value>
- </data>
- <data name="SignatureDoesNotIncludeMandatoryParts" xml:space="preserve">
- <value>The following parameter(s) are not included in the signature but must be: {0}</value>
- </data>
- <data name="SregInvalidBirthdate" xml:space="preserve">
- <value>Invalid birthdate value. Must be in the form yyyy-MM-dd.</value>
- </data>
- <data name="TypeMustImplementX" xml:space="preserve">
- <value>The type must implement {0}.</value>
- </data>
- <data name="UnsolicitedAssertionsNotAllowedFrom1xOPs" xml:space="preserve">
- <value>Unsolicited assertions are not allowed from 1.0 OpenID Providers.</value>
- </data>
- <data name="UserSetupUrlRequiredInImmediateNegativeResponse" xml:space="preserve">
- <value>The openid.user_setup_url parameter is required when sending negative assertion messages in response to immediate mode requests.</value>
- </data>
- <data name="XriResolutionFailed" xml:space="preserve">
- <value>XRI resolution failed.</value>
- </data>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="AssociationAndNonceStoresMustBeBothNullOrBothNonNull" xml:space="preserve">
+ <value>The association and nonce stores must either be both null or both non-null.</value>
+ </data>
+ <data name="AssociationSecretAndTypeLengthMismatch" xml:space="preserve">
+ <value>The length of the shared secret ({0}) does not match the length required by the association type ('{1}').</value>
+ </data>
+ <data name="AssociationSecretHashLengthMismatch" xml:space="preserve">
+ <value>The length of the encrypted shared secret ({0}) does not match the length of the hashing algorithm ({1}).</value>
+ </data>
+ <data name="BadAssociationPrivateData" xml:space="preserve">
+ <value>The private data supplied does not meet the requirements of any known Association type. Its length may be too short, or it may have been corrupted.</value>
+ </data>
+ <data name="CallDeserializeBeforeCreateResponse" xml:space="preserve">
+ <value>A Simple Registration request can only generate a response on the receiving end.</value>
+ </data>
+ <data name="ClaimedIdAndLocalIdMustBothPresentOrAbsent" xml:space="preserve">
+ <value>The openid.claimed_id and openid.identity parameters must both be present or both be absent.</value>
+ </data>
+ <data name="DiffieHellmanRequiredPropertiesNotSet" xml:space="preserve">
+ <value>The following properties must be set before the Diffie-Hellman algorithm can generate a public key: {0}</value>
+ </data>
+ <data name="ExplicitHttpUriSuppliedWithSslRequirement" xml:space="preserve">
+ <value>URI is not SSL yet requireSslDiscovery is set to true.</value>
+ </data>
+ <data name="ExtensionAlreadyAddedWithSameTypeURI" xml:space="preserve">
+ <value>An extension sharing namespace '{0}' has already been added. Only one extension per namespace is allowed in a given request.</value>
+ </data>
+ <data name="InvalidCharacterInKeyValueFormInput" xml:space="preserve">
+ <value>Cannot encode '{0}' because it contains an illegal character for Key-Value Form encoding. (line {1}: '{2}')</value>
+ </data>
+ <data name="InvalidKeyValueFormCharacterMissing" xml:space="preserve">
+ <value>Cannot decode Key-Value Form because a line was found without a '{0}' character. (line {1}: '{2}')</value>
+ </data>
+ <data name="InvalidScheme" xml:space="preserve">
+ <value>The scheme must be http or https but was '{0}'.</value>
+ </data>
+ <data name="InvalidUri" xml:space="preserve">
+ <value>The value '{0}' is not a valid URI.</value>
+ </data>
+ <data name="InvalidXri" xml:space="preserve">
+ <value>Not a recognized XRI format: '{0}'.</value>
+ </data>
+ <data name="KeysListAndDictionaryDoNotMatch" xml:space="preserve">
+ <value>The list of keys do not match the provided dictionary.</value>
+ </data>
+ <data name="NoAssociationTypeFoundByLength" xml:space="preserve">
+ <value>No recognized association type matches the requested length of {0}.</value>
+ </data>
+ <data name="NoAssociationTypeFoundByName" xml:space="preserve">
+ <value>No recognized association type matches the requested name of '{0}'.</value>
+ </data>
+ <data name="NoEncryptionSessionRequiresHttps" xml:space="preserve">
+ <value>Unless using transport layer encryption, "no-encryption" MUST NOT be used.</value>
+ </data>
+ <data name="NoSessionTypeFound" xml:space="preserve">
+ <value>Diffie-Hellman session type '{0}' not found for OpenID {1}.</value>
+ </data>
+ <data name="ProviderVersionUnrecognized" xml:space="preserve">
+ <value>Unable to determine the version of the OpenID protocol implemented by the Provider at endpoint '{0}'.</value>
+ </data>
+ <data name="RealmCausedRedirectUponDiscovery" xml:space="preserve">
+ <value>An HTTP request to the realm URL ({0}) resulted in a redirect, which is not allowed during relying party discovery.</value>
+ </data>
+ <data name="ReturnToNotUnderRealm" xml:space="preserve">
+ <value>return_to '{0}' not under realm '{1}'.</value>
+ </data>
+ <data name="ReturnToParamDoesNotMatchRequestUrl" xml:space="preserve">
+ <value>The {0} parameter ({1}) does not match the actual URL ({2}) the request was made with.</value>
+ </data>
+ <data name="ReturnToRequiredForResponse" xml:space="preserve">
+ <value>The openid.return_to parameter is required in the request message in order to construct a response, but that parameter was missing.</value>
+ </data>
+ <data name="SignatureDoesNotIncludeMandatoryParts" xml:space="preserve">
+ <value>The following parameter(s) are not included in the signature but must be: {0}</value>
+ </data>
+ <data name="SregInvalidBirthdate" xml:space="preserve">
+ <value>Invalid birthdate value. Must be in the form yyyy-MM-dd.</value>
+ </data>
+ <data name="TypeMustImplementX" xml:space="preserve">
+ <value>The type must implement {0}.</value>
+ </data>
+ <data name="UnsolicitedAssertionsNotAllowedFrom1xOPs" xml:space="preserve">
+ <value>Unsolicited assertions are not allowed from 1.0 OpenID Providers.</value>
+ </data>
+ <data name="UserSetupUrlRequiredInImmediateNegativeResponse" xml:space="preserve">
+ <value>The openid.user_setup_url parameter is required when sending negative assertion messages in response to immediate mode requests.</value>
+ </data>
+ <data name="XriResolutionFailed" xml:space="preserve">
+ <value>XRI resolution failed.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequestMode.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequestMode.cs
index 15e0ad8..40ea66a 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequestMode.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequestMode.cs
@@ -1,26 +1,26 @@
-//-----------------------------------------------------------------------
-// <copyright file="AuthenticationRequestMode.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- /// <summary>
- /// Indicates the mode the Provider should use while authenticating the end user.
- /// </summary>
- public enum AuthenticationRequestMode {
- /// <summary>
- /// The Provider should use whatever credentials are immediately available
- /// to determine whether the end user owns the Identifier. If sufficient
- /// credentials (i.e. cookies) are not immediately available, the Provider
- /// should fail rather than prompt the user.
- /// </summary>
- Immediate,
-
- /// <summary>
- /// The Provider should determine whether the end user owns the Identifier,
- /// displaying a web page to the user to login etc., if necessary.
- /// </summary>
- Setup,
- }
+//-----------------------------------------------------------------------
+// <copyright file="AuthenticationRequestMode.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ /// <summary>
+ /// Indicates the mode the Provider should use while authenticating the end user.
+ /// </summary>
+ public enum AuthenticationRequestMode {
+ /// <summary>
+ /// The Provider should use whatever credentials are immediately available
+ /// to determine whether the end user owns the Identifier. If sufficient
+ /// credentials (i.e. cookies) are not immediately available, the Provider
+ /// should fail rather than prompt the user.
+ /// </summary>
+ Immediate,
+
+ /// <summary>
+ /// The Provider should determine whether the end user owns the Identifier,
+ /// displaying a web page to the user to login etc., if necessary.
+ /// </summary>
+ Setup,
+ }
} \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
index f4e03a5..ed9a7ca 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -1,110 +1,110 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingParty.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OpenId.ChannelElements;
- using DotNetOpenAuth.OpenId.Messages;
-
- /// <summary>
- /// Provides the programmatic facilities to act as an OpenId consumer.
- /// </summary>
- public sealed class OpenIdRelyingParty {
- /// <summary>
- /// The untrusted web request handler we use (and share) by default across all RP instances.
- /// </summary>
- private static IDirectSslWebRequestHandler defaultUntrustedWebRequestHandler = new UntrustedWebRequestHandler();
-
- /// <summary>
- /// Backing field for the <see cref="SecuritySettings"/> property.
- /// </summary>
- private RelyingPartySecuritySettings securitySettings;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class.
- /// </summary>
- /// <param name="associationStore">The association store. If null, the relying party will always operate in "dumb mode".</param>
- /// <param name="nonceStore">The nonce store to use. If null, the relying party will always operate in "dumb mode".</param>
- /// <param name="secretStore">The secret store to use. If null, the relying party will always operate in "dumb mode".</param>
- public OpenIdRelyingParty(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore) {
- // TODO: fix this so that a null association store is supported as 'dumb mode only'.
- ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore");
- ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
- ErrorUtilities.VerifyArgumentNotNull(secretStore, "secretStore");
- ErrorUtilities.VerifyArgument((associationStore == null) == (nonceStore == null), OpenIdStrings.AssociationAndNonceStoresMustBeBothNullOrBothNonNull);
-
- this.Channel = new OpenIdChannel(associationStore, nonceStore, secretStore);
- this.AssociationStore = associationStore;
- this.SecuritySettings = RelyingPartySection.Configuration.SecuritySettings.CreateSecuritySettings();
- this.WebRequestHandler = defaultUntrustedWebRequestHandler;
- }
-
- /// <summary>
- /// Gets the channel to use for sending/receiving messages.
- /// </summary>
- public Channel Channel { get; internal set; }
-
- /// <summary>
- /// Gets the security settings used by this Relying Party.
- /// </summary>
- public RelyingPartySecuritySettings SecuritySettings {
- get {
- return this.securitySettings;
- }
-
- internal set {
- if (value == null) {
- throw new ArgumentNullException("value");
- }
-
- this.securitySettings = value;
- }
- }
-
- /// <summary>
- /// Gets the association store.
- /// </summary>
- internal IAssociationStore<Uri> AssociationStore { get; private set; }
-
- /// <summary>
- /// Gets the web request handler to use for discovery and the part of
- /// authentication where direct messages are sent to an untrusted remote party.
- /// </summary>
- internal IDirectSslWebRequestHandler WebRequestHandler { get; private set; }
-
- /// <summary>
- /// Gets an association between this Relying Party and a given Provider.
- /// A new association is created if necessary and possible.
- /// </summary>
- /// <param name="provider">The provider to create an association with.</param>
- /// <returns>The association if one exists and/or could be created. Null otherwise.</returns>
- internal Association GetAssociation(ProviderEndpointDescription provider) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
-
- var associateRequest = AssociateRequest.Create(this.SecuritySettings, provider);
- if (associateRequest == null) {
- return null;
- }
-
- var associateResponse = this.Channel.Request(associateRequest);
- var associateSuccessfulResponse = associateResponse as AssociateSuccessfulResponse;
- var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse;
- if (associateSuccessfulResponse != null) {
- Association association = associateSuccessfulResponse.CreateAssociation(associateRequest);
- this.AssociationStore.StoreAssociation(provider.Endpoint, association);
- return association;
- } else if (associateUnsuccessfulResponse != null) {
- // TODO: code here
- throw new NotImplementedException();
- } else {
- throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany);
- }
- }
- }
-}
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdRelyingParty.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using DotNetOpenAuth.Configuration;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OpenId.ChannelElements;
+ using DotNetOpenAuth.OpenId.Messages;
+
+ /// <summary>
+ /// Provides the programmatic facilities to act as an OpenId consumer.
+ /// </summary>
+ public sealed class OpenIdRelyingParty {
+ /// <summary>
+ /// The untrusted web request handler we use (and share) by default across all RP instances.
+ /// </summary>
+ private static IDirectSslWebRequestHandler defaultUntrustedWebRequestHandler = new UntrustedWebRequestHandler();
+
+ /// <summary>
+ /// Backing field for the <see cref="SecuritySettings"/> property.
+ /// </summary>
+ private RelyingPartySecuritySettings securitySettings;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class.
+ /// </summary>
+ /// <param name="associationStore">The association store. If null, the relying party will always operate in "dumb mode".</param>
+ /// <param name="nonceStore">The nonce store to use. If null, the relying party will always operate in "dumb mode".</param>
+ /// <param name="secretStore">The secret store to use. If null, the relying party will always operate in "dumb mode".</param>
+ public OpenIdRelyingParty(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore) {
+ // TODO: fix this so that a null association store is supported as 'dumb mode only'.
+ ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore");
+ ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
+ ErrorUtilities.VerifyArgumentNotNull(secretStore, "secretStore");
+ ErrorUtilities.VerifyArgument((associationStore == null) == (nonceStore == null), OpenIdStrings.AssociationAndNonceStoresMustBeBothNullOrBothNonNull);
+
+ this.Channel = new OpenIdChannel(associationStore, nonceStore, secretStore);
+ this.AssociationStore = associationStore;
+ this.SecuritySettings = RelyingPartySection.Configuration.SecuritySettings.CreateSecuritySettings();
+ this.WebRequestHandler = defaultUntrustedWebRequestHandler;
+ }
+
+ /// <summary>
+ /// Gets the channel to use for sending/receiving messages.
+ /// </summary>
+ public Channel Channel { get; internal set; }
+
+ /// <summary>
+ /// Gets the security settings used by this Relying Party.
+ /// </summary>
+ public RelyingPartySecuritySettings SecuritySettings {
+ get {
+ return this.securitySettings;
+ }
+
+ internal set {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+
+ this.securitySettings = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the association store.
+ /// </summary>
+ internal IAssociationStore<Uri> AssociationStore { get; private set; }
+
+ /// <summary>
+ /// Gets the web request handler to use for discovery and the part of
+ /// authentication where direct messages are sent to an untrusted remote party.
+ /// </summary>
+ internal IDirectSslWebRequestHandler WebRequestHandler { get; private set; }
+
+ /// <summary>
+ /// Gets an association between this Relying Party and a given Provider.
+ /// A new association is created if necessary and possible.
+ /// </summary>
+ /// <param name="provider">The provider to create an association with.</param>
+ /// <returns>The association if one exists and/or could be created. Null otherwise.</returns>
+ internal Association GetAssociation(ProviderEndpointDescription provider) {
+ ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+
+ var associateRequest = AssociateRequest.Create(this.SecuritySettings, provider);
+ if (associateRequest == null) {
+ return null;
+ }
+
+ var associateResponse = this.Channel.Request(associateRequest);
+ var associateSuccessfulResponse = associateResponse as AssociateSuccessfulResponse;
+ var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse;
+ if (associateSuccessfulResponse != null) {
+ Association association = associateSuccessfulResponse.CreateAssociation(associateRequest);
+ this.AssociationStore.StoreAssociation(provider.Endpoint, association);
+ return association;
+ } else if (associateUnsuccessfulResponse != null) {
+ // TODO: code here
+ throw new NotImplementedException();
+ } else {
+ throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany);
+ }
+ }
+ }
+}