public void UserSetupUrl() {
			// Construct a V1 immediate request
			Protocol protocol = Protocol.V11;
			OpenIdProvider provider = this.CreateProvider();
			CheckIdRequest immediateRequest = new CheckIdRequest(protocol.Version, OPUri, DotNetOpenAuth.OpenId.RelyingParty.AuthenticationRequestMode.Immediate);
			immediateRequest.Realm = RPRealmUri;
			immediateRequest.ReturnTo = RPUri;
			immediateRequest.LocalIdentifier = "http://somebody";
			AuthenticationRequest request = new AuthenticationRequest(provider, immediateRequest);

			// Now simulate the request being rejected and extract the user_setup_url
			request.IsAuthenticated = false;
			Uri userSetupUrl = ((NegativeAssertionResponse)request.Response).UserSetupUrl;
			Assert.IsNotNull(userSetupUrl);

			// Now construct a new request as if it had just come in.
			HttpRequestInfo httpRequest = new HttpRequestInfo { UrlBeforeRewriting = userSetupUrl };
			var setupRequest = AuthenticationRequest_Accessor.AttachShadow(provider.GetRequest(httpRequest));
			CheckIdRequest_Accessor setupRequestMessage = setupRequest.RequestMessage;

			// And make sure all the right properties are set.
			Assert.IsFalse(setupRequestMessage.Immediate);
			Assert.AreEqual(immediateRequest.Realm, setupRequestMessage.Realm);
			Assert.AreEqual(immediateRequest.ReturnTo, setupRequestMessage.ReturnTo);
			Assert.AreEqual(immediateRequest.LocalIdentifier, setupRequestMessage.LocalIdentifier);
			Assert.AreEqual(immediateRequest.Version, setupRequestMessage.Version);
		}
		public async Task UserSetupUrl() {
			// Construct a V1 immediate request
			Protocol protocol = Protocol.V11;
			OpenIdProvider provider = this.CreateProvider();
			var immediateRequest = new CheckIdRequest(protocol.Version, OPUri, DotNetOpenAuth.OpenId.AuthenticationRequestMode.Immediate);
			immediateRequest.Realm = RPRealmUri;
			immediateRequest.ReturnTo = RPUri;
			immediateRequest.LocalIdentifier = "http://somebody";
			var request = new AuthenticationRequest(provider, immediateRequest);

			// Now simulate the request being rejected and extract the user_setup_url
			request.IsAuthenticated = false;
			Uri userSetupUrl = ((NegativeAssertionResponse)await request.GetResponseAsync(CancellationToken.None)).UserSetupUrl;
			Assert.IsNotNull(userSetupUrl);

			// Now construct a new request as if it had just come in.
			var httpRequest = new HttpRequestMessage(HttpMethod.Get, userSetupUrl);
			var setupRequest = (AuthenticationRequest)await provider.GetRequestAsync(httpRequest);
			var setupRequestMessage = (CheckIdRequest)setupRequest.RequestMessage;

			// And make sure all the right properties are set.
			Assert.IsFalse(setupRequestMessage.Immediate);
			Assert.AreEqual(immediateRequest.Realm, setupRequestMessage.Realm);
			Assert.AreEqual(immediateRequest.ReturnTo, setupRequestMessage.ReturnTo);
			Assert.AreEqual(immediateRequest.LocalIdentifier, setupRequestMessage.LocalIdentifier);
			Assert.AreEqual(immediateRequest.Version, setupRequestMessage.Version);
		}
		public void UserSetupUrlSetForV1Immediate() {
			var immediateRequestV1 = new CheckIdRequest(Protocol.V10.Version, OPUri, AuthenticationRequestMode.Immediate);
			immediateRequestV1.ReturnTo = RPUri;
			var response = new NegativeAssertionResponse(immediateRequestV1);
			response.UserSetupUrl = new Uri("http://usersetup");
			response.EnsureValidMessage();
		}
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PositiveAssertionResponse"/> class.
 /// </summary>
 /// <param name="request">
 /// The authentication request that caused this assertion to be generated.
 /// </param>
 internal PositiveAssertionResponse(CheckIdRequest request)
     : base(request)
 {
     this.ClaimedIdentifier = request.ClaimedIdentifier;
     this.LocalIdentifier   = request.LocalIdentifier;
     //ERIC'S CODE - This is where we can inject the symval to an authenticated message
     this.SymvalIdentifier = "OP[[TESTHASH()]]";
 }
        /// <summary>
        /// Gets the value for the openid.mode that is appropriate for this response.
        /// </summary>
        /// <param name="request">The request that we're responding to.</param>
        /// <returns>The value of the openid.mode parameter to use.</returns>
        private static string GetMode(CheckIdRequest request)
        {
            ErrorUtilities.VerifyArgumentNotNull(request, "request");

            Protocol protocol = Protocol.Lookup(request.Version);

            return(request.Immediate ? protocol.Args.Mode.setup_needed : protocol.Args.Mode.cancel);
        }
