/// <summary>
		/// Processes an incoming authorization-granted message from an SP and obtains an access token.
		/// </summary>
		/// <param name="openIdAuthenticationResponse">The OpenID authentication response that may be carrying an authorized request token.</param>
		/// <returns>
		/// The access token, or null if OAuth authorization was denied by the user or service provider.
		/// </returns>
		/// <remarks>
		/// The access token, if granted, is automatically stored in the <see cref="ConsumerBase.TokenManager"/>.
		/// The token manager instance must implement <see cref="IOpenIdOAuthTokenManager"/>.
		/// </remarks>
		public AuthorizedTokenResponse ProcessUserAuthorization(IAuthenticationResponse openIdAuthenticationResponse) {
			Requires.NotNull(openIdAuthenticationResponse, "openIdAuthenticationResponse");
			Requires.ValidState(this.TokenManager is IOpenIdOAuthTokenManager);
			var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager;
			ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName);

			// The OAuth extension is only expected in positive assertion responses.
			if (openIdAuthenticationResponse.Status != AuthenticationStatus.Authenticated) {
				return null;
			}

			// Retrieve the OAuth extension
			var positiveAuthorization = openIdAuthenticationResponse.GetExtension<AuthorizationApprovedResponse>();
			if (positiveAuthorization == null) {
				return null;
			}

			// Prepare a message to exchange the request token for an access token.
			// We are careful to use a v1.0 message version so that the oauth_verifier is not required.
			var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) {
				RequestToken = positiveAuthorization.RequestToken,
				ConsumerKey = this.ConsumerKey,
			};

			// Retrieve the access token and store it in the token manager.
			openidTokenManager.StoreOpenIdAuthorizedRequestToken(this.ConsumerKey, positiveAuthorization);
			var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, positiveAuthorization.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret);

			// Provide the caller with the access token so it may be associated with the user
			// that is logging in.
			return grantAccess;
		}
		/// <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>
		/// <remarks>
		/// The request messages are:
		/// UnauthorizedTokenRequest
		/// AuthorizedTokenRequest
		/// UserAuthorizationRequest
		/// AccessProtectedResourceRequest
		/// </remarks>
		public virtual IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
			MessageBase message = null;
			Protocol protocol = Protocol.V10; // default to assuming the less-secure 1.0 instead of 1.0a until we prove otherwise.
			string token;
			fields.TryGetValue("oauth_token", out token);

			try {
				if (fields.ContainsKey("oauth_consumer_key") && !fields.ContainsKey("oauth_token")) {
					protocol = fields.ContainsKey("oauth_callback") ? Protocol.V10a : Protocol.V10;
					message = new UnauthorizedTokenRequest(recipient, protocol.Version);
				} else if (fields.ContainsKey("oauth_consumer_key") && fields.ContainsKey("oauth_token")) {
					// Discern between RequestAccessToken and AccessProtectedResources,
					// which have all the same parameters, by figuring out what type of token
					// is in the token parameter.
					bool tokenTypeIsAccessToken = this.tokenManager.GetTokenType(token) == TokenType.AccessToken;

					if (tokenTypeIsAccessToken) {
						message = (MessageBase)new AccessProtectedResourceRequest(recipient, protocol.Version);
					} else {
						// Discern between 1.0 and 1.0a requests by checking on the consumer version we stored
						// when the consumer first requested an unauthorized token.
						protocol = Protocol.Lookup(this.tokenManager.GetRequestToken(token).ConsumerVersion);
						message = new AuthorizedTokenRequest(recipient, protocol.Version);
					}
				} else {
					// fail over to the message with no required fields at all.
					if (token != null) {
						protocol = Protocol.Lookup(this.tokenManager.GetRequestToken(token).ConsumerVersion);
					}

					// If a callback parameter is included, that suggests either the consumer
					// is following OAuth 1.0 instead of 1.0a, or that a hijacker is trying
					// to attack.  Either way, if the consumer started out as a 1.0a, keep it
					// that way, and we'll just ignore the oauth_callback included in this message
					// by virtue of the UserAuthorizationRequest message not including it in its
					// 1.0a payload.
					message = new UserAuthorizationRequest(recipient, protocol.Version);
				}

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

				return message;
			} catch (KeyNotFoundException ex) {
				throw ErrorUtilities.Wrap(ex, OAuthStrings.TokenNotFound);
			}
		}
Esempio n. 3
0
		public async Task VerifyAuthenticationFailsIfAccessTokenIsInvalid() {
			// Arrange
			var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
			var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));

			var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
			webWorker.Setup(w => w.ProcessUserAuthorizationAsync(It.IsAny<HttpContextBase>(), CancellationToken.None)).Returns(Task.FromResult<AccessTokenResponse>(null)).Verifiable();

			var client = new MockOAuthClient(webWorker.Object);
			var context = new Mock<HttpContextBase>();

			// Act
			AuthenticationResult result = await client.VerifyAuthenticationAsync(context.Object);

			// Assert
			webWorker.Verify();

			Assert.False(result.IsSuccessful);
		}
