/// <summary>
        /// Perform complete validation of the OAuth request and return a comprehensive result.
        /// </summary>
        /// <param name="requestMode">Desired token request mode.</param>
        /// <param name="uri">URI of the resource.</param>
        /// <param name="httpMethod">Request method.</param>
        /// <param name="arguments">Arguments in the request.</param>
        /// <param name="store">The Token Storage Provider.</param>
        /// <returns>A populated CheckResult object.</returns>
        static CheckResult CheckRequest(ServerRequestMode requestMode, Uri uri, string httpMethod, NameValueCollection arguments, IServerTokenStore store)
        {
            if (!IsSupportedVersion(arguments))
            {
                return new CheckResult(false, FailureTypeToString(FailureSpecificType.UnsupportedVersion), FailureGenericType.BadRequest, FailureSpecificType.UnsupportedVersion);
            }
            if (!HasRequiredArguments(arguments))
            {
                return new CheckResult(false, FailureTypeToString(FailureSpecificType.MissingParameter), FailureGenericType.BadRequest, FailureSpecificType.MissingParameter);
            }
            if (!HasOnlySingleArguments(arguments))
            {
                return new CheckResult(false, FailureTypeToString(FailureSpecificType.DuplicatedParameter), FailureGenericType.BadRequest, FailureSpecificType.DuplicatedParameter);
            }

            if (!IsValidTimestamp(arguments[OAuthArguments.OAuthTimestamp]))
            {
                return new CheckResult(false, FailureTypeToString(FailureSpecificType.InvalidTimestamp) + " - " + OAuthUtility.Timestamp().ToString(CultureInfo.InvariantCulture), FailureGenericType.BadRequest, FailureSpecificType.InvalidTimestamp); 
            }

            if (requestMode == ServerRequestMode.AccessToken)
            {
                if (!IsValidNonce(arguments[OAuthArguments.OAuthConsumerKey], arguments[OAuthArguments.OAuthNonce]))
                {
                    return new CheckResult(false, FailureTypeToString(FailureSpecificType.InvalidNonce), FailureGenericType.Unauthorized, FailureSpecificType.InvalidNonce);
                }
            }
            
            ConsumerRegistration cr = store.FindConsumerRegistration(arguments[OAuthArguments.OAuthConsumerKey]);
            if (cr == null)
            {
                return new CheckResult(false, FailureTypeToString(FailureSpecificType.InvalidConsumerKey), FailureGenericType.Unauthorized, FailureSpecificType.InvalidConsumerKey);
            }

            string tokenSecret = null;
            ServerAccessToken accessToken = null;
            switch (requestMode) 
            {
                case ServerRequestMode.RequestToken:
                    ServerRequestToken rt = store.FindRequestToken(arguments[OAuthArguments.OAuthToken]);
                    if (rt != null) tokenSecret = rt.Secret;
                    break;
                case ServerRequestMode.AccessToken:
                    accessToken = store.FindAccessToken(arguments[OAuthArguments.OAuthToken]);
                    if (accessToken != null) tokenSecret = accessToken.Secret;
                    break;
            }

            try
            {
                if (!IsValidSignature(uri, httpMethod, arguments, cr.ConsumerSecret, tokenSecret, cr.RsaCertificate))
                {
                    string failReason = FailureTypeToString(FailureSpecificType.InvalidSignature) + " - BaseString: " + OAuthUtility.GenerateBaseString(uri, arguments, httpMethod);
                    return new CheckResult(false, failReason, FailureGenericType.Unauthorized, FailureSpecificType.InvalidSignature);
                }
            }
            catch (NotSupportedException)
            {
                string failReason = FailureTypeToString(FailureSpecificType.UnsupportedSignatureMethod);
                return new CheckResult(false, failReason, FailureGenericType.BadRequest, FailureSpecificType.UnsupportedSignatureMethod);
            }

            CheckResult result = new CheckResult(true, null, FailureGenericType.None, FailureSpecificType.None);
            result.Consumer = cr;
            result.AccessToken = accessToken;

            return result;
        }
        /// <summary>
        /// Abstract method to handle token requests.
        /// </summary>
        /// <param name="request">Abstracted HTTP request object.</param>
        /// <param name="response">Abstracted HTTP response object.</param>
        /// <param name="mode">Token request mode.</param>
        /// <param name="store">Token storage provider.</param>
        static void HandleHttpTokenRequest(AbstractRequest request, AbstractResponse response, ServerRequestMode mode, IServerTokenStore store)
        {
            StreamWriter sw = new StreamWriter(response.OutputStream);
            NameValueCollection nvc = null;
            nvc = DecodeRequest(request);
            if (nvc == null) 
            {
                response.StatusCode = 400;
                sw.Write("Unsupported HTTP request method");
                sw.Dispose();
                return;
            }

            TokenProcessingResult result = HandleTokenRequest(mode, request.Url, request.HttpMethod, nvc, store);
            if (!result.Success)
            {
                switch (result.FailGenericCondition)
                {
                    case FailureGenericType.BadRequest:
                        response.StatusCode = 400;
                        break;
                    case FailureGenericType.Unauthorized:
                        response.StatusCode = 401;
                        break;
                }
                sw.Write(result.FailReason);
                sw.Dispose();
                return;
            }

            sw.Write(OAuthUtility.ArgsToVal(result.ResponseArguments, AuthenticationMethod.Post));
            sw.Dispose();
        }
        /// <summary>
        /// Handle a token request using raw request arguments.
        /// </summary>
        /// <param name="mode">The request OAuth mode for processing token requests.</param>
        /// <param name="uri">The URI of the resource.</param>
        /// <param name="requestMethod">The request method used.</param>
        /// <param name="arguments">The arguments in the request.</param>
        /// <param name="store">The Token Storage Provider.</param>
        /// <returns>A processing result object that contains all the important result data.</returns>
        static TokenProcessingResult HandleTokenRequest(ServerRequestMode mode, Uri uri, string requestMethod, NameValueCollection arguments, IServerTokenStore store)
        {
            NameValueCollection nvc = new NameValueCollection(arguments);
            nvc.Remove(Strings.Realm);

            CheckResult result = CheckRequest(ServerRequestMode.RequestToken, uri, requestMethod, nvc, store);
            if (!result.Success)
            {
                return new TokenProcessingResult(false, result.FailReason, result.FailGenericCondition, result.FailSpecificCondition);
            }

            OAuthToken token = null;

            switch (mode)
            {
                case ServerRequestMode.RequestToken:
                    token = BuildAndStoreRequestToken(result.Consumer.ConsumerKey, null, store);
                    break;
                case ServerRequestMode.AccessToken:
                    token = RetrieveAccessTokenUsingRequestToken(nvc[OAuthArguments.OAuthToken], store);
                    if (token == null) return new TokenProcessingResult(false, FailureTypeToString(FailureSpecificType.InvalidToken), FailureGenericType.Unauthorized, FailureSpecificType.InvalidToken);
                    break;
            }

            if (token != null)
            {
                NameValueCollection outcollection = new NameValueCollection();
                outcollection.Add(OAuthArguments.OAuthToken, token.Key);
                outcollection.Add(OAuthArguments.OAuthTokenSecret, token.Secret);
                TokenProcessingResult tresult = new TokenProcessingResult(true, null, FailureGenericType.None, FailureSpecificType.None);
                tresult.ResponseArguments.Add(outcollection);
                return tresult;
            }
            return new TokenProcessingResult(false, "Bad request", FailureGenericType.BadRequest, FailureSpecificType.None);
        }
 /// <summary>
 /// Using the provided Request Token, retrieve the associated Access Token,
 /// if one has been authorized.
 /// </summary>
 /// <param name="requestTokenKey">The key of the Request Token.</param>
 /// <param name="store">Token storage provider.</param>
 /// <returns>If the Access Token is valid, returns the token.  If not, returns null.</returns>
 public static ServerAccessToken RetrieveAccessTokenUsingRequestToken(string requestTokenKey, IServerTokenStore store)
 {
     ServerRequestToken requestToken = store.FindRequestToken(requestTokenKey);
     if (requestToken == null || String.IsNullOrEmpty(requestToken.AccessTokenKey))
     {
         return null;
     }
     ServerAccessToken accessToken = store.FindAccessToken(requestToken.AccessTokenKey);
     store.DeleteRequestToken(requestTokenKey);
     return accessToken;
 }
 /// <summary>
 /// Process and respond to a token request using HttpListenerRequest and HttpListenerResponse objects.
 /// </summary>
 /// <param name="request">Request to process.</param>
 /// <param name="response">Response object to respond with.</param>
 /// <param name="mode">Token request mode.</param>
 /// <param name="store">Token storage object.</param>
 public static void HandleTokenRequest(HttpListenerRequest request, HttpListenerResponse response, ServerRequestMode mode, IServerTokenStore store)
 {
     AbstractRequest arequest = new AbstractRequest(request);
     AbstractResponse aresponse = new AbstractResponse(response);
     HandleHttpTokenRequest(arequest, aresponse, mode, store);
 }
        /// <summary>
        /// Authorize a Request Token, thereby generating an associated Access Token.
        /// </summary>
        /// <param name="requestTokenKey">Key of the request token.</param>
        /// <param name="userAccount">The associated user account.</param>
        /// <param name="approvedScope">The optional scope parameters.</param>
        /// <param name="store">Token storage object to use.</param>
        public static void AuthorizeRequestToken(string requestTokenKey, string userAccount, string[] approvedScope, IServerTokenStore store)
        {
            ServerRequestToken requestToken = store.FindRequestToken(requestTokenKey);
            if (requestToken == null)
            {
                throw new TokenNotFoundException(String.Format(CultureInfo.InvariantCulture, "Request Token '{0}' is not present.", requestTokenKey));
            }
            if (!String.IsNullOrEmpty(requestToken.AccessTokenKey))
            {
                throw new TokenAlreadyAuthorizedException(String.Format(CultureInfo.InvariantCulture, "Request Token '{0}' is already authorized.", requestTokenKey));
            }
            NameValueCollection nvc = new NameValueCollection();
            nvc.Add(requestToken.Parameters);
            if (approvedScope != null) { nvc["scope"] = String.Join(" ", approvedScope); }
            else { nvc["scope"] = ""; }

            ServerAccessToken accessToken = new ServerAccessToken(requestToken.ConsumerKey, GenerateRandomValue(), GenerateRandomValue(), userAccount, nvc);
            requestToken.AccessTokenKey = accessToken.Key;
            store.StoreAccessToken(accessToken);
            store.StoreRequestToken(requestToken);
        }
 /// <summary>
 /// Create a new Request Token using the given arguments, and store it using the supplied
 /// token storage.
 /// </summary>
 /// <param name="consumerKey">Key of the consumer that is making the request.</param>
 /// <param name="parameters">Additional parameters that will be stored in the Request Token.</param>
 /// <param name="store">Token storage provider.</param>
 /// <returns>A new ServerRequestToken.</returns>
 public static ServerRequestToken BuildAndStoreRequestToken(string consumerKey, NameValueCollection parameters, IServerTokenStore store)
 {
     ServerRequestToken requestToken = new ServerRequestToken(consumerKey, GenerateRandomValue(), GenerateRandomValue(), null, parameters);
     store.StoreRequestToken(requestToken);
     return requestToken;
 }
 /// <summary>
 /// Authenticate a user given raw request arguments.
 /// </summary>
 /// <param name="uri">The URI of the resource.</param>
 /// <param name="requestMethod">The request method used.</param>
 /// <param name="arguments">The arugments in the request.</param>
 /// <param name="store">The Token Storage Provider.</param>
 /// <returns>If valid, returns the matching ServerAccessToken.  If not valid, returns null.</returns>
 static ServerAccessToken AuthenticateUser(Uri uri, string requestMethod, NameValueCollection arguments, IServerTokenStore store)
 {
     CheckResult result = CheckRequest(ServerRequestMode.AccessToken, uri, requestMethod, arguments, store);
     if (!result.Success) return null;
     return result.AccessToken;
 }
 /// <summary>
 /// Authenticate a user HTTP Request.
 /// </summary>
 /// <param name="request">HttpRequest to authenticate.</param>
 /// <param name="store">Token storage object to use.</param>
 /// <returns>If valid, returns the matching ServerAccessToken.  If not valid, returns null.</returns>
 public static ServerAccessToken AuthenticateUser(HttpListenerRequest request, IServerTokenStore store)
 {
     AbstractRequest arequest = new AbstractRequest(request);
     NameValueCollection nvc = DecodeRequest(arequest);
     if (nvc == null) return null;
     return AuthenticateUser(arequest.Url, arequest.HttpMethod, nvc, store);
 }
 /// <summary>
 /// Initializes the HttpModule.
 /// </summary>
 /// <param name="context">The current ASP.NET application.</param>
 public void Init(HttpApplication context)
 {
     Store = OAuthServer.GetConfiguredStorageProvider();
     context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
     context.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
 }