[client,common] add common GetCommonAccessToken

If client-common is build with WITH_SSO_MIB inject a callback that first
tries to retrieve a token from sso-mib library and only if that fails
falls back to a client provided callback.
This commit is contained in:
Armin Novak 2025-05-21 11:40:30 +02:00
parent 55d34fdb0e
commit 39f7972b28
No known key found for this signature in database
GPG Key ID: 2CF4A2D2D3D72105
3 changed files with 88 additions and 70 deletions

View File

@ -209,6 +209,10 @@ int freerdp_client_start(rdpContext* context)
client_context->mibClientWrapper = NULL;
return ERROR_INTERNAL_ERROR;
}
client_context->mibClientWrapper->GetCommonAccessToken =
freerdp_get_common_access_token(context);
if (!freerdp_set_common_access_token(context, sso_mib_get_access_token))
return ERROR_INTERNAL_ERROR;
client_context->mibClientWrapper->state = SSO_MIB_STATE_INIT;
#endif
@ -1126,27 +1130,6 @@ static BOOL client_cli_get_avd_access_token(freerdp* instance, char** token)
*token = NULL;
#ifdef WITH_SSO_MIB
rdpClientContext* client_context = (rdpClientContext*)instance->context;
if (client_context->mibClientWrapper->state == SSO_MIB_STATE_INIT ||
client_context->mibClientWrapper->state == SSO_MIB_STATE_SUCCESS)
{
rc = sso_mib_get_avd_access_token(instance, token);
if (rc)
{
client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS;
return rc;
}
else
{
WLog_WARN(TAG, "Getting AVD token from identity broker failed, falling back to "
"browser-based authentication.");
client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED;
// Fall through to regular avd access token retrieval
}
}
#endif
const char* client_id =
freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayAvdClientID);
const char* base = freerdp_settings_get_string(instance->context->settings,
@ -1227,42 +1210,7 @@ BOOL client_cli_get_access_token(freerdp* instance, AccessTokenType tokenType, c
va_start(ap, count);
const char* scope = va_arg(ap, const char*);
const char* req_cnf = va_arg(ap, const char*);
BOOL rc = FALSE;
#ifdef WITH_SSO_MIB
rdpClientContext* client_context = (rdpClientContext*)instance->context;
if (client_context->mibClientWrapper->state == SSO_MIB_STATE_INIT ||
client_context->mibClientWrapper->state == SSO_MIB_STATE_SUCCESS)
{
// Setup scope without URL encoding for sso-mib
char* scope_copy = winpr_str_url_decode(scope, strlen(scope));
if (!scope_copy)
{
WLog_ERR(TAG, "Failed to decode scope");
va_end(ap);
return FALSE;
}
rc = sso_mib_get_rdsaad_access_token(instance, scope_copy, req_cnf, token);
free(scope_copy);
if (rc)
{
client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS;
va_end(ap);
return rc;
}
else
{
WLog_WARN(TAG, "Getting RDS token from identity broker failed, falling back to "
"browser-based authentication.");
client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED;
// Fall through to regular rdsaad access token retrieval
}
}
#endif // WITH_SSO_MIB
rc = client_cli_get_rdsaad_access_token(instance, scope, req_cnf, token);
BOOL rc = client_cli_get_rdsaad_access_token(instance, scope, req_cnf, token);
va_end(ap);
return rc;
}

View File

@ -9,11 +9,12 @@
#include "sso_mib_tokens.h"
BOOL sso_mib_get_avd_access_token(freerdp* instance, char** token)
#include <freerdp/log.h>
#define TAG CLIENT_TAG("common.sso")
static BOOL sso_mib_get_avd_access_token(rdpClientContext* client_context, char** token)
{
WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context);
rdpClientContext* client_context = (rdpClientContext*)instance->context;
WINPR_ASSERT(client_context);
WINPR_ASSERT(client_context->mibClientWrapper);
WINPR_ASSERT(client_context->mibClientWrapper->app);
WINPR_ASSERT(token);
@ -52,12 +53,10 @@ cleanup:
return rc;
}
BOOL sso_mib_get_rdsaad_access_token(freerdp* instance, const char* scope, const char* req_cnf,
char** token)
static BOOL sso_mib_get_rdsaad_access_token(rdpClientContext* client_context, const char* scope,
const char* req_cnf, char** token)
{
WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context);
rdpClientContext* client_context = (rdpClientContext*)instance->context;
WINPR_ASSERT(client_context);
WINPR_ASSERT(client_context->mibClientWrapper);
WINPR_ASSERT(client_context->mibClientWrapper->app);
WINPR_ASSERT(scope);
@ -117,3 +116,75 @@ cleanup:
g_slist_free_full(scopes, g_free);
return rc;
}
BOOL sso_mib_get_access_token(rdpContext* context, AccessTokenType tokenType, char** token,
size_t count, ...)
{
BOOL rc = FALSE;
rdpClientContext* client_context = (rdpClientContext*)context;
WINPR_ASSERT(client_context);
const char* scope = NULL;
const char* req_cnf = NULL;
va_list ap;
va_start(ap, count);
if (tokenType == ACCESS_TOKEN_TYPE_AAD)
{
scope = va_arg(ap, const char*);
req_cnf = va_arg(ap, const char*);
}
if ((client_context->mibClientWrapper->state == SSO_MIB_STATE_INIT) ||
(client_context->mibClientWrapper->state == SSO_MIB_STATE_SUCCESS))
{
switch (tokenType)
{
case ACCESS_TOKEN_TYPE_AVD:
{
rc = sso_mib_get_avd_access_token(client_context, token);
if (rc)
client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS;
else
{
WLog_WARN(TAG, "Getting AVD token from identity broker failed, falling back to "
"browser-based authentication.");
client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED;
}
}
break;
case ACCESS_TOKEN_TYPE_AAD:
{
// Setup scope without URL encoding for sso-mib
char* scope_copy = winpr_str_url_decode(scope, strlen(scope));
if (!scope_copy)
WLog_ERR(TAG, "Failed to decode scope");
else
{
rc =
sso_mib_get_rdsaad_access_token(client_context, scope_copy, req_cnf, token);
free(scope_copy);
if (rc)
client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS;
else
{
WLog_WARN(TAG,
"Getting RDS token from identity broker failed, falling back to "
"browser-based authentication.");
client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED;
}
}
}
break;
default:
break;
}
}
if (!rc && client_context->mibClientWrapper->GetCommonAccessToken)
rc = client_context->mibClientWrapper->GetCommonAccessToken(context, tokenType, token,
count, scope, req_cnf);
va_end(ap);
return rc;
}

View File

@ -20,11 +20,10 @@ struct MIBClientWrapper
{
MIBClientApp* app;
enum sso_mib_state state;
pGetCommonAccessToken GetCommonAccessToken;
};
BOOL sso_mib_get_avd_access_token(freerdp* instance, char** token);
BOOL sso_mib_get_rdsaad_access_token(freerdp* instance, const char* scope, const char* req_cnf,
char** token);
BOOL sso_mib_get_access_token(rdpContext* context, AccessTokenType tokenType, char** token,
size_t count, ...);
#endif /* FREERDP_CLIENT_COMMON_SSO_MIB_TOKENS_H */