Esempio n. 4
0
		public void VerifyAuthenticationFailsIfAccessTokenIsInvalid() {
			// Arrange
			var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
			var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));
			var response = new AuthorizedTokenResponse(request) {
				AccessToken = "invalid token"
			};

			var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
			webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable();

			var client = new MockOAuthClient(webWorker.Object);
			var context = new Mock<HttpContextBase>();

			// Act
			AuthenticationResult result = client.VerifyAuthentication(context.Object);

			// Assert
			webWorker.Verify();

			Assert.False(result.IsSuccessful);
		}
Esempio n. 5
0
		/// <summary>
		/// Obtains an access token for a new account at the Service Provider via 2-legged OAuth.
		/// </summary>
		/// <param name="requestParameters">Any applicable parameters to include in the query string of the token request.</param>
		/// <returns>The access token.</returns>
		/// <remarks>
		/// The token secret is stored in the <see cref="TokenManager"/>.
		/// </remarks>
		public string RequestNewClientAccount(IDictionary<string, string> requestParameters = null) {
			// Obtain an unauthorized request token.  Assume the OAuth version given in the service description.
			var token = new UnauthorizedTokenRequest(this.ServiceProvider.RequestTokenEndpoint, this.ServiceProvider.Version) {
				ConsumerKey = this.ConsumerKey,
			};
			var tokenAccessor = this.Channel.MessageDescriptions.GetAccessor(token);
			tokenAccessor.AddExtraParameters(requestParameters);
			var requestTokenResponse = this.Channel.Request<UnauthorizedTokenResponse>(token);
			this.TokenManager.StoreNewRequestToken(token, requestTokenResponse);

			var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
				RequestToken = requestTokenResponse.RequestToken,
				ConsumerKey = this.ConsumerKey,
			};
			var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestTokenResponse.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
			return grantAccess.AccessToken;
		}
Esempio n. 6
0
		/// <summary>
		/// Exchanges a given request token for access token.
		/// </summary>
		/// <param name="requestToken">The request token that the user has authorized.</param>
		/// <param name="verifier">The verifier code.</param>
		/// <returns>
		/// The access token assigned by the Service Provider.
		/// </returns>
		protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken, string verifier) {
			Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(requestToken));
			Contract.Ensures(Contract.Result<AuthorizedTokenResponse>() != null);

			var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
				RequestToken = requestToken,
				VerificationCode = verifier,
				ConsumerKey = this.ConsumerKey,
			};
			var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
			return grantAccess;
		}
		/// <summary>
		/// Prepares and sends an access token to a Consumer, and invalidates the request token.
		/// </summary>
		/// <param name="request">The Consumer's message requesting an access token.</param>
		/// <returns>The HTTP response to actually send to the Consumer.</returns>
		public AuthorizedTokenResponse PrepareAccessTokenMessage(AuthorizedTokenRequest request) {
			Requires.NotNull(request, "request");

			ErrorUtilities.VerifyProtocol(this.TokenManager.IsRequestTokenAuthorized(request.RequestToken), OAuthStrings.AccessTokenNotAuthorized, request.RequestToken);

			string accessToken = this.TokenGenerator.GenerateAccessToken(request.ConsumerKey);
			string tokenSecret = this.TokenGenerator.GenerateSecret();
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(request.ConsumerKey, request.RequestToken, accessToken, tokenSecret);
			var grantAccess = new AuthorizedTokenResponse(request) {
				AccessToken = accessToken,
				TokenSecret = tokenSecret,
			};

			return grantAccess;
		}
Esempio n. 8
0
		public async Task VerifyAuthenticationSucceeds() {
			// Arrange
			var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
			var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));

			var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
			webWorker
				.Setup(w => w.ProcessUserAuthorizationAsync(It.IsAny<HttpContextBase>(), CancellationToken.None))
				.Returns(Task.FromResult(new AccessTokenResponse("ok", "secret", new NameValueCollection()))).Verifiable();

			var client = new MockOAuthClient(webWorker.Object);
			var context = new Mock<HttpContextBase>();

			// Act
			AuthenticationResult result = await client.VerifyAuthenticationAsync(context.Object);

			// Assert
			webWorker.Verify();

			Assert.True(result.IsSuccessful);
			Assert.AreEqual("mockoauth", result.Provider);
			Assert.AreEqual("12345", result.ProviderUserId);
			Assert.AreEqual("super", result.UserName);
			Assert.IsNotNull(result.ExtraData);
			Assert.AreEqual("ok", result.ExtraData["accesstoken"]);
		}
