10Duke Scale C++ Client
Loading...
Searching...
No Matches
AbstractClientFactory.h
1#ifndef TENDUKE_SE_ABSTRACTCLIENTFACTORY_H
2#define TENDUKE_SE_ABSTRACTCLIENTFACTORY_H
3
4#include "createDefaultTendukeServices.h"
5#include "createTendukeClient.h"
6#include "TendukeClientWithOIDCSession.h"
7#include "config/BackendConfiguration.h"
8#include "config/ClientProperties.h"
9#include "log/log.h"
10#include "oidc/idtoken/IdTokenSession.h"
11#include "oidc/session/OIDCLogin.h"
12#include "oidc/session/SerializedOIDCSession.h"
13#include "state/ClientState.h"
14#include "state/DeserializeStateFromJSON.h"
15
16namespace tenduke { namespace se {
17
23template<class P>
25{
26public:
27 virtual ~AbstractClientFactory() = default;
28
38 const std::string &clientId,
39 const ::tenduke::ServiceConfiguration &serviceConfiguration
40 )
41 : services(::tenduke::createDefaultTendukeServices(clientId, serviceConfiguration))
42 {}
43
50 explicit AbstractClientFactory(const ::tenduke::TendukeServices &services)
51 : services(services)
52 {}
53
54public:
69 virtual std::unique_ptr<::tenduke::se::TendukeClientWithOIDCSession> createClient(
70 const ::tenduke::se::ClientProperties &clientProperties,
71 const ::tenduke::se::BackendConfiguration &backendConfiguration,
72 const ::tenduke::oauth::OAuthBackendConfiguration &oauthBackendConfiguration,
73 const ::tenduke::oidc::OIDCConfiguration &oidcConfiguration,
74 const P &authenticationConfiguration,
75 const std::string &initialStateAsJSON = {}
76 ) const
77 {
78 auto oauthConfiguration = mkOAuthConfiguration(oauthBackendConfiguration, authenticationConfiguration);
79 auto oidcConfig = std::make_shared<::tenduke::oidc::OIDCConfiguration>(oidcConfiguration);
80 auto initialState = deserializeInitialState(initialStateAsJSON);
81
82 return ::tenduke::se::createClient(
83 services,
84 clientProperties,
85 backendConfiguration,
86 oauthConfiguration,
87 oidcConfig,
88 initialState,
89 createOIDCSessionService(
90 oauthConfiguration,
91 oidcConfig,
92 authenticationConfiguration,
93 createUniqueOIDCState(initialState.oidcState)
94 )
95 );
96 }
97
113 std::unique_ptr<::tenduke::se::TendukeClientWithOIDCSession> createClientUsingAutodiscovery(
114 const ::tenduke::se::ClientProperties &clientProperties,
115 const ::tenduke::se::BackendConfiguration &backendConfiguration,
116 const std::string &oidcAutodiscoveryURL,
117 const P &authenticationConfiguration,
118 const std::string &initialStateAsJSON = {}
119 ) const
120 {
121 const auto initialState = deserializeInitialState(initialStateAsJSON);
122 std::shared_ptr<const ::tenduke::oauth::OAuthConfiguration> oauthConfiguration;
123 std::shared_ptr<const ::tenduke::oidc::OIDCConfiguration> oidcConfiguration;
124 if (canUseState(initialState)) {
125 ::tenduke::log::info("Bootstrapping OIDC configuration from provided state");
126 oauthConfiguration = initialState.oauthConfiguration;
127 oidcConfiguration = initialState.oidcConfiguration;
128 }
129 else {
130 ::tenduke::log::info("Bootstrapping OIDC configuration with auto discovery...");
131 auto discoveryResult = services.oidcBackendConfiguration->discover(oidcAutodiscoveryURL);
132 oidcConfiguration = services.oidcBackendConfiguration->toOIDCConfiguration(discoveryResult);
133 oauthConfiguration = mkOAuthConfiguration(
134 *discoveryResult.getOAuthConfiguration(),
135 authenticationConfiguration
136 );
137
138 dumpAutodiscoveryResult(*services.oidcBackendConfiguration, discoveryResult);
139 }
140
141 return ::tenduke::se::createClient(
142 services,
143 clientProperties,
144 backendConfiguration,
145 oauthConfiguration,
146 oidcConfiguration,
147 initialState,
148 createOIDCSessionService(
149 oauthConfiguration,
150 oidcConfiguration,
151 authenticationConfiguration,
152 createUniqueOIDCState(initialState.oidcState)
153 )
154 );
155 }
156
157protected:
161 {
162 std::shared_ptr<const ::tenduke::oidc::OIDCClient> client;
163 std::shared_ptr<const ::tenduke::oidc::OIDCLogin> login;
164 };
165
172 virtual std::shared_ptr<::tenduke::oauth::OAuthConfiguration> mkOAuthConfiguration(
173 const ::tenduke::oauth::OAuthBackendConfiguration &oauthBackendConfig,
174 const P &authenticationConfig
175 ) const = 0;
176
183 const ::tenduke::oidc::AutoDiscovery &service,
184 const ::tenduke::oidc::AutoDiscoveryResult &result
185 ) const
186 {
187 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() Auto discovered properties:");
188 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() - authorization endpoint: " + result.getOAuthConfiguration()->authorizationEndpointUrl);
189 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() - token endpoint: " + result.getOAuthConfiguration()->tokenEndpointUrl);
190 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() - userinfo endpoint: " + result.getOOIDCConfiguration()->userinfoEndpoint);
191 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() - issuer: " + result.getOOIDCConfiguration()->issuer);
192 ::tenduke::log::debug("AbstractClientFactory::dumpAutodiscoveryResult() - verification key:");
193
194 auto jwk = service.getDefaultVerificationKey(result);
195
196 ::tenduke::log::debug(jwk->key->toPEM());
197 }
198
199 virtual std::unique_ptr<::tenduke::oidc::OIDCState> createUniqueOIDCState(const std::shared_ptr<const ::tenduke::oidc::OIDCState> &state)
200 const
201 {
202 if (state == nullptr) {
203 return nullptr;
204 }
205 return std::unique_ptr<::tenduke::oidc::OIDCState>(new ::tenduke::oidc::OIDCState(*state));
206 }
207
208
209 virtual ::tenduke::se::ClientState deserializeInitialState(const std::string &initialStateAsJson) const
210 {
211 return ::tenduke::se::DeserializeStateFromJSON(
212 services.jwtParser,
213 services.jsonParser,
214 services.keyFactory
215 ).from(initialStateAsJson);
216 }
217
218 virtual OIDCServices createOIDCLoginService(
219 const std::shared_ptr<const ::tenduke::oauth::OAuthConfiguration> &oauthConfiguration,
220 const std::shared_ptr<const ::tenduke::oidc::OIDCConfiguration> &oidcConfiguration,
221 const P &authenticationConfiguration
222 ) const = 0;
223
224 virtual std::shared_ptr<::tenduke::oidc::OIDCSession> createOIDCSessionService(
225 const std::shared_ptr<const ::tenduke::oauth::OAuthConfiguration> &oauthConfiguration ,
226 const std::shared_ptr<const ::tenduke::oidc::OIDCConfiguration> &oidcConfiguration,
227 const P &authenticationConfiguration,
228 std::unique_ptr<::tenduke::oidc::OIDCState> initialState
229 ) const
230 {
231 auto oidcLoginServices = createOIDCLoginService(
232 oauthConfiguration,
233 oidcConfiguration,
234 authenticationConfiguration
235 );
236 auto oidcSessionImpl = std::make_shared<::tenduke::oidc::IdTokenSession>(
237 std::move(initialState),
238 oidcLoginServices.login,
239 oidcLoginServices.client,
240 services.clock,
241 authenticationConfiguration.oidcSessionConfiguration.sessionEventListener,
243 authenticationConfiguration.oidcSessionConfiguration.loginTimeout
244 );
245
246 return std::make_shared<::tenduke::oidc::SerializedOIDCSession>(
247 oidcSessionImpl,
248 authenticationConfiguration.oidcSessionConfiguration.concurrencyTimeout
249 );
250 }
251
258 virtual bool canUseState(const ::tenduke::se::ClientState &state)
259 const
260 {
261 // OAuthConfiguration is required
262 if (state.oauthConfiguration == nullptr) {
263 return false;
264 }
265 // OAuth client ID is required
266 if (state.oauthConfiguration->clientId.empty()) {
267 return false;
268 }
269 // OIDC configuration is required
270 if (state.oidcConfiguration == nullptr) {
271 return false;
272 }
273 return true;
274 };
275
276 virtual std::string getScope(const P &authenticationConfiguration)
277 const
278 {
279 if (authenticationConfiguration.scopes.empty()) {
280 return "profile email";
281 }
282 return authenticationConfiguration.scopes;
283 }
284
285protected:
286 ::tenduke::TendukeServices services;
287};
288
289}}
290
291#endif //TENDUKE_SE_ABSTRACTCLIENTFACTORY_H
AbstractClientFactory(const std::string &clientId, const ::tenduke::ServiceConfiguration &serviceConfiguration)
Constructs new instance with default services.
Definition AbstractClientFactory.h:37
static const std::uint64_t DEFAULT_SAFETY_MARGIN_S
Default safety margin in seconds for checking access token expiration.
Definition OIDCSessionImpl.h:26
virtual std::shared_ptr<::tenduke::oauth::OAuthConfiguration > mkOAuthConfiguration(const ::tenduke::oauth::OAuthBackendConfiguration &oauthBackendConfig, const P &authenticationConfig) const =0
Creates full OAuth-configuration.
AbstractClientFactory(const std::string &clientId, const ::tenduke::ServiceConfiguration &serviceConfiguration)
Constructs new instance with default services.
Definition AbstractClientFactory.h:37
AbstractClientFactory(const ::tenduke::TendukeServices &services)
Constructs new instance with given services.
Definition AbstractClientFactory.h:50
virtual bool canUseState(const ::tenduke::se::ClientState &state) const
Checks if stored state can be used and autodiscovery skipped.
Definition AbstractClientFactory.h:258
virtual void dumpAutodiscoveryResult(const ::tenduke::oidc::AutoDiscovery &service, const ::tenduke::oidc::AutoDiscoveryResult &result) const
Dumps OIDC autodiscovery result to log, using DEBUG log level.
Definition AbstractClientFactory.h:182
std::unique_ptr<::tenduke::se::TendukeClientWithOIDCSession > createClientUsingAutodiscovery(const ::tenduke::se::ClientProperties &clientProperties, const ::tenduke::se::BackendConfiguration &backendConfiguration, const std::string &oidcAutodiscoveryURL, const P &authenticationConfiguration, const std::string &initialStateAsJSON={}) const
Creates client for 10Duke Enterprise, using OIDC autodiscovery for OAuth and OIDC parameters.
Definition AbstractClientFactory.h:113
virtual std::unique_ptr<::tenduke::se::TendukeClientWithOIDCSession > createClient(const ::tenduke::se::ClientProperties &clientProperties, const ::tenduke::se::BackendConfiguration &backendConfiguration, const ::tenduke::oauth::OAuthBackendConfiguration &oauthBackendConfiguration, const ::tenduke::oidc::OIDCConfiguration &oidcConfiguration, const P &authenticationConfiguration, const std::string &initialStateAsJSON={}) const
Creates client for 10Duke Scale from manually provided parameters.
Definition AbstractClientFactory.h:69
Support for JSON Web Keys.
Definition DynamicJWKSSignatureValidator.h:9
void debug(const char *message)
Write message to global logger at DEBUG-level.
Definition log.cpp:54
void info(const char *message)
Write message to global logger at INFO-level.
Definition log.cpp:74
Classes, functions and globals of 10Duke Scale C++ Client.
Definition AbstractClientFactory.h:16
Root for classes, functions and globals of 10Duke C++ Client.
Definition AbstractClientFactory.h:16
Helper to return OIDCClient and OIDLogin: IdToken auth needs both.
Definition AbstractClientFactory.h:161
Helper to return OIDCClient and OIDLogin: IdToken auth needs both.
Definition AbstractClientFactory.h:161