Top | ![]() |
![]() |
![]() |
![]() |
GSignondOauthPluginGSignondOauthPlugin — OAuth1/OAuth2 authentication plugin for gSSO single sign-on service |
The OAuth plugin provides a client-side implementation of OAuth 1 and OAuth 2 authorization protocols. The overall flow is that the plugin is requested to perform authorization using supplied authorization parameters, and if it has succeeded in doing so, it returns a token string to the application that can be used to access protected resources over https. The plugin is not involved in accessing protected resources, only in initial authorization.
OAuth1 is specified in RFC 5849, OAuth2 is specified in RFC 6749 (with additional info regarding the basic bearer token type in RFC6750). The two versions are not compatible and specify significantly different authorization sequences, for that reason they are implemented as separate mechanisms in the plugin.
The plugin implements the standard GSignondPlugin interface, and after instantiating a plugin object all interactions happen through that interface.
“type” property of the plugin object is set to "oauth".
“mechanisms” property of the plugin object is a list of "oauth1" and "oauth2".
The authorization sequence begins with issuing gsignond_plugin_request_initial()
.
The mechanism
parameter should be set to "oauth1" or "oauth2", and
the contents of session_data
and identity_method_cache
parameters depend
on the mechanism and are described in detail below.
The plugin responds to the request with one of the following signals:
“response-final” This means the authorization sequence ended
successfully, and the authorization token is delivered in session_data
parameter
of the signal. This signal concludes the sequence.
“user-action-required” The plugin is requesting to perform a
user authorization procedure by opening a webpage in a user-agent (browser) where the user is expected
to enter her credentials. Parameters for this step are specified in ui_data
.
After the user interaction has completed, the results are returned to the
plugin with gsignond_plugin_user_action_finished()
method, and the authorization
process continues.
“store” The plugin is requesting to replace the token cache
with the contents of identity_method_cache
parameter. There is no need to respond to this
signal; the authorization process continues immediately.
“error” An error has happened in the authorization sequence
and it stops.
Typical errors are GSIGNOND_ERROR_MISSING_DATA
which means there wasn't enough
data provided in gsignond_plugin_request_initial()
to perform the authorization,
GSIGNOND_ERROR_NOT_AUTHORIZED
which means the server rejected the
authorization attempt, GSIGNOND_ERROR_USER_INTERACTION
which means there
was an error during interaction with the user.
At any point the application can request to stop the authorization by calling
gsignond_plugin_cancel()
. The plugin responds with an “error” signal
containing a GSIGNOND_ERROR_SESSION_CANCELED
error.
Example 1. Using OAuth1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
/* PLEASE NOTE: this example is meant for OAuth plugin developers. If you're * an application developer who wants to use this plugin, please refer to * libgsignon-glib documentation here: * http://accounts-sso.gitlab.io/libgsignon-glib */ /* * Copyright (C) 2012 Intel Corporation. * * Contact: Alexander Kanavin <alex.kanavin@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA */ #include <gsignond/gsignond-session-data.h> #include <gsignond/gsignond-plugin-interface.h> #include <gsignond/gsignond-error.h> #include <gsignond/gsignond-utils.h> #include "gsignond-oauth-plugin.h" // this function returns a token for the token cache static GVariant* make_normal_token(void) { GSignondDictionary* token = gsignond_dictionary_new(); gsignond_dictionary_set_string(token, "AccessToken", "megaaccesstoken"); gsignond_dictionary_set_string(token, "TokenSecret", "megatokensecret"); gsignond_dictionary_set_string(token, "Realm", "megarealm"); GVariant* token_var = gsignond_dictionary_to_variant(token); g_object_unref(token); return token_var; } //this function makes a token cache with one unrelated token //(because it belongs to a different consumer key) static GSignondDictionary* make_token_cache(void) { GSignondDictionary* tokens = gsignond_dictionary_new(); gsignond_dictionary_set(tokens, "someotherclient", make_normal_token()); return tokens; } //this callback prints the received token and exits the mainloop static void response_callback(GSignondPlugin* plugin, GSignondSessionData* result, gpointer user_data) { GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(result)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Authenticated successfully, got token:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); g_main_loop_quit(user_data); } //this function prints the content of the updated token cache static void store_callback(GSignondPlugin* plugin, GSignondSessionData* result, gpointer user_data) { GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(result)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Should replace the token cache with the following:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); } //this function shows what the UI interaction component needs to do static void user_action_required_callback(GSignondPlugin* plugin, GSignondSignonuiData* ui_request, gpointer user_data) { // ui_request typically contains a URI that needs to be opened, // and a redirect URI that needs to be 'captured' by the user-agent and // reported back to the plugin // in practice the ui_request needs to be handed over to a user-agent // but here we simply print it GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(ui_request)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Got a UI interaction request:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); // in practice the following should be received from a user-agent, // but in this example for the sake of simplicity we report the hardcoded redirect // URI (with additional parameters) immidiately back to the plugin GSignondSignonuiData* ui_data = gsignond_signonui_data_new(); gsignond_signonui_data_set_url_response(ui_data, "http://somehost/somegsignondoauthcallback?oauth_token=somerandomtoken&oauth_verifier=somerandomverifier"); gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_NONE); gsignond_plugin_user_action_finished(plugin, ui_data); g_object_unref(ui_data); } // print an error and exit the mainloop static void error_callback(GSignondPlugin* plugin, GError* error, gpointer user_data) { g_print("Got an error: %s\n", error->message); g_main_loop_quit(user_data); } int main (void) { #if !GLIB_CHECK_VERSION (2, 36, 0) g_type_init (); #endif gpointer plugin = g_object_new(gsignond_oauth_plugin_get_type(), NULL); GMainLoop *main_loop = g_main_loop_new (NULL, FALSE); //connect to various signals of the plugin object g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), main_loop); g_signal_connect(plugin, "user-action-required", G_CALLBACK(user_action_required_callback), NULL); g_signal_connect(plugin, "store", G_CALLBACK(store_callback), NULL); g_signal_connect(plugin, "error", G_CALLBACK(error_callback), main_loop); GSignondSessionData* data = gsignond_session_data_new(); GSignondDictionary* token_cache = make_token_cache(); //fill in necessary data for OAuth1 authorization gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "ConsumerKey", "megaclient"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "ConsumerSecret", "megasecret"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "Realm", "megarealm"); gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT); const gchar *realm_list[] = { "somehost", NULL }; GSequence *allowed_realms = gsignond_copy_array_to_sequence(realm_list); gsignond_session_data_set_allowed_realms(data, allowed_realms); g_sequence_free(allowed_realms); // can also be HMAC-SHA1, or RSA-SHA1 (in the latter case, also RSAPrivateKey // needs to be set gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "SignatureMethod", "PLAINTEXT"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "RequestEndpoint", "https://somehost/temporarytokenpath"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "AuthorizationEndpoint", "https://somehost/authorization"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "Callback", "http://somehost/somegsignondoauthcallback"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "TokenEndpoint", "https://somehost/accesstokenpath"); //start the authorization and run the mainloop //any further processing happens in signal callbacks gsignond_plugin_request_initial(plugin, data, token_cache, "oauth1"); g_object_unref(data); g_object_unref(token_cache); g_main_loop_run (main_loop); g_object_unref(plugin); g_main_loop_unref(main_loop); return 0; } |
Example 2. Using OAuth2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
/* PLEASE NOTE: this example is meant for OAuth plugin developers. If you're * an application developer who wants to use this plugin, please refer to * libgsignon-glib documentation here: * http://accounts-sso.gitlab.io/libgsignon-glib */ /* * Copyright (C) 2012 Intel Corporation. * * Contact: Alexander Kanavin <alex.kanavin@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA */ #include <gsignond/gsignond-session-data.h> #include <gsignond/gsignond-plugin-interface.h> #include <gsignond/gsignond-error.h> #include <gsignond/gsignond-utils.h> #include "gsignond-oauth-plugin.h" // this function returns a token for the token cache static GVariant* make_normal_token() { GSignondDictionary* token = gsignond_dictionary_new(); gsignond_dictionary_set_string(token, "AccessToken", "megaaccesstoken"); GDateTime* now = g_date_time_new_now_utc(); gsignond_dictionary_set_int64(token, "Timestamp", g_date_time_to_unix(now)); g_date_time_unref(now); gsignond_dictionary_set_int64(token, "ExpiresIn", 3600); gsignond_dictionary_set_string(token, "RefreshToken", "megarefreshtoken"); gsignond_dictionary_set_string(token, "Scope", "somescope1 somescope2 somescope3"); GVariant* token_var = gsignond_dictionary_to_variant(token); g_object_unref(token); return token_var; } //this function makes a token cache with one unrelated token //(because it belongs to a different client id) static GSignondDictionary* make_token_cache() { GSignondDictionary* tokens = gsignond_dictionary_new(); GSignondDictionary* client_tokens = gsignond_dictionary_new(); gsignond_dictionary_set(client_tokens, "somescope1 somescope2 somescope3", make_normal_token()); gsignond_dictionary_set(tokens, "someotherclient", gsignond_dictionary_to_variant(client_tokens)); g_object_unref(client_tokens); return tokens; } //this callback prints the received token and exits the mainloop static void response_callback(GSignondPlugin* plugin, GSignondSessionData* result, gpointer user_data) { GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(result)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Authenticated successfully, got token:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); g_main_loop_quit(user_data); } //this function prints the content of the updated token cache static void store_callback(GSignondPlugin* plugin, GSignondSessionData* result, gpointer user_data) { GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(result)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Should replace the token cache with the following:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); } //this function shows what the UI interaction component needs to do static void user_action_required_callback(GSignondPlugin* plugin, GSignondSignonuiData* ui_request, gpointer user_data) { // ui_request typically contains a URI that needs to be opened, // and a redirect URI that needs to be 'captured' by the user-agent and // reported back to the plugin // in practice the ui_request needs to be handed over to a user-agent // but here we simply print it GVariant* token_variant = gsignond_dictionary_to_variant(GSIGNOND_DICTIONARY(ui_request)); gchar* token_str = g_variant_print(token_variant, TRUE); g_print("Got a UI interaction request:\n%s\n", token_str); g_free(token_str); g_variant_unref(token_variant); // in practice the following should be received from a user-agent, // but in this example for the sake of simplicity we report the hardcoded redirect // URI (with additional parameters) immidiately back to the plugin GSignondSignonuiData* ui_data = gsignond_signonui_data_new(); gsignond_signonui_data_set_url_response(ui_data, "http://somehost/login.html?state=somerandomstate&code=somerandomcode"); gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_NONE); gsignond_plugin_user_action_finished(plugin, ui_data); g_object_unref(ui_data); } // print an error and exit the mainloop static void error_callback(GSignondPlugin* plugin, GError* error, gpointer user_data) { g_print("Got an error: %s\n", error->message); g_main_loop_quit(user_data); } int main (void) { #if !GLIB_CHECK_VERSION (2, 36, 0) g_type_init (); #endif gpointer plugin = g_object_new(gsignond_oauth_plugin_get_type(), NULL); GMainLoop *main_loop = g_main_loop_new (NULL, FALSE); //connect to various signals of the plugin object g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), main_loop); g_signal_connect(plugin, "user-action-required", G_CALLBACK(user_action_required_callback), NULL); g_signal_connect(plugin, "store", G_CALLBACK(store_callback), NULL); g_signal_connect(plugin, "error", G_CALLBACK(error_callback), main_loop); GSignondSessionData* data = gsignond_session_data_new(); GSignondDictionary* token_cache = make_token_cache(); //fill in necessary data for OAuth2 authorization gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "ClientId", "megaclient"); gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "TokenHost", "somehost"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "TokenPath", "/tokenpath"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "Scope", "Photos Videos"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "AuthHost", "somehost"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "AuthPath", "/somepath"); const gchar *realm_list[] = { "somehost", NULL }; GSequence *allowed_realms = gsignond_copy_array_to_sequence(realm_list); gsignond_session_data_set_allowed_realms(data, allowed_realms); g_sequence_free(allowed_realms); //use authorization code grant for this example as it's the most complex //of those provided in OAuth2 spec gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "ResponseType", "code"); gsignond_dictionary_set_string(GSIGNOND_DICTIONARY(data), "RedirectUri", "http://somehost/login.html"); //start the authorization and run the mainloop //any further processing happens in signal callbacks gsignond_plugin_request_initial(plugin, data, token_cache, "oauth2"); g_object_unref(data); g_object_unref(token_cache); g_main_loop_run (main_loop); g_object_unref(plugin); g_main_loop_unref(main_loop); return 0; } |
Both OAuth1 and OAuth2 are using HTTP requests for authorization. It's possible
to use the following entries in gsignond_plugin_request_initial()
session_data
parameter to influence those requests:
gsignond_session_data_set_network_proxy() provides a HTTP proxy to use. If this parameter is not set, the system proxy configuration is used.
"SslStrict" key whose value is a gboolean. If set to FALSE, then server certificates which are invalid (for example, expired, or self-signed) will not be rejected. If set to TRUE or not set, then server certificates have to be valid.
Where not specified otherwise, parameters are strings.
This parameter contains a cache of previously received tokens in the form of a GSignondDictionary. Tokens are indexed by a ConsumerKey in the dictionary, and each token is itself a GSignondDictionary, with keys and values described below in the token format section.
"ConsumerKey" (mandatory) - the identifier portion of the client credentials (equivalent to a username). Refer to RFC5849 section 3.1
gsignond_session_data_set_ui_policy() (mandatory) - if set to GSIGNOND_UI_POLICY_DEFAULT
a default authorization sequence is used, which may involve re-using a
previously cached token without making any authorization server requests at all.
If set to GSIGNOND_UI_POLICY_REQUEST_PASSWORD
any cached token corresponding
to the ConsumerKey is discarded and the authorization procedure is started
from the beginning.
gsignond_session_data_set_allowed_realms (mandatory) - a list of domains that RequestEndpoint, AuthorizationEndpoint and TokenEndpoint hosts must be in. There authorization sequence will fail if any of the endpoints is not in this list.
"Realm" (optional) - a requested realm for the token, as specified in
RFC5849 section 3.5.1."RequestEndpoint" (mandatory) - a URL that specifies an endpoint used by the plugin to obtain a set of temporary credentials, as specified in
RFC5849 section 2.The endpoint must use HTTPS scheme.
"Callback" (mandatory) - a callback URI where the user is redirected after completing the Resource Owner Authorization step, as specified in
RFC5849 section 2."SignatureMethod" (mandatory) - one of "PLAINTEXT", "HMAC-SHA1", or "RSA-SHA1" - a method used used by the plugin to sign the requests. Specified in RFC5849 section 3.4.
"ConsumerSecret" (optional) - the shared secret portion of the client credentials, used to sign requests to the server when using PLAINTEXT or HMAC-SHA1 signature methods. An empty consumer secret is used if it's not supplied.
"RSAPrivateKey" (mandatory, if RSA-SHA1 signature method is used) - PEM formatted X.509 private key, used to sign requests to the server when using RSA-SHA1 signature methods.
"AuthorizationEndpoint" (mandatory) - Resource Owner Authorization endpoint, to which the user (resource owner) is redirected to grant authorization, as specified in
RFC5849 section 2.gsignond_session_data_set_username() and gsignond_session_data_set_secret()
(optional) - these two parameters may be used when opening the authorization
endpoint URI to initialize corresponding fields on the webpage.
"TokenEndpoint" (mandatory) - a URL that specifies an endpoint used by the plugin to obtain a set of access credentials, as specified in
RFC5849 section 2.gsignond_signonui_data_set_open_url() (mandatory) - a URI that should be opened in a
user-agent (browser) for the user (resource owner) to authenticate herself.
This URI is taken from "AuthorizationEndpoint" parameter of gsignond_plugin_request_initial()
and additional parameters may be appended to the query component.
gsignond_signonui_data_set_final_url() (mandatory) - a URI where the user-agent should
be redirected after a successfull authentication by the resource owner. This
expected URI is taken from the "Callback" parameter of gsignond_plugin_request_initial()
call
to the plugin.The actual (vs. expected) URI may contain additional parameters in the query
component of the URI that are used to continue the authorization process.
gsignond_signonui_data_set_username() and gsignond_signonui_data_set_password()
(optional) - these two parameters may be used when opening the URI to initialize
corresponding fields on the webpage.
gsignond_signonui_data_set_query_error() (mandatory) - indicates if there
was an error in UI interaction and what it was. May be SIGNONUI_ERROR_NONE
(which means no error), SIGNONUI_ERROR_CANCELED
or any other error.
gsignond_signonui_data_get_url_response() (mandatory) - the URI that the user-agent
was redirected to. The callback URI supplied in parameters of
gsignond_plugin_request_initial()
must be a prefix of this URI. The URI also
has to contain parameters in the query component that are necessary to continue
the authorization sequence.
gsignond_plugin_response_final() signal concludes the authorization process and returns a GSignondDictionary parameter that contains the access token and some token parameters:
"AccessToken" (mandatory) - the token itself
"TokenSecret" (mandatory) - the token shared-secret, used by the application to sign requests for protected resources
"Realm" (optional) - the token realm, as specified in
RFC5849 section 3.5.1."ExtraFields" (mandatory) - a GSignondDictionary containing any additional parameters returned by the server together with the access token. This dictionary may be empty, or if it's not, it typically contains service-specific, non-standardized keys and values. This replaces the now deprecated "TokenParameters" parameter.
Where not specified otherwise, parameters are strings.
This parameter contains a cache of previously received tokens in the form of a GSignondDictionary. The keys are tokens' ClientId and values are also GSignondDictionary. Those second-level dictionaries contain token scopes as keys and tokens as values. This two-level approach is done to allow caching several tokens with unrelated scopes per client.
Finally, each token is itself a GSignondDictionary, with keys and values described below in the token format section.
"ClientId" (mandatory) - client identifier as described in
RFC6749 section 2.2."ClientSecret" (optional) - client password as described in
RFC6749 section 2.3.gsignond_session_data_set_ui_policy() (mandatory) - if set to GSIGNOND_UI_POLICY_DEFAULT
a default authorization sequence is used, which may involve re-using a
previously cached token without making any authorization server requests at all.
If set to GSIGNOND_UI_POLICY_REQUEST_PASSWORD
any cached token information
(including a refresh token) corresponding to the ClientId is discarded and
the authorization procedure is started from the beginning.
gsignond_session_data_set_allowed_realms (mandatory) - a list of domains that AuthHost and TokenHost must be in. The authorization sequence will fail if either of the hosts is not in this list.
"Scope" (optional) - a space-separated list of scopes that are requested for the token, as specified in
RFC6749 section 3.3."ForceClientAuthViaRequestBody" (optional) - by default the clients are authenticated via HTTP Basic authorization mechanism, as described in
RFC6749 section 2.3.1.The RFC stipulates that all OAuth 2 servers must support this, however, it was discovered that at least Google and Facebook require client authorization in the request body (which is, according to standard, optional and not recommended). If set to TRUE, this parameter forces this non-compliant client authorization to be used.
"ForceTokenRefresh" (optional) - normally if the token cache contains a suitable token, it is returned immediately. If this parameter is set to TRUE, then a refresh token is always used instead to obtain a new token.
"ResponseType" (mandatory) - should be set to "code" or "token" as described in
RFC6749 section 3.1.1."AuthHost" (mandatory) - hostname component of the authorization endpoint URI, as described in
RFC6749 section 3.1.If it is the equal as "TokenHost", a single "Host" parameter is also possible.
"AuthPath" (mandatory) - pathname component of the authorization endpoint URI, as described in
RFC6749 section 3.1."AuthPort" (optional) - port component of the authorization endpoint URI, as described in
RFC6749 section 3.1.If not specified, standard https port is used.
"AuthQuery" (optional) - query component of the authorization endpoint URI, as described in
RFC6749 section 3.1.This can be used to add provider-specific parameters to the authorization URI. One such parameter is Google's "login_hint" that allows the authorization endpoint pre-fill the login box, or select the proper multi-login session. It is specified at
https://developers.google.com/accounts/docs/OAuth2InstalledApp#formingtheurl. Anothercustom parameter is Facebook's "display", specified at
https://developers.facebook.com/docs/reference/dialogs/oauth/,that affects the way the authorization page looks. Typical values are "page", "popup" and "touch".
"RedirectUri" (optional) - redirection endpoint as described in
RFC6749 section 3.1.2.gsignond_session_data_set_username() and gsignond_session_data_set_secret()
(optional) - these two parameters may be used by UI implementation to
initialize corresponding fields on the webpage when opening the authorization
endpoint URI.
Refer to RFC6749 section 4.3.
"GrantType" (mandatory) - must be set to "password"
gsignond_session_data_set_username() and gsignond_session_data_set_secret()
(mandatory) - resource owner username and password
Refer to RFC6749 section 4.4.
"GrantType" (mandatory) - must be set to "client_credentials"
"TokenHost" (mandatory) - hostname component of the token endpoint URI, as described in
RFC6749 section 3.2.If it is the equal as "AuthHost", a single "Host" parameter is also possible.
"TokenPath" (mandatory) - pathname component of the token endpoint URI, as described in
RFC6749 section 3.2."TokenPort" (optional) - port component of the token endpoint URI, as described in
RFC6749 section 3.2.If not specified, standard https port is used.
"TokenQuery" (optional) - query component of the token endpoint URI, as described in
RFC6749 section 3.2.This signal is issued only when using authorization code grant or implicit code grant flows, and contains the following parameters:
gsignond_signonui_data_set_open_url() (mandatory) - an authorization endpoint URI that should be opened in a
user-agent (browser) for the user (resource owner) to authenticate herself.
This URI is constructed using parameters of gsignond_plugin_request_initial()
and additional parameters may be appended to the query component.
gsignond_signonui_data_set_final_url() (optional) - a redirection endpoint URI where the user-agent should
be redirected after authentication by the resource owner has finished. This
expected URI is taken from the "RedirectUri" parameter of gsignond_plugin_request_initial()
call
to the plugin. The actual (vs. expected) URI may contain additional parameters in the query or fragment
components of the URI that are used to determine the outcome of the authorization process.
gsignond_signonui_data_set_username() and gsignond_signonui_data_set_password()
(optional) - these two parameters may be used when opening the authorization endpoint URI to initialize
corresponding fields on the webpage.
This function is called when UI interaction has completed and only when using authorization code grant or implicit code grant flows.
gsignond_signonui_data_set_query_error() (mandatory) - indicates if there
was an error in UI interaction and what it was. May be SIGNONUI_ERROR_NONE
(which means no error), SIGNONUI_ERROR_CANCELED
or any other error.
gsignond_signonui_data_get_url_response() (mandatory) - the URI that the user-agent
was redirected to. The redirection endpoint URI supplied in parameters of
gsignond_plugin_request_initial()
must be a prefix of this URI. The URI also
has to contain parameters in the query component (if using authorization code grant)
or in the fragment component (if using implicit code grant) that are necessary to continue
the authorization sequence. Specific information is provided at
and RFC6749 section 4.2.2 respectively.
gsignond_plugin_response_final() signal concludes the authorization process and returns a GSignondDictionary parameter that contains the access token and some token parameters:
"AccessToken" (mandatory) - the token itself
"TokenType" (mandatory) - the token type, as specified in
RFC6749 section 7.1.Currently only one token type is supported (the bearer token, standardizied in
RFC6750)."ExtraFields" (mandatory) - a GSignondDictionary containing any additional parameters returned by the server together with the access token. The contents of this parameter is specific to the token type, and for bearer tokens it's empty. This replaces the now deprecated "TokenParameters" parameter.
"Scope" (optional) - the scopes of the issued token, a space separated list as specified in
RFC6749 section 3.3."Timestamp" (mandatory) - a gint64 Unix time specifying the time when token was issued. A Unix time is the number of seconds that have elapsed since 1970-01-01 00:00:00 UTC.
"ExpiresIn" (optional) - the lifetime in seconds of the access token. If specified, the token will expire at Timestamp+ExpiresIn point in time.
"Duration" (optional) - deprecated, replaced by "ExpiresIn" above.
"RefreshToken" (optional) - refresh token as specified in
RFC6749 section 6.This signal is issued by the plugin when the token cache needs to be updated.
The parameter is a GSignondDictionary of tokens. The specific cache format
is same as identity_method_cache
parameter of gsignond_plugin_request_initial()
and is desribed in detail in corresponding OAuth1 and OAuth2 sections.
The token cache should be entirely replaced with the parameter of the signal;
the plugin preserves existing tokens that were supplied to
gsignond_plugin_request_initial()
in identity_method_cache
parameter.
At any point in the authorization process the plugin may issue this signal
with an error
parameter that is a GError. The error
has domain
field set to
GSIGNOND_ERROR
. code
field can be one of GSIGNOND_ERROR_MISSING_DATA
(not enough data was supplied in gsignond_plugin_request_initial()
),
GSIGNOND_ERROR_NOT_AUTHORIZED
(there was an error in the authorization
process), GSIGNOND_ERROR_USER_INTERACTION
(there was an error in the interaction
with the user), GSIGNOND_ERROR_SESSION_CANCELED
(the authorization process
was canceled). message
field tells additional details about the exact cause of the
error, and it's intended to help programming and debugging, but not meant
to be understood by end users directly (although it can be shown to them).