Esempio n. 9
0
 /// <summary>
 /// Exchanges a given request token for access token.
 /// </summary>
 /// <param name="requestToken">The request token that the user has authorized.</param>
 /// <returns>The access token assigned by the Service Provider.</returns>
 protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken)
 {
     var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint) {
         RequestToken = requestToken,
         ConsumerKey = this.ConsumerKey,
     };
     var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
     this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
     return grantAccess;
 }
Esempio n. 10
0
        /// <summary>
        /// Prepares and sends an access token to a Consumer, and invalidates the request token.
        /// </summary>
        /// <param name="request">The Consumer's message requesting an access token.</param>
        /// <returns>The HTTP response to actually send to the Consumer.</returns>
        public AuthorizedTokenResponse PrepareAccessTokenMessage(AuthorizedTokenRequest request)
        {
            if (request == null) {
                throw new ArgumentNullException("request");
            }

            if (!this.TokenManager.IsRequestTokenAuthorized(request.RequestToken)) {
                throw new ProtocolException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        OAuthStrings.AccessTokenNotAuthorized,
                        request.RequestToken));
            }

            string accessToken = this.TokenGenerator.GenerateAccessToken(request.ConsumerKey);
            string tokenSecret = this.TokenGenerator.GenerateSecret();
            this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(request.ConsumerKey, request.RequestToken, accessToken, tokenSecret);
            var grantAccess = new AuthorizedTokenResponse(request) {
                AccessToken = accessToken,
                TokenSecret = tokenSecret,
            };

            return grantAccess;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="AuthorizedTokenResponse"/> class.
 /// </summary>
 /// <param name="originatingRequest">The originating request.</param>
 protected internal AuthorizedTokenResponse(AuthorizedTokenRequest originatingRequest)
     : base(MessageProtections.None, originatingRequest)
 {
 }
Esempio n. 12
0
		/// <summary>
		/// Obtains an access token for a new account at the Service Provider via 2-legged OAuth.
		/// </summary>
		/// <param name="requestParameters">Any applicable parameters to include in the query string of the token request.</param>
		/// <returns>The access token.</returns>
		/// <remarks>
		/// The token secret is stored in the <see cref="TokenManager"/>.
		/// </remarks>
		public string RequestNewClientAccount(IDictionary<string, string> requestParameters = null) {
			// Obtain an unauthorized request token.  Force use of OAuth 1.0 (not 1.0a) so that 
			// we are not expected to provide an oauth_verifier which doesn't apply in 2-legged OAuth.
			var token = new UnauthorizedTokenRequest(this.ServiceProvider.RequestTokenEndpoint, Protocol.V10.Version) {
				ConsumerKey = this.ConsumerKey,
			};
			var tokenAccessor = this.Channel.MessageDescriptions.GetAccessor(token);
			tokenAccessor.AddExtraParameters(requestParameters);
			var requestTokenResponse = this.Channel.Request<UnauthorizedTokenResponse>(token);
			this.TokenManager.StoreNewRequestToken(token, requestTokenResponse);

			var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) {
				RequestToken = requestTokenResponse.RequestToken,
				ConsumerKey = this.ConsumerKey,
			};
			var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestTokenResponse.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
			return grantAccess.AccessToken;
		}
Esempio n. 13
0
		/// <summary>
		/// Exchanges a given request token for access token.
		/// </summary>
		/// <param name="requestToken">The request token that the user has authorized.</param>
		/// <param name="verifier">The verifier code.</param>
		/// <returns>
		/// The access token assigned by the Service Provider.
		/// </returns>
		protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken, string verifier) {
			Requires.NotNullOrEmpty(requestToken, "requestToken");

			var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
				RequestToken = requestToken,
				VerificationCode = verifier,
				ConsumerKey = this.ConsumerKey,
			};
			var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess);
			this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
			return grantAccess;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="AuthorizedTokenResponse"/> class.
 /// </summary>
 /// <param name="originatingRequest">The originating request.</param>
 protected internal AuthorizedTokenResponse(AuthorizedTokenRequest originatingRequest)
     : base(MessageProtections.None, originatingRequest, originatingRequest.Version)
 {
 }
Esempio n. 15
0
		public void VerifyAuthenticationSucceeds() {
			// Arrange
			var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
			var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));
			var response = new AuthorizedTokenResponse(request) {
				AccessToken = "ok"
			};

			var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
			webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable();

			var client = new MockOAuthClient(webWorker.Object);
			var context = new Mock<HttpContextBase>();

			// Act
			AuthenticationResult result = client.VerifyAuthentication(context.Object);

			// Assert
			webWorker.Verify();

			Assert.True(result.IsSuccessful);
			Assert.AreEqual("mockoauth", result.Provider);
			Assert.AreEqual("12345", result.ProviderUserId);
			Assert.AreEqual("super", result.UserName);
			Assert.IsNotNull(result.ExtraData);
			Assert.IsTrue(result.ExtraData.ContainsKey("accesstoken"));
			Assert.AreEqual("ok", result.ExtraData["accesstoken"]);
		}