/// <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); }