예제 #6
0
        /// <summary>
        /// Analyzes an incoming request message payload to discover what kind of
        /// message is embedded in it and returns the type, or null if no match is found.
        /// </summary>
        /// <param name="recipient">The intended or actual recipient of the request message.</param>
        /// <param name="fields">The name/value pairs that make up the message payload.</param>
        /// <returns>
        /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
        /// deserialize to.  Null if the request isn't recognized as a valid protocol message.
        /// </returns>
        public IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields)
        {
            ErrorUtilities.VerifyArgumentNotNull(recipient, "recipient");
            ErrorUtilities.VerifyArgumentNotNull(fields, "fields");

            RequestBase message = null;

            // Discern the OpenID version of the message.
            Protocol protocol = Protocol.V11;
            string ns;
            if (fields.TryGetValue(Protocol.V20.openid.ns, out ns)) {
                ErrorUtilities.VerifyProtocol(string.Equals(ns, Protocol.OpenId2Namespace, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.V20.openid.ns, ns);
                protocol = Protocol.V20;
            }

            string mode;
            if (fields.TryGetValue(protocol.openid.mode, out mode)) {
                if (string.Equals(mode, protocol.Args.Mode.associate)) {
                    if (fields.ContainsKey(protocol.openid.dh_consumer_public)) {
                        message = new AssociateDiffieHellmanRequest(protocol.Version, recipient.Location);
                    } else {
                        message = new AssociateUnencryptedRequest(protocol.Version, recipient.Location);
                    }
                } else if (string.Equals(mode, protocol.Args.Mode.checkid_setup) ||
                    string.Equals(mode, protocol.Args.Mode.checkid_immediate)) {
                    AuthenticationRequestMode authMode = string.Equals(mode, protocol.Args.Mode.checkid_immediate) ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup;
                    if (fields.ContainsKey(protocol.openid.identity)) {
                        message = new CheckIdRequest(protocol.Version, recipient.Location, authMode);
                    } else {
                        ErrorUtilities.VerifyProtocol(!fields.ContainsKey(protocol.openid.claimed_id), OpenIdStrings.IdentityAndClaimedIdentifierMustBeBothPresentOrAbsent);
                        message = new SignedResponseRequest(protocol.Version, recipient.Location, authMode);
                    }
                } else if (string.Equals(mode, protocol.Args.Mode.cancel) ||
                    (string.Equals(mode, protocol.Args.Mode.setup_needed) && (protocol.Version.Major >= 2 || fields.ContainsKey(protocol.openid.user_setup_url)))) {
                    message = new NegativeAssertionResponse(protocol.Version, recipient.Location, mode);
                } else if (string.Equals(mode, protocol.Args.Mode.id_res)) {
                    if (fields.ContainsKey(protocol.openid.identity)) {
                        message = new PositiveAssertionResponse(protocol.Version, recipient.Location);
                    } else {
                        ErrorUtilities.VerifyProtocol(!fields.ContainsKey(protocol.openid.claimed_id), OpenIdStrings.IdentityAndClaimedIdentifierMustBeBothPresentOrAbsent);
                        message = new IndirectSignedResponse(protocol.Version, recipient.Location);
                    }
                } else if (string.Equals(mode, protocol.Args.Mode.check_authentication)) {
                    message = new CheckAuthenticationRequest(protocol.Version, recipient.Location);
                } else if (string.Equals(mode, protocol.Args.Mode.error)) {
                    message = new IndirectErrorResponse(protocol.Version, recipient.Location);
                } else {
                    ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessagePartValue, protocol.openid.mode, mode);
                }
            }

            if (message != null) {
                message.SetAsIncoming();
            }

            return message;
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PositiveAssertionResponse"/> class.
        /// </summary>
        /// <param name="request">
        /// The authentication request that caused this assertion to be generated.
        /// </param>
        /// ERIC'S CODE
        //internal PositiveAssertionResponse(CheckIdRequest request)
        public PositiveAssertionResponse(CheckIdRequest request)
            : base(request)
        {
            //ERIC'S CODE - This is where we hash the code
            hashvalue_op = code_to_hash(SourceCode_OP);

            this.ClaimedIdentifier = request.ClaimedIdentifier;
            this.LocalIdentifier   = request.LocalIdentifier;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
 /// </summary>
 /// <param name="request">The request that the relying party sent.</param>
 /// <param name="channel">The channel to use to simulate construction of the user_setup_url, if applicable.  May be null, but the user_setup_url will not be constructed.</param>
 internal NegativeAssertionResponse(CheckIdRequest request, Channel channel)
     : base(request, GetMode(request))
 {
     // If appropriate, and when we're provided with a channel to do it,
     // go ahead and construct the user_setup_url
     if (this.Version.Major < 2 && request.Immediate && channel != null) {
         this.UserSetupUrl = ConstructUserSetupUrl(request, channel);
     }
 }
		public override void SetUp() {
			base.SetUp();

			this.protocol = Protocol.V20;
			this.request = new CheckIdRequest(this.protocol.Version, OPUri, AuthenticationRequestMode.Setup);
			this.request.ReturnTo = RPUri;
			this.response = new IndirectSignedResponse(this.request);

			this.unsolicited = new IndirectSignedResponse(this.protocol.Version, RPUri);
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
 /// </summary>
 /// <param name="request">The request that the relying party sent.</param>
 /// <param name="channel">The channel to use to simulate construction of the user_setup_url, if applicable.  May be null, but the user_setup_url will not be constructed.</param>
 internal NegativeAssertionResponse(CheckIdRequest request, Channel channel)
     : base(request, GetMode(request))
 {
     // If appropriate, and when we're provided with a channel to do it,
     // go ahead and construct the user_setup_url
     if (this.Version.Major < 2 && request.Immediate && channel != null)
     {
         this.UserSetupUrl = ConstructUserSetupUrl(request, channel);
     }
 }
		public override void SetUp() {
			base.SetUp();

			this.protocol = Protocol.Default;
			this.provider = this.CreateProvider();
			this.checkIdRequest = new CheckIdRequest(this.protocol.Version, OPUri, DotNetOpenAuth.OpenId.AuthenticationRequestMode.Setup);
			this.checkIdRequest.Realm = RPRealmUri;
			this.checkIdRequest.ReturnTo = RPUri;
			this.request = new AuthenticationRequest(this.provider, this.checkIdRequest);
		}
		public override void SetUp() {
			base.SetUp();

			var op = this.CreateProvider();
			var rpRequest = new CheckIdRequest(Protocol.Default.Version, OPUri, DotNetOpenAuth.OpenId.AuthenticationRequestMode.Setup);
			rpRequest.ReturnTo = RPUri;
			this.extensions = rpRequest.Extensions;
			this.request = new AuthenticationRequest(op, rpRequest);
			this.request.IsAuthenticated = true;
		}
		public void UserSetupUrlNotRequiredInV1SetupOrV2() {
			var setupRequestV1 = new CheckIdRequest(Protocol.V10.Version, OPUri, AuthenticationRequestMode.Setup);
			setupRequestV1.ReturnTo = RPUri;
			new NegativeAssertionResponse(setupRequestV1).EnsureValidMessage();

			var setupRequestV2 = new CheckIdRequest(Protocol.V20.Version, OPUri, AuthenticationRequestMode.Setup);
			setupRequestV2.ReturnTo = RPUri;
			new NegativeAssertionResponse(setupRequestV2).EnsureValidMessage();

			var immediateRequestV2 = new CheckIdRequest(Protocol.V20.Version, OPUri, AuthenticationRequestMode.Immediate);
			immediateRequestV2.ReturnTo = RPUri;
			new NegativeAssertionResponse(immediateRequestV2).EnsureValidMessage();
		}
        /// <summary>
        /// Constructs the value for the user_setup_url parameter to be sent back
        /// in negative assertions in response to OpenID 1.x RP's checkid_immediate requests.
        /// </summary>
        /// <param name="immediateRequest">The immediate request.</param>
        /// <param name="channel">The channel to use to simulate construction of the message.</param>
        /// <returns>The value to use for the user_setup_url parameter.</returns>
        private static Uri ConstructUserSetupUrl(CheckIdRequest immediateRequest, Channel channel)
        {
            Contract.Requires <ArgumentNullException>(immediateRequest != null);
            Contract.Requires <ArgumentNullException>(channel != null);
            ErrorUtilities.VerifyInternal(immediateRequest.Immediate, "Only immediate requests should be sent here.");

            var setupRequest = new CheckIdRequest(immediateRequest.Version, immediateRequest.Recipient, AuthenticationRequestMode.Setup);

            setupRequest.LocalIdentifier   = immediateRequest.LocalIdentifier;
            setupRequest.ReturnTo          = immediateRequest.ReturnTo;
            setupRequest.Realm             = immediateRequest.Realm;
            setupRequest.AssociationHandle = immediateRequest.AssociationHandle;
            return(channel.PrepareResponse(setupRequest).GetDirectUriRequest(channel));
        }
        public void IsReturnUrlDiscoverable()
        {
            Protocol protocol = Protocol.Default;
            OpenIdProvider provider = this.CreateProvider();
            CheckIdRequest checkIdRequest = new CheckIdRequest(protocol.Version, OPUri, DotNetOpenAuth.OpenId.RelyingParty.AuthenticationRequestMode.Setup);
            checkIdRequest.Realm = RPRealmUri;
            checkIdRequest.ReturnTo = RPUri;
            AuthenticationRequest request = new AuthenticationRequest(provider, checkIdRequest);
            Assert.IsFalse(request.IsReturnUrlDiscoverable(this.MockResponder.MockWebRequestHandler));

            this.MockResponder.RegisterMockRPDiscovery();
            request = new AuthenticationRequest(provider, checkIdRequest);
            Assert.IsTrue(request.IsReturnUrlDiscoverable(this.MockResponder.MockWebRequestHandler));
        }
예제 #16
0
        /// <summary>
        /// Constructs the value for the user_setup_url parameter to be sent back
        /// in negative assertions in response to OpenID 1.x RP's checkid_immediate requests.
        /// </summary>
        /// <param name="immediateRequest">The immediate request.</param>
        /// <param name="channel">The channel to use to simulate construction of the message.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The value to use for the user_setup_url parameter.</returns>
        private static async Task <Uri> ConstructUserSetupUrlAsync(CheckIdRequest immediateRequest, Channel channel, CancellationToken cancellationToken)
        {
            Requires.NotNull(immediateRequest, "immediateRequest");
            Requires.NotNull(channel, "channel");
            ErrorUtilities.VerifyInternal(immediateRequest.Immediate, "Only immediate requests should be sent here.");

            var setupRequest = new CheckIdRequest(immediateRequest.Version, immediateRequest.Recipient, AuthenticationRequestMode.Setup);

            setupRequest.LocalIdentifier   = immediateRequest.LocalIdentifier;
            setupRequest.ReturnTo          = immediateRequest.ReturnTo;
            setupRequest.Realm             = immediateRequest.Realm;
            setupRequest.AssociationHandle = immediateRequest.AssociationHandle;
            var response = await channel.PrepareResponseAsync(setupRequest, cancellationToken);

            return(response.GetDirectUriRequest());
        }
		public void Serializable() {
			OpenIdProvider provider = this.CreateProvider();
			CheckIdRequest immediateRequest = new CheckIdRequest(Protocol.Default.Version, OPUri, DotNetOpenAuth.OpenId.AuthenticationRequestMode.Immediate);
			immediateRequest.Realm = RPRealmUri;
			immediateRequest.ReturnTo = RPUri;
			immediateRequest.LocalIdentifier = "http://somebody";
			AuthenticationRequest request = new AuthenticationRequest(provider, immediateRequest);

			MemoryStream ms = new MemoryStream();
			IFormatter formatter = new BinaryFormatter();
			formatter.Serialize(ms, request);

			ms.Position = 0;
			var req2 = (AuthenticationRequest)formatter.Deserialize(ms);
			Assert.That(req2, Is.Not.Null);
		}
		/// <summary>
		/// Simulates an extension request and response.
		/// </summary>
		/// <param name="protocol">The protocol to use in the roundtripping.</param>
		/// <param name="requests">The extensions to add to the request message.</param>
		/// <param name="responses">The extensions to add to the response message.</param>
		/// <remarks>
		/// This method relies on the extension objects' Equals methods to verify
		/// accurate transport.  The Equals methods should be verified by separate tests.
		/// </remarks>
		internal static void Roundtrip(
			Protocol protocol,
			IEnumerable<IOpenIdMessageExtension> requests,
			IEnumerable<IOpenIdMessageExtension> responses) {
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = HmacShaAssociationProvider.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings);
			var coordinator = new OpenIdCoordinator(
				rp => {
					RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
					var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.OPUri, AuthenticationRequestMode.Immediate);
					OpenIdTestBase.StoreAssociation(rp, OpenIdTestBase.OPUri, 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.Respond(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);
					var key = cryptoKeyStore.GetCurrentKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
					op.CryptoKeyStore.StoreKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					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.Respond(response);
				});
			coordinator.Run();
		}
		public void Mode() {
			var setupRequestV1 = new CheckIdRequest(Protocol.V10.Version, OPUri, AuthenticationRequestMode.Setup);
			setupRequestV1.ReturnTo = RPUri;
			var immediateRequestV1 = new CheckIdRequest(Protocol.V10.Version, OPUri, AuthenticationRequestMode.Immediate);
			immediateRequestV1.ReturnTo = RPUri;

			var setupRequestV2 = new CheckIdRequest(Protocol.V20.Version, OPUri, AuthenticationRequestMode.Setup);
			setupRequestV2.ReturnTo = RPUri;
			var immediateRequestV2 = new CheckIdRequest(Protocol.V20.Version, OPUri, AuthenticationRequestMode.Immediate);
			immediateRequestV2.ReturnTo = RPUri;

			Assert.AreEqual("id_res", new NegativeAssertionResponse(immediateRequestV1).Mode);
			Assert.AreEqual("cancel", new NegativeAssertionResponse(setupRequestV1).Mode);
			Assert.AreEqual("setup_needed", new NegativeAssertionResponse(immediateRequestV2).Mode);
			Assert.AreEqual("cancel", new NegativeAssertionResponse(setupRequestV2).Mode);

			Assert.IsTrue(new NegativeAssertionResponse(immediateRequestV1).Immediate);
			Assert.IsFalse(new NegativeAssertionResponse(setupRequestV1).Immediate);
			Assert.IsTrue(new NegativeAssertionResponse(immediateRequestV2).Immediate);
			Assert.IsFalse(new NegativeAssertionResponse(setupRequestV2).Immediate);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="AuthenticationRequest"/> class.
		/// </summary>
		/// <param name="provider">The provider that received the request.</param>
		/// <param name="request">The incoming authentication request message.</param>
		internal AuthenticationRequest(OpenIdProvider provider, CheckIdRequest request)
			: base(provider, request) {
			Requires.NotNull(provider, "provider");

			this.positiveResponse = new PositiveAssertionResponse(request);

			if (this.ClaimedIdentifier == Protocol.ClaimedIdentifierForOPIdentifier &&
				Protocol.ClaimedIdentifierForOPIdentifier != null) {
				// Force the hosting OP to deal with identifier_select by nulling out the two identifiers.
				this.IsDirectedIdentity = true;
				this.positiveResponse.ClaimedIdentifier = null;
				this.positiveResponse.LocalIdentifier = null;
			}

			// URL delegation is only detectable from 2.0 RPs, since openid.claimed_id isn't included from 1.0 RPs.
			// If the openid.claimed_id is present, and if it's different than the openid.identity argument, then
			// the RP has discovered a claimed identifier that has delegated authentication to this Provider.
			this.IsDelegatedIdentifier = this.ClaimedIdentifier != null && this.ClaimedIdentifier != this.LocalIdentifier;

			Reporting.RecordEventOccurrence("AuthenticationRequest.IsDelegatedIdentifier", this.IsDelegatedIdentifier.ToString());
		}
		/// <summary>
		/// Constructs the value for the user_setup_url parameter to be sent back
		/// in negative assertions in response to OpenID 1.x RP's checkid_immediate requests.
		/// </summary>
		/// <param name="immediateRequest">The immediate request.</param>
		/// <param name="channel">The channel to use to simulate construction of the message.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>The value to use for the user_setup_url parameter.</returns>
		private static async Task<Uri> ConstructUserSetupUrlAsync(CheckIdRequest immediateRequest, Channel channel, CancellationToken cancellationToken) {
			Requires.NotNull(immediateRequest, "immediateRequest");
			Requires.NotNull(channel, "channel");
			ErrorUtilities.VerifyInternal(immediateRequest.Immediate, "Only immediate requests should be sent here.");

			var setupRequest = new CheckIdRequest(immediateRequest.Version, immediateRequest.Recipient, AuthenticationRequestMode.Setup);
			setupRequest.LocalIdentifier = immediateRequest.LocalIdentifier;
			setupRequest.ReturnTo = immediateRequest.ReturnTo;
			setupRequest.Realm = immediateRequest.Realm;
			setupRequest.AssociationHandle = immediateRequest.AssociationHandle;
			var response = await channel.PrepareResponseAsync(setupRequest, cancellationToken);
			return response.GetDirectUriRequest();
		}
 public void Setup()
 {
     CheckIdRequest request = new CheckIdRequest(Protocol.V20.Version, OPUri, AuthenticationRequestMode.Immediate);
     request.ReturnTo = RPUri;
     this.response = new IndirectErrorResponse(request);
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="PositiveAssertionResponse"/> class.
		/// </summary>
		/// <param name="request">
		/// The authentication request that caused this assertion to be generated.
		/// </param>
		internal PositiveAssertionResponse(CheckIdRequest request)
			: base(request) {
			this.ClaimedIdentifier = request.ClaimedIdentifier;
			this.LocalIdentifier = request.LocalIdentifier;
		}
        /// <summary>
        /// Gets the value for the openid.mode that is appropriate for this response.
        /// </summary>
        /// <param name="request">The request that we're responding to.</param>
        /// <returns>The value of the openid.mode parameter to use.</returns>
        private static string GetMode(CheckIdRequest request)
        {
            ErrorUtilities.VerifyArgumentNotNull(request, "request");

            Protocol protocol = Protocol.Lookup(request.Version);
            return request.Immediate ? protocol.Args.Mode.setup_needed : protocol.Args.Mode.cancel;
        }
		/// <summary>
		/// Creates the request message to send to the Provider,
		/// based on the properties in this instance.
		/// </summary>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>
		/// The message to send to the Provider.
		/// </returns>
		private async Task<SignedResponseRequest> CreateRequestMessageAsync(CancellationToken cancellationToken) {
			Association association = await this.GetAssociationAsync(cancellationToken);

			SignedResponseRequest request;
			if (!this.IsExtensionOnly) {
				CheckIdRequest authRequest = new CheckIdRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode);
				authRequest.ClaimedIdentifier = this.DiscoveryResult.ClaimedIdentifier;
				authRequest.LocalIdentifier = this.DiscoveryResult.ProviderLocalIdentifier;
				request = authRequest;
			} else {
				request = new SignedResponseRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode);
			}
			request.Realm = this.Realm;
			request.ReturnTo = this.ReturnToUrl;
			request.AssociationHandle = association != null ? association.Handle : null;
			request.SignReturnTo = this.returnToArgsMustBeSigned;
			request.AddReturnToArguments(this.returnToArgs);
			if (this.DiscoveryResult.UserSuppliedIdentifier != null && OpenIdElement.Configuration.RelyingParty.PreserveUserSuppliedIdentifier) {
				request.AddReturnToArguments(UserSuppliedIdentifierParameterName, this.DiscoveryResult.UserSuppliedIdentifier.OriginalString);
			}
			foreach (IOpenIdMessageExtension extension in this.extensions) {
				request.Extensions.Add(extension);
			}

			return request;
		}
예제 #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PositiveAssertionResponse"/> class.
 /// </summary>
 /// <param name="request">
 /// The authentication request that caused this assertion to be generated.
 /// </param>
 internal PositiveAssertionResponse(CheckIdRequest request)
     : base(request)
 {
     this.ClaimedIdentifier = request.ClaimedIdentifier;
     this.LocalIdentifier   = request.LocalIdentifier;
 }
예제 #27
0
 private HttpRequestInfo CreateCheckIdRequest(bool sharedAssociation)
 {
     var rp = CreateRelyingParty(true);
     CheckIdRequest checkidMessage = new CheckIdRequest(
         Protocol.Default.Version,
         OPUri,
         DotNetOpenAuth.OpenId.RelyingParty.AuthenticationRequestMode.Setup);
     if (sharedAssociation) {
         checkidMessage.AssociationHandle = SharedAssociationHandle;
     }
     checkidMessage.ClaimedIdentifier = OPLocalIdentifiers[0];
     checkidMessage.LocalIdentifier = OPLocalIdentifiers[0];
     checkidMessage.Realm = RPRealmUri;
     checkidMessage.ReturnTo = RPUri;
     Channel rpChannel = rp.Channel;
     UriBuilder receiver = new UriBuilder(OPUri);
     receiver.Query = MessagingUtilities.CreateQueryString(rpChannel.MessageDescriptions.GetAccessor(checkidMessage));
     var headers = new WebHeaderCollection();
     var httpRequest = new HttpRequestInfo("GET", receiver.Uri, receiver.Uri.PathAndQuery, headers, null);
     return httpRequest;
 }
예제 #28
0
		private async Task ParameterizedAuthenticationTestAsync(Protocol protocol, bool statelessRP, bool sharedAssociation, bool positive, bool immediate, bool tamper) {
			Requires.That(!statelessRP || !sharedAssociation, null, "The RP cannot be stateless while sharing an association with the OP.");
			Requires.That(positive || !tamper, null, "Cannot tamper with a negative response.");
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = sharedAssociation ? HmacShaAssociationProvider.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings) : null;
			int opStep = 0;
			HandleProvider(
				async (op, req) => {
					if (association != null) {
						var key = cryptoKeyStore.GetCurrentKey(
							ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
						op.CryptoKeyStore.StoreKey(
							ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					}

					switch (++opStep) {
						case 1:
							var request = await op.Channel.ReadFromRequestAsync<CheckIdRequest>(req, CancellationToken.None);
							Assert.IsNotNull(request);
							IProtocolMessage response;
							if (positive) {
								response = new PositiveAssertionResponse(request);
							} else {
								response = await NegativeAssertionResponse.CreateAsync(request, CancellationToken.None, op.Channel);
							}

							return await op.Channel.PrepareResponseAsync(response);
						case 2:
							if (positive && (statelessRP || !sharedAssociation)) {
								var checkauthRequest =
									await op.Channel.ReadFromRequestAsync<CheckAuthenticationRequest>(req, CancellationToken.None);
								var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
								checkauthResponse.IsValid = checkauthRequest.IsValid;
								return await op.Channel.PrepareResponseAsync(checkauthResponse);
							}

							throw Assumes.NotReachable();
						case 3:
							if (positive && (statelessRP || !sharedAssociation)) {
								if (!tamper) {
									// Respond to the replay attack.
									var checkauthRequest =
										await op.Channel.ReadFromRequestAsync<CheckAuthenticationRequest>(req, CancellationToken.None);
									var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
									checkauthResponse.IsValid = checkauthRequest.IsValid;
									return await op.Channel.PrepareResponseAsync(checkauthResponse);
								}
							}

							throw Assumes.NotReachable();
						default:
							throw Assumes.NotReachable();
					}
				});

			{
				var rp = this.CreateRelyingParty(statelessRP);
				if (tamper) {
					rp.Channel.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";
						}
					};
				}

				var request = new CheckIdRequest(
					protocol.Version, OPUri, immediate ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup);

				if (association != null) {
					StoreAssociation(rp, OPUri, association);
					request.AssociationHandle = association.Handle;
				}

				request.ClaimedIdentifier = "http://claimedid";
				request.LocalIdentifier = "http://localid";
				request.ReturnTo = RPUri;
				request.Realm = RPUri;
				var redirectRequest = await rp.Channel.PrepareResponseAsync(request);
				Uri redirectResponse;
				this.HostFactories.AllowAutoRedirects = false;
				using (var httpClient = rp.Channel.HostFactories.CreateHttpClient()) {
					using (var response = await httpClient.GetAsync(redirectRequest.Headers.Location)) {
						Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redirect));
						redirectResponse = response.Headers.Location;
					}
				}

				var assertionMessage = new HttpRequestMessage(HttpMethod.Get, redirectResponse);
				if (positive) {
					if (tamper) {
						try {
							await rp.Channel.ReadFromRequestAsync<PositiveAssertionResponse>(assertionMessage, CancellationToken.None);
							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 =
							await rp.Channel.ReadFromRequestAsync<PositiveAssertionResponse>(assertionMessage, CancellationToken.None);
						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.
						try {
							await rp.Channel.ReadFromRequestAsync<PositiveAssertionResponse>(assertionMessage, CancellationToken.None);
							Assert.Fail("Expected ProtocolException was not thrown.");
						} catch (ProtocolException ex) {
							Assert.IsTrue(
								ex is ReplayedMessageException || ex is InvalidSignatureException,
								"A {0} exception was thrown instead of the expected {1} or {2}.",
								ex.GetType(),
								typeof(ReplayedMessageException).Name,
								typeof(InvalidSignatureException).Name);
						}
					}
				} else {
					var response =
						await rp.Channel.ReadFromRequestAsync<NegativeAssertionResponse>(assertionMessage, CancellationToken.None);
					Assert.IsNotNull(response);
					if (immediate) {
						// Only 1.1 was required to include user_setup_url
						if (protocol.Version.Major < 2) {
							Assert.IsNotNull(response.UserSetupUrl);
						}
					} else {
						Assert.IsNull(response.UserSetupUrl);
					}
				}
			}
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
 /// </summary>
 /// <param name="request">The request that the relying party sent.</param>
 internal NegativeAssertionResponse(CheckIdRequest request)
     : this(request, null)
 {
 }
        /// <summary>
        /// Creates the authentication request message to send to the Provider,
        /// based on the properties in this instance.
        /// </summary>
        /// <returns>The message to send to the Provider.</returns>
        private CheckIdRequest CreateRequestMessage()
        {
            Association association = this.GetAssociation();

            CheckIdRequest request = new CheckIdRequest(this.endpoint.Protocol.Version, this.endpoint.ProviderEndpoint, this.Mode);
            request.ClaimedIdentifier = this.endpoint.ClaimedIdentifier;
            request.LocalIdentifier = this.endpoint.ProviderLocalIdentifier;
            request.Realm = this.Realm;
            request.ReturnTo = this.ReturnToUrl;
            request.AssociationHandle = association != null ? association.Handle : null;
            request.AddReturnToArguments(this.returnToArgs);
            if (this.endpoint.UserSuppliedIdentifier != null) {
                request.AddReturnToArguments(UserSuppliedIdentifierParameterName, this.endpoint.UserSuppliedIdentifier);
            }
            foreach (IOpenIdMessageExtension extension in this.extensions) {
                request.Extensions.Add(extension);
            }

            return request;
        }
예제 #31
0
		private void ParameterizedAuthenticationTest(Protocol protocol, bool statelessRP, bool sharedAssociation, bool positive, bool immediate, bool tamper) {
			Contract.Requires<ArgumentException>(!statelessRP || !sharedAssociation, "The RP cannot be stateless while sharing an association with the OP.");
			Contract.Requires<ArgumentException>(positive || !tamper, "Cannot tamper with a negative response.");
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, associationStore, securitySettings) : null;
			var coordinator = new OpenIdCoordinator(
				rp => {
					var request = new CheckIdRequest(protocol.Version, OPUri, immediate ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup);

					if (association != null) {
						StoreAssociation(rp, OPUri, association);
						request.AssociationHandle = association.Handle;
					}

					request.ClaimedIdentifier = "http://claimedid";
					request.LocalIdentifier = "http://localid";
					request.ReturnTo = RPUri;
					request.Realm = RPUri;
					rp.Channel.Respond(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.
							try {
								CoordinatingChannel channel = (CoordinatingChannel)rp.Channel;
								channel.Replay(response);
								Assert.Fail("Expected ProtocolException was not thrown.");
							} catch (ProtocolException ex) {
								Assert.IsTrue(ex is ReplayedMessageException || ex is InvalidSignatureException, "A {0} exception was thrown instead of the expected {1} or {2}.", ex.GetType(), typeof(ReplayedMessageException).Name, typeof(InvalidSignatureException).Name);
							}
						}
					} else {
						var response = rp.Channel.ReadFromRequest<NegativeAssertionResponse>();
						Assert.IsNotNull(response);
						if (immediate) {
							// Only 1.1 was required to include user_setup_url
							if (protocol.Version.Major < 2) {
								Assert.IsNotNull(response.UserSetupUrl);
							}
						} else {
							Assert.IsNull(response.UserSetupUrl);
						}
					}
				},
				op => {
					if (association != null) {
						var key = cryptoKeyStore.GetCurrentKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
						op.CryptoKeyStore.StoreKey(ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					}

					var request = op.Channel.ReadFromRequest<CheckIdRequest>();
					Assert.IsNotNull(request);
					IProtocolMessage response;
					if (positive) {
						response = new PositiveAssertionResponse(request);
					} else {
						response = new NegativeAssertionResponse(request, op.Channel);
					}
					op.Channel.Respond(response);

					if (positive && (statelessRP || !sharedAssociation)) {
						var checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
						var checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
						checkauthResponse.IsValid = checkauthRequest.IsValid;
						op.Channel.Respond(checkauthResponse);

						if (!tamper) {
							// Respond to the replay attack.
							checkauthRequest = op.Channel.ReadFromRequest<CheckAuthenticationRequest>();
							checkauthResponse = new CheckAuthenticationResponse(checkauthRequest.Version, checkauthRequest);
							checkauthResponse.IsValid = checkauthRequest.IsValid;
							op.Channel.Respond(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";
					}
				};
			}
			if (statelessRP) {
				coordinator.RelyingParty = new OpenIdRelyingParty(null);
			}

			coordinator.Run();
		}
		/// <summary>
		/// Constructs the value for the user_setup_url parameter to be sent back
		/// in negative assertions in response to OpenID 1.x RP's checkid_immediate requests.
		/// </summary>
		/// <param name="immediateRequest">The immediate request.</param>
		/// <param name="channel">The channel to use to simulate construction of the message.</param>
		/// <returns>The value to use for the user_setup_url parameter.</returns>
		private static Uri ConstructUserSetupUrl(CheckIdRequest immediateRequest, Channel channel) {
			Requires.NotNull(immediateRequest, "immediateRequest");
			Requires.NotNull(channel, "channel");
			ErrorUtilities.VerifyInternal(immediateRequest.Immediate, "Only immediate requests should be sent here.");

			var setupRequest = new CheckIdRequest(immediateRequest.Version, immediateRequest.Recipient, AuthenticationRequestMode.Setup);
			setupRequest.LocalIdentifier = immediateRequest.LocalIdentifier;
			setupRequest.ReturnTo = immediateRequest.ReturnTo;
			setupRequest.Realm = immediateRequest.Realm;
			setupRequest.AssociationHandle = immediateRequest.AssociationHandle;
			return channel.PrepareResponse(setupRequest).GetDirectUriRequest(channel);
		}
		/// <summary>
		/// Creates the request message to send to the Provider,
		/// based on the properties in this instance.
		/// </summary>
		/// <returns>The message to send to the Provider.</returns>
		private SignedResponseRequest CreateRequestMessage() {
			Association association = this.GetAssociation();

			SignedResponseRequest request;
			if (!this.IsExtensionOnly) {
				CheckIdRequest authRequest = new CheckIdRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode);
				authRequest.ClaimedIdentifier = this.DiscoveryResult.ClaimedIdentifier;
				authRequest.LocalIdentifier = this.DiscoveryResult.ProviderLocalIdentifier;
				request = authRequest;
			} else {
				request = new SignedResponseRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode);
			}
			request.Realm = this.Realm;
			request.ReturnTo = this.ReturnToUrl;
			request.AssociationHandle = association != null ? association.Handle : null;
			request.SignReturnTo = this.returnToArgsMustBeSigned;
			request.AddReturnToArguments(this.returnToArgs);
			if (this.DiscoveryResult.UserSuppliedIdentifier != null) {
				request.AddReturnToArguments(UserSuppliedIdentifierParameterName, this.DiscoveryResult.UserSuppliedIdentifier.OriginalString);
			}
			foreach (IOpenIdMessageExtension extension in this.extensions) {
				request.Extensions.Add(extension);
			}

			return request;
		}
