Skip to content

Commit

Permalink
Cpp oauth2 auth client (apache#7467)
Browse files Browse the repository at this point in the history
### Motivation

apache#7420 provides an Oauth2 auth client for java. This PR tries to support it in cpp client

### Modifications

- add implementation
- add related tests.
  • Loading branch information
jiazhai authored Jul 9, 2020
1 parent cc2c203 commit 2d0cceb
Show file tree
Hide file tree
Showing 10 changed files with 505 additions and 9 deletions.
107 changes: 103 additions & 4 deletions pulsar-client-cpp/include/pulsar/Authentication.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class PULSAR_PUBLIC Authentication {
public:
virtual ~Authentication();
virtual const std::string getAuthMethodName() const = 0;
virtual Result getAuthData(AuthenticationDataPtr& authDataContent) const {
virtual Result getAuthData(AuthenticationDataPtr& authDataContent) {
authDataContent = authData_;
return ResultOk;
}
Expand Down Expand Up @@ -107,7 +107,7 @@ class PULSAR_PUBLIC AuthTls : public Authentication {
static AuthenticationPtr create(const std::string& authParamsString);
static AuthenticationPtr create(const std::string& certificatePath, const std::string& privateKeyPath);
const std::string getAuthMethodName() const;
Result getAuthData(AuthenticationDataPtr& authDataTls) const;
Result getAuthData(AuthenticationDataPtr& authDataTls);

private:
AuthenticationDataPtr authDataTls_;
Expand Down Expand Up @@ -144,7 +144,7 @@ class PULSAR_PUBLIC AuthToken : public Authentication {
static AuthenticationPtr create(const TokenSupplier& tokenSupplier);

const std::string getAuthMethodName() const;
Result getAuthData(AuthenticationDataPtr& authDataToken) const;
Result getAuthData(AuthenticationDataPtr& authDataToken);

private:
AuthenticationDataPtr authDataToken_;
Expand All @@ -160,12 +160,111 @@ class PULSAR_PUBLIC AuthAthenz : public Authentication {
static AuthenticationPtr create(ParamMap& params);
static AuthenticationPtr create(const std::string& authParamsString);
const std::string getAuthMethodName() const;
Result getAuthData(AuthenticationDataPtr& authDataAthenz) const;
Result getAuthData(AuthenticationDataPtr& authDataAthenz);

private:
AuthenticationDataPtr authDataAthenz_;
};

// OAuth 2.0 token and associated information.
// currently mainly works for access token
class Oauth2TokenResult {
public:
enum
{
undefined_expiration = -1
};

Oauth2TokenResult();
~Oauth2TokenResult();

Oauth2TokenResult& setAccessToken(const std::string& accessToken);
Oauth2TokenResult& setIdToken(const std::string& idToken);
Oauth2TokenResult& setRefreshToken(const std::string& refreshToken);
Oauth2TokenResult& setExpiresIn(const int64_t expiresIn);

const std::string& getAccessToken() const;
const std::string& getIdToken() const;
const std::string& getRefreshToken() const;
int64_t getExpiresIn() const;

private:
// map to json "access_token"
std::string accessToken_;
// map to json "id_token"
std::string idToken_;
// map to json "refresh_token"
std::string refreshToken_;
// map to json "expires_in"
int64_t expiresIn_;
};

typedef std::shared_ptr<Oauth2TokenResult> Oauth2TokenResultPtr;

class Oauth2Flow {
public:
virtual ~Oauth2Flow();

/**
* Initializes the authorization flow.
*/
virtual void initialize() = 0;

/**
* Acquires an access token from the OAuth 2.0 authorization server.
* @return a token result including an access token.
*/
virtual Oauth2TokenResultPtr authenticate() = 0;

/**
* Closes the authorization flow.
*/
virtual void close() = 0;

protected:
Oauth2Flow();
};

typedef std::shared_ptr<Oauth2Flow> FlowPtr;

class CachedToken {
public:
~CachedToken();
virtual bool isExpired() = 0;
virtual AuthenticationDataPtr getAuthData() = 0;

protected:
CachedToken();
};

typedef std::shared_ptr<CachedToken> CachedTokenPtr;

/**
* Oauth2 based implementation of Pulsar client authentication.
* Passed in parameter would be like:
* ```
* "type": "client_credentials",
* "issuer_url": "https://accounts.google.com",
* "client_id": "d9ZyX97q1ef8Cr81WHVC4hFQ64vSlDK3",
* "client_secret": "on1uJ...k6F6R",
* "audience": "https://broker.example.com"
* ```
*/
class PULSAR_PUBLIC AuthOauth2 : public Authentication {
public:
AuthOauth2(ParamMap& params);
~AuthOauth2();

static AuthenticationPtr create(ParamMap& params);
static AuthenticationPtr create(const std::string& authParamsString);
const std::string getAuthMethodName() const;
Result getAuthData(AuthenticationDataPtr& authDataOauth2);

private:
FlowPtr flowPtr_;
CachedTokenPtr cachedTokenPtr_;
};

} // namespace pulsar

#endif /* PULSAR_AUTHENTICATION_H_ */
2 changes: 1 addition & 1 deletion pulsar-client-cpp/include/pulsar/ClientConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PULSAR_PUBLIC ClientConfiguration {
/**
* @return the authentication data
*/
const Authentication& getAuth() const;
Authentication& getAuth() const;

/**
* Set timeout on client operations (subscribe, create producer, close, unsubscribe)
Expand Down
7 changes: 7 additions & 0 deletions pulsar-client-cpp/lib/Authentication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "auth/AuthTls.h"
#include "auth/AuthAthenz.h"
#include "auth/AuthToken.h"
#include "auth/AuthOauth2.h"
#include <lib/LogUtils.h>

#include <string>
Expand Down Expand Up @@ -125,6 +126,9 @@ AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, ParamMap&
} else if (boost::iequals(pluginName, ATHENZ_PLUGIN_NAME) ||
boost::iequals(pluginName, ATHENZ_JAVA_PLUGIN_NAME)) {
return AuthAthenz::create(paramMap);
} else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) ||
boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) {
return AuthOauth2::create(paramMap);
} else {
return AuthenticationPtr();
}
Expand All @@ -139,6 +143,9 @@ AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, const std:
} else if (boost::iequals(pluginName, ATHENZ_PLUGIN_NAME) ||
boost::iequals(pluginName, ATHENZ_JAVA_PLUGIN_NAME)) {
return AuthAthenz::create(authParamsString);
} else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) ||
boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) {
return AuthOauth2::create(authParamsString);
} else {
return AuthenticationPtr();
}
Expand Down
2 changes: 1 addition & 1 deletion pulsar-client-cpp/lib/ClientConfiguration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ClientConfiguration& ClientConfiguration::setAuth(const AuthenticationPtr& authe
return *this;
}

const Authentication& ClientConfiguration::getAuth() const { return *impl_->authenticationPtr; }
Authentication& ClientConfiguration::getAuth() const { return *impl_->authenticationPtr; }

const AuthenticationPtr& ClientConfiguration::getAuthPtr() const { return impl_->authenticationPtr; }

Expand Down
2 changes: 1 addition & 1 deletion pulsar-client-cpp/lib/auth/AuthAthenz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ AuthenticationPtr AuthAthenz::create(ParamMap& params) {

const std::string AuthAthenz::getAuthMethodName() const { return "athenz"; }

Result AuthAthenz::getAuthData(AuthenticationDataPtr& authDataContent) const {
Result AuthAthenz::getAuthData(AuthenticationDataPtr& authDataContent) {
authDataContent = authDataAthenz_;
return ResultOk;
}
Expand Down
Loading

0 comments on commit 2d0cceb

Please sign in to comment.