// // OAuth10Credentials.h // // Library: Net // Package: OAuth // Module: OAuth10Credentials // // Definition of the OAuth10Credentials class. // // Copyright (c) 2014, Applied Informatics Software Engineering GmbH. // and Contributors. // // SPDX-License-Identifier: BSL-1.0 // #ifndef Net_OAuth10Credentials_INCLUDED #define Net_OAuth10Credentials_INCLUDED #include "Poco/Net/Net.h" #include "Poco/URI.h" namespace Poco { namespace Net { class HTTPRequest; class HTMLForm; class Net_API OAuth10Credentials /// This class implements OAuth 1.0A authentication for HTTP requests, /// according to RFC 5849. /// /// Only PLAINTEXT and HMAC-SHA1 signature methods are /// supported. The RSA-SHA1 signature method is not supported. /// /// The OAuth10Credentials can be used to sign a client request, as /// well as to verify the signature of a request on the server. /// /// To sign a client request, using a known consumer (client) key, consumer (client) secret, /// OAuth token and token secret: /// /// 1. Create an OAuth10Credentials object using all four credentials, either using /// the four argument constructor, or by using the default constructor and setting /// the credentials using the setter methods. /// 2. Create a URI containing the full request URI. /// 3. Create an appropriate HTTPRequest object. /// 4. Optionally, create a HTMLForm object containing additional parameters to sign. /// 5. Sign the request by calling authenticate(). This will add an OAuth /// Authorization header to the request. /// 6. Send the request using a HTTPClientSession. /// /// To request the OAuth request token from a server, using only the consumer (client) key /// and consumer (client) secret: /// /// 1. Create an OAuth10Credentials object using the two consumer credentials, either using /// the two argument constructor, or by using the default constructor and setting /// the credentials using the setter methods. /// 2. Specify the callback URI using setCallback(). /// 3. Create a URI containing the full request URI to obtain the token. /// 4. Create an appropriate HTTPRequest object. /// 5. Sign the request by calling authenticate(). This will add an OAuth /// Authorization header to the request. /// 6. Send the request using a HTTPClientSession. /// 7. The response will contain the request token and request token secret. /// These can be extracted from the response body using a HTMLForm object. /// /// Requesting the access token and secret (temporary credentials) from the server /// is analogous to signing a client request using consumer key, consumer secret, /// request token and request token secret. /// The server response will contain the access token and access token secret, /// which can again be extracted from the response body using a HTMLForm object. /// /// To verify a request on the server: /// /// 1. Create an OAuth10Credentials object using the constructor taking a /// HTTPRequest object. This will extract the consumer key and token (if /// provided). /// 2. Provide the consumer secret and token secret (if required) matching the /// consumer key and token to the OAuth10Credentials object using the /// setter methods. /// 3. Create an URI object containing the full request URI. /// 4. Call verify() to verify the signature. /// 5. If verification was successful, and the request was a request for /// a request (temporary) token, call getCallback() to /// obtain the callback URI provided by the client. { public: enum SignatureMethod /// OAuth 1.0A Signature Method. { SIGN_PLAINTEXT, /// OAuth 1.0A PLAINTEXT signature method SIGN_HMAC_SHA1 /// OAuth 1.0A HMAC-SHA1 signature method }; OAuth10Credentials(); /// Creates an empty OAuth10Credentials object. OAuth10Credentials(const std::string& consumerKey, const std::string& consumerSecret); /// Creates an OAuth10Credentials object with the given consumer key and consumer secret. /// /// The token and tokenSecret will be left empty. OAuth10Credentials(const std::string& consumerKey, const std::string& consumerSecret, const std::string& token, const std::string& tokenSecret); /// Creates an OAuth10Credentials object with the given consumer key and /// consumer secret, as well as token and token secret. explicit OAuth10Credentials(const HTTPRequest& request); /// Creates an OAuth10Credentials object from a HTTPRequest object. /// /// Extracts consumer key and token (if available) from the Authorization header. /// /// Throws a NotAuthenticatedException if the request does /// not contain OAuth 1.0 credentials. ~OAuth10Credentials(); /// Destroys the OAuth10Credentials. void setConsumerKey(const std::string& consumerKey); /// Sets the consumer key. const std::string& getConsumerKey() const; /// Returns the consumer key. void setConsumerSecret(const std::string& consumerSecret); /// Sets the consumer secret. const std::string& getConsumerSecret() const; /// Returns the consumer secret. void setToken(const std::string& token); /// Sets the token. const std::string& getToken() const; /// Returns the token. void setTokenSecret(const std::string& tokenSecret); /// Sets the token. const std::string& getTokenSecret() const; /// Returns the token secret. void setRealm(const std::string& realm); /// Sets the optional realm to be included in the Authorization header. const std::string& getRealm() const; /// Returns the optional realm to be included in the Authorization header. void setCallback(const std::string& uri); /// Sets the callback URI. const std::string& getCallback() const; /// Returns the callback URI. void authenticate(HTTPRequest& request, const Poco::URI& uri, SignatureMethod method = SIGN_HMAC_SHA1); /// Adds an OAuth 1.0A Authentication header to the given request, using /// the given signature method. void authenticate(HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params, SignatureMethod method = SIGN_HMAC_SHA1); /// Adds an OAuth 1.0A Authentication header to the given request, using /// the given signature method. bool verify(const HTTPRequest& request, const Poco::URI& uri); /// Verifies the signature of the given request. /// /// The consumer key, consumer secret, token and token secret must have been set. /// /// Returns true if the signature is valid, otherwise false. /// /// Throws a NotAuthenticatedException if the request does not contain OAuth /// credentials, or in case of an unsupported OAuth version or signature method. bool verify(const HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params); /// Verifies the signature of the given request. /// /// The consumer key, consumer secret, token and token secret must have been set. /// /// Returns true if the signature is valid, otherwise false. /// /// Throws a NotAuthenticatedException if the request does not contain OAuth /// credentials, or in case of an unsupported OAuth version or signature method. void nonceAndTimestampForTesting(const std::string& nonce, const std::string& timestamp); /// Sets the nonce and timestamp to a wellknown value. /// /// For use by testsuite only, to test the signature /// algorithm with wellknown inputs. /// /// In normal operation, the nonce is a random value /// computed by createNonce() and the timestamp is taken /// from the system time. static const std::string SCHEME; protected: void signPlaintext(Poco::Net::HTTPRequest& request) const; /// Signs the given HTTP request according to OAuth 1.0A PLAINTEXT signature method. void signHMACSHA1(Poco::Net::HTTPRequest& request, const std::string& uri, const Poco::Net::HTMLForm& params) const; /// Signs the given HTTP request according to OAuth 1.0A HMAC-SHA1 signature method. std::string createNonce() const; /// Creates a nonce, which is basically a Base64-encoded 32 character random /// string, with non-alphanumeric characters removed. std::string createSignature(const Poco::Net::HTTPRequest& request, const std::string& uri, const Poco::Net::HTMLForm& params, const std::string& nonce, const std::string& timestamp) const; /// Creates a OAuth signature for the given request and its parameters, according /// to . static std::string percentEncode(const std::string& str); /// Percent-encodes the given string according to Twitter API's rules, /// given in . private: OAuth10Credentials(const OAuth10Credentials&); OAuth10Credentials& operator = (const OAuth10Credentials&); std::string _consumerKey; std::string _consumerSecret; std::string _token; std::string _tokenSecret; std::string _callback; std::string _realm; std::string _nonce; std::string _timestamp; }; // // inlines // inline const std::string& OAuth10Credentials::getConsumerKey() const { return _consumerKey; } inline const std::string& OAuth10Credentials::getConsumerSecret() const { return _consumerSecret; } inline const std::string& OAuth10Credentials::getToken() const { return _token; } inline const std::string& OAuth10Credentials::getTokenSecret() const { return _tokenSecret; } inline const std::string& OAuth10Credentials::getRealm() const { return _realm; } inline const std::string& OAuth10Credentials::getCallback() const { return _callback; } } } // namespace Poco::Net #endif // Net_OAuth10Credentials_INCLUDED