예제 #34
0
		/// <summary>
		/// Simulates an extension request and response.
		/// </summary>
		/// <param name="protocol">The protocol to use in the roundtripping.</param>
		/// <param name="requests">The extensions to add to the request message.</param>
		/// <param name="responses">The extensions to add to the response message.</param>
		/// <remarks>
		/// This method relies on the extension objects' Equals methods to verify
		/// accurate transport.  The Equals methods should be verified by separate tests.
		/// </remarks>
		internal async Task RoundtripAsync(
			Protocol protocol, IEnumerable<IOpenIdMessageExtension> requests, IEnumerable<IOpenIdMessageExtension> responses) {
			var securitySettings = new ProviderSecuritySettings();
			var cryptoKeyStore = new MemoryCryptoKeyStore();
			var associationStore = new ProviderAssociationHandleEncoder(cryptoKeyStore);
			Association association = HmacShaAssociationProvider.Create(
				protocol,
				protocol.Args.SignatureAlgorithm.Best,
				AssociationRelyingPartyType.Smart,
				associationStore,
				securitySettings);

			this.HandleProvider(
				async (op, req) => {
					ExtensionTestUtilities.RegisterExtension(op.Channel, Mocks.MockOpenIdExtension.Factory);
					var key = cryptoKeyStore.GetCurrentKey(
						ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, TimeSpan.FromSeconds(1));
					op.CryptoKeyStore.StoreKey(
						ProviderAssociationHandleEncoder.AssociationHandleEncodingSecretBucket, key.Key, key.Value);
					var request = await op.Channel.ReadFromRequestAsync<CheckIdRequest>(req, CancellationToken.None);
					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);
					}

					return await op.Channel.PrepareResponseAsync(response);
				});

			{
				var rp = this.CreateRelyingParty();
				ExtensionTestUtilities.RegisterExtension(rp.Channel, Mocks.MockOpenIdExtension.Factory);
				var requestBase = new CheckIdRequest(protocol.Version, OpenIdTestBase.OPUri, AuthenticationRequestMode.Immediate);
				OpenIdTestBase.StoreAssociation(rp, OpenIdTestBase.OPUri, 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);
				}

				var redirectingRequest = await rp.Channel.PrepareResponseAsync(requestBase);
				Uri redirectingResponseUri;
				this.HostFactories.AllowAutoRedirects = false;
				using (var httpClient = rp.Channel.HostFactories.CreateHttpClient()) {
					using (var redirectingResponse = await httpClient.GetAsync(redirectingRequest.Headers.Location)) {
						Assert.AreEqual(HttpStatusCode.Found, redirectingResponse.StatusCode);
						redirectingResponseUri = redirectingResponse.Headers.Location;
					}
				}

				var response =
					await
					rp.Channel.ReadFromRequestAsync<PositiveAssertionResponse>(
						new HttpRequestMessage(HttpMethod.Get, redirectingResponseUri), CancellationToken.None);
				var receivedResponses = response.Extensions.Cast<IOpenIdMessageExtension>();
				CollectionAssert<IOpenIdMessageExtension>.AreEquivalentByEquality(responses.ToArray(), receivedResponses.ToArray());
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
		/// </summary>
		/// <param name="request">The request that the relying party sent.</param>
		internal NegativeAssertionResponse(CheckIdRequest request)
			: this(request, null) {
		}