Lasso Reference Manual | ||||
---|---|---|---|---|
Top | Description |
Synopsis
enum LassoLoginProtocolProfile; struct LassoLogin; LassoLogin * lasso_login_new (LassoServer *server
); LassoLogin * lasso_login_new_from_dump (LassoServer *server
,const gchar *dump
); lasso_error_t lasso_login_accept_sso (LassoLogin *login
); lasso_error_t lasso_login_build_artifact_msg (LassoLogin *login
,LassoHttpMethod http_method
); lasso_error_t lasso_login_build_assertion (LassoLogin *login
,const char *authenticationMethod
,const char *authenticationInstant
,const char *reauthenticateOnOrAfter
,const char *notBefore
,const char *notOnOrAfter
); lasso_error_t lasso_login_build_authn_request_msg (LassoLogin *login
); lasso_error_t lasso_login_build_authn_response_msg (LassoLogin *login
); lasso_error_t lasso_login_build_request_msg (LassoLogin *login
); lasso_error_t lasso_login_build_response_msg (LassoLogin *login
,gchar *remote_providerID
); void lasso_login_destroy (LassoLogin *login
); gchar * lasso_login_dump (LassoLogin *login
); LassoNode * lasso_login_get_assertion (LassoLogin *login
); lasso_error_t lasso_login_init_authn_request (LassoLogin *login
,const gchar *remote_providerID
,LassoHttpMethod http_method
); lasso_error_t lasso_login_init_idp_initiated_authn_request (LassoLogin *login
,const gchar *remote_providerID
); lasso_error_t lasso_login_init_request (LassoLogin *login
,gchar *response_msg
,LassoHttpMethod response_http_method
); gboolean lasso_login_must_ask_for_consent (LassoLogin *login
); gboolean lasso_login_must_authenticate (LassoLogin *login
); lasso_error_t lasso_login_process_authn_request_msg (LassoLogin *login
,const char *authn_request_msg
); lasso_error_t lasso_login_process_authn_response_msg (LassoLogin *login
,gchar *authn_response_msg
); lasso_error_t lasso_login_process_paos_response_msg (LassoLogin *login
,gchar *msg
); lasso_error_t lasso_login_process_request_msg (LassoLogin *login
,gchar *request_msg
); lasso_error_t lasso_login_process_response_msg (LassoLogin *login
,gchar *response_msg
); lasso_error_t lasso_login_validate_request_msg (LassoLogin *login
,gboolean authentication_result
,gboolean is_consent_obtained
);
Description
The Single Sign On process allows a user to log in once to an identity provider (IdP), and to be then transparently loged in to the required service providers (SP) belonging to the IP "circle of trust". Subordinating different identities of the same user within a circle of trust to a unique IP is called "Identity Federation". The liberty Alliance specifications allows, thanks to this federation, strong and unique authentication coupled with control by the user of his personal informations. The explicit user agreement is necessary before proceeding to Identity Federation.
The service provider must implement the following process:
creating an authentication request with
lasso_login_init_authn_request()
;sending it to the identity provider with
lasso_login_build_authn_request_msg()
;-
receiving and processing the answer:
- either an authentication response with
lasso_login_process_authn_response_msg()
- or an artifact with
lasso_login_init_request()
then sending the request to the IdP withlasso_login_build_request_msg()
and processing the new answer withlasso_login_process_response_msg()
.
- either an authentication response with
Our first example shows how to initiate a request toward an ID-FF 1.2 or SAML 2.0 identity
provider. It supposes that we already initialized a LassoServer object with the metadatas or our
provider (and its private key if we want to sign the request), and that we added the metadatas of
the targetted IdP with the method lasso_server_add_provider()
.
Example 1. Service Provider Login URL
LassoLogin *login; int rc; // hold return codes login = lasso_login_new(server); rc = lasso_login_init_authn_request(login, "http://identity-provider-id/", LASSO_HTTP_METHOD_REDIRECT); if (rc != 0) { ... // handle errors, most of them are related to bad initialization } // customize AuthnRequest // protocolProfile is the protocolProfile of the provider http://identity-provider-id/ if (protocolProfile == LASSO_LIBERTY_1_2) { LassoLibAuthnRequest *request = LASSO_LIB_AUTHN_REQUEST(LASSO_PROFILE(login)->request); request->NameIDPolicy = strdup(LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED); request->ForceAuthn = TRUE; request->IsPassive = FALSE; // tell the IdP how to return the response request->ProtocolProfile = strdup(LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART); } else if (protocolProfile == LASSO_SAML_2_0) { LassoSamlp2AuthnRequest *request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(login)->request); if (request->NameIDPolicy->Format) { g_free(request->NameIDPolicy->Format); } request->NameIDPolicy->Format = g_strdup(LASSO_NAME_IDENTIFIER_FORMAT_PERSISTENT); // Allow creation of new federation // request->NameIDPolicy->AllowCreate = 1; request->ForceAuthn = TRUE; request->IsPassive = FALSE; // tell the IdP how to return the response if (request->ProtocolBinding) { g_free(request->ProtocolBinding); } // here we expect an artifact response, it could be post, redirect or PAOS. request->ProtocolBinding = g_strdup(LASSO_SAML2_METADATA_BINDING_ARTIFACT); } // Lasso will choose whether to sign the request by looking at the IdP // metadatas and at our metadatas, but you can always force him to sign or to // not sign using the method lasso_profile_set_signature_hint() on the // LassoLogin object. rc = lasso_login_build_authn_request_msg(login); if (rc != 0) { .... // handle errors // could be that the requested binding (POST, Redirect, etc..) is not supported (LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE) // or that we could not sign the request (LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED). } // redirect user to identity provider // we chose the Redirect binding, so we have to generate a redirect HTTP response to the URL returned by Lasso printf("Location: %s\n\nRedirected to IdP\n", LASSO_PROFILE(login)->msg_url);
Next example shows how to receive the response from the identity provider for ID-FF 1.2.
Example 2. Service Provider Assertion Consumer Service URL for ID-FF 1.2
LassoLogin *login; char *request_method = getenv("REQUEST_METHOD"); char *artifact_msg = NULL, *lares = NULL, *lareq = NULL; char *name_identifier; lassoHttpMethod method; int rc = 0; login = lasso_login_new(server); if (strcmp(request_method, "GET") == 0) { artifact_msg = getenv("QUERY_STRING"); method = LASSO_HTTP_METHOD_REDIRECT; } else { // read submitted form; if it has a LAREQ field, put it in lareq, // if it has a LARES field, put it in lares if (lareq) { artifact_msg = lareq; } else if (lares) { response_msg = lares; } else { // bail out } method = LASSO_HTTP_METHOD_POST; } if (artifact_msg) { // we received an artifact response, // it means we did not really receive the response, // only a token to redeem the real response from the identity // provider through a SOAP resolution call rc = lasso_login_init_request(login, artifact_msg, method); if (rc != 0) { ... // handle errors // there is usually no error at this step, only // if the IdP response is malformed } rc = lasso_login_build_request_msg(login); if (rc != 0) { ... // handle errors // as for AuthnRequest generation, it generally is caused // by a bad initialization like an impossibility to load // the private key. } // makes a SOAP call, soap_call is NOT a Lasso function soap_answer_msg = soap_call(LASSO_PROFILE(login)->msg_url, LASSO_PROFILE(login)->msg_body); rc = lasso_login_process_response_msg(login, soap_answer_msg); if (rc != 0) { ... // handle errors // here you can know if the IdP refused the request, } } else if (response_msg) { lasso_login_process_authn_response_msg(login, response_msg); } // looks up name_identifier in local file, database, whatever and gets back // two things: identity_dump and session_dump name_identifier = LASSO_PROFILE(login)->nameIdentifier lasso_profile_set_identity_from_dump(LASSO_PROFILE(login), identity_dump); lasso_profile_set_session_from_dump(LASSO_PROFILE(login), session_dump); lasso_login_accept_sso(login); if (lasso_profile_is_identity_dirty(LASSO_PROFILE(login))) { LassoIdentity *identity; char *identity_dump; identity = lasso_profile_get_identity(LASSO_PROFILE(login)); identity_dump = lasso_identity_dump(identity); // record identity_dump in file, database... } if (lasso_profile_is_session_dirty(LASSO_PROFILE(login))) { LassoSession *session; char *session_dump; session = lasso_profile_get_session(LASSO_PROFILE(login)); session_dump = lasso_session_dump(session); // record session_dump in file, database... } // redirect user anywhere printf("Location: %s\n\nRedirected to site root\n", login->msg_url);
The implement an IdP you must create a single sign-on service endpoint, the needed APIs for
this are lasso_login_process_authn_request_msg()
, lasso_login_validate_request_msg()
,
lasso_login_build_assertion()
, lasso_login_build_authn_response_msg()
and
lasso_login_build_artifact_msg()
. You will have to chose between
lasso_login_build_authn_response_msg()
and lasso_login_build_artifact_msg()
depending on the
requested protocol for the response by the service provider
Example 3. Identity provider single sign-on service
LassoLogin *login; char *request_method = getenv("REQUEST_METHOD"); char *artifact_msg = NULL, *lares = NULL, *lareq = NULL; char *name_identifier; lassoHttpMethod method; int rc = 0; login = lasso_login_new(server); if (strcmp(request_method, 'GET')) { // AuthnRequest send with the HTTP-Redirect binding // lasso_profile_set_signature_verify_hint(LASSO_PROFILE(login), LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE); rc = lasso_process_authn_request_msg(login, getenv("QUERY_STRING")); if (rc != 0) { // handle errors } } else {
Details
enum LassoLoginProtocolProfile
typedef enum { LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART = 1, LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST, LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP, LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT, } LassoLoginProtocolProfile;
Identifies the four possible profiles for Single Sign-On and Federation. It defined how the response to authentication request will transmitted to the service provider.
response is transmitted through a redirect request with an artifact, followed by an artifact resolution request by the service provider. | |
response is transmitted through a POST. | |
response is transmitted in a PAOS response (see LassoLecp). | |
response is transmitted through a redirect. |
struct LassoLogin
struct LassoLogin { LassoProfile parent; LassoLoginProtocolProfile protocolProfile; gchar *assertionArtifact; };
Single sign-on profile for the current transaction; possibly an assertionArtifact to be used by the service provider in its "assertionConsumerServiceURL" and the assertion created or received for the principal.
LassoProfile |
|
LassoLoginProtocolProfile |
the kind of binding used for this authentication request. |
gchar * |
a string representing the artifact received through an artifact resolution. request |
lasso_login_new ()
LassoLogin * lasso_login_new (LassoServer *server
);
Creates a new LassoLogin.
|
the LassoServer |
Returns : |
a newly created LassoLogin object; or NULL if an error occured |
lasso_login_new_from_dump ()
LassoLogin * lasso_login_new_from_dump (LassoServer *server
,const gchar *dump
);
Restores the dump
to a new LassoLogin.
|
the LassoServer |
|
XML login dump |
Returns : |
a newly created LassoLogin; or NULL if an error occured. |
lasso_login_accept_sso ()
lasso_error_t lasso_login_accept_sso (LassoLogin *login
);
Gets the assertion of the response and adds it to the LassoSession object. Builds a federation with the 2 name identifiers of the assertion and adds it into the identity. If the session or the identity are NULL, they are created.
|
a LassoLogin |
Returns : |
0 on success; or
|
lasso_login_build_artifact_msg ()
lasso_error_t lasso_login_build_artifact_msg (LassoLogin *login
,LassoHttpMethod http_method
);
Builds a SAML artifact. Depending of the HTTP method, the data for the sending of
the artifact are stored in msg_url
(REDIRECT) or msg_url
, msg_body
and
msg_relayState
(POST).
|
a LassoLogin |
|
the HTTP method to send the artifact (REDIRECT or POST) |
Returns : |
0 on success; or
|
lasso_login_build_assertion ()
lasso_error_t lasso_login_build_assertion (LassoLogin *login
,const char *authenticationMethod
,const char *authenticationInstant
,const char *reauthenticateOnOrAfter
,const char *notBefore
,const char *notOnOrAfter
);
Builds an assertion and stores it in profile session.
authenticationInstant
, reauthenticateOnOrAfter, notBefore
and
notOnOrAfter
may be NULL. If authenticationInstant
is NULL, the current
time will be used. Time values must be encoded in UTC.
Construct the authentication assertion for the response. It must be called after validating the
request using lasso_login_validate_request_msg()
. The created assertion is accessed using
lasso_login_get_assertion()
.
|
a LassoLogin |
|
the authentication method |
|
the time at which the authentication took place |
|
the earliest time instant at which the assertion is valid |
|
the time instant at which the assertion has expired |
Returns : |
0 on success; or
|
lasso_login_build_authn_request_msg ()
lasso_error_t lasso_login_build_authn_request_msg (LassoLogin *login
);
Converts profile authentication request (request
member) into a Liberty message, either an URL
in HTTP-Redirect profile or an URL and a field value in Browser-POST (form) profile.
The URL is set into the msg_url
member and the eventual field value (LAREQ) is set into the
msg_body
member.
|
a LassoLogin |
Returns : |
0 on success; or
|
lasso_login_build_authn_response_msg ()
lasso_error_t lasso_login_build_authn_response_msg
(LassoLogin *login
);
Converts profile authentication response (response
member) into a Liberty
message.
The URL is set into the msg_url
member and the field value (LARES) is set
into the msg_body
member.
|
a LassoLogin |
Returns : |
0 on success; or
|
lasso_login_build_request_msg ()
lasso_error_t lasso_login_build_request_msg (LassoLogin *login
);
Produce a SOAP Artifact Resolve message. It must follows a call to
lasso_login_init_request()
on the artifact message.
Converts artifact request into a Liberty SOAP message.
The URL is set into the msg_url
member and the SOAP message is set into the
msg_body
member. You should POST the msg_body
to the msg_url
afterward.
|
a LassoLogin |
Returns : |
0 on success; or LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a LassoLogin object, LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if not remote provider ID was setup -- it usually means that lasso_login_init_request was not called before, LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the remote provider ID is not registered in the server object. |
lasso_login_build_response_msg ()
lasso_error_t lasso_login_build_response_msg (LassoLogin *login
,gchar *remote_providerID
);
Converts profile assertion response (response
member) into a Liberty SOAP
messageresponse message.
The URL is set into the msg_url
member and the SOAP message is set into the
msg_body
member.
|
a LassoLogin |
|
service provider ID |
Returns : |
0 on success; or a negative value otherwise.
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a LassoLogin object,
LASSO_PROFILE_ERROR_SESSION_NOT_FOUND if no session object was found in the login profile object
-- it should be created by lasso_login_build_assertion() if you did not set it manually before
calling lasso_login_build_assertion() . |
lasso_login_destroy ()
void lasso_login_destroy (LassoLogin *login
);
Destroys a LassoLogin object.
Deprecated
: Since 2.2.1, use g_object_unref()
instead.
|
a LassoLogin |
lasso_login_dump ()
gchar * lasso_login_dump (LassoLogin *login
);
Dumps login
content to an XML string.
|
a LassoLogin |
Returns : |
the dump string. It must be freed by the caller. [transfer full] |
lasso_login_get_assertion ()
LassoNode * lasso_login_get_assertion (LassoLogin *login
);
Return the last build assertion.
|
a LassoLogin object |
Returns : |
a LassoNode representing the build assertion (generally a LassoSamlAssertion when using ID-FF 1.2 or a LassoSaml2Assertion when using SAML 2.0) |
lasso_login_init_authn_request ()
lasso_error_t lasso_login_init_authn_request (LassoLogin *login
,const gchar *remote_providerID
,LassoHttpMethod http_method
);
Initializes a new AuthnRequest from current service provider to remote
identity provider specified in remote_providerID
(if NULL the first known
identity provider is used).
For ID-FF 1.2 the default NameIDPolicy in an AuthnRequest is None, which imply that a federation must already exist on the IdP side.
For SAML 2.0 the default NameIDPolicy is the first listed in the metadatas of the current provider, or if none is specified, Transient, which ask the IdP to give a one-time federation
|
a LassoLogin |
|
the providerID of the identity provider (may be NULL) |
|
HTTP method to use for request transmission. [default LASSO_HTTP_METHOD_REDIRECT] |
Returns : |
0 on success; or
|
lasso_login_init_idp_initiated_authn_request ()
lasso_error_t lasso_login_init_idp_initiated_authn_request (LassoLogin *login
,const gchar *remote_providerID
);
Generates an authentication response without matching authentication request.
The choice of NameIDFormat is the same as for lasso_login_init_authn_request()
but with the
target remote_providerID
as the current provider
If remote_providerID
is NULL, the first known provider is used.
|
a LassoLogin. |
|
the providerID of the remote service provider (may be NULL) |
Returns : |
0 on success; or a negative value otherwise. Error codes are the same as
lasso_login_init_authn_request() . |
lasso_login_init_request ()
lasso_error_t lasso_login_init_request (LassoLogin *login
,gchar *response_msg
,LassoHttpMethod response_http_method
);
Initializes an artifact request. response_msg
is either the query string
(in redirect mode) or the form LAREQ field (in browser-post mode).
It should only be used if you received an artifact message, response_msg
must be content of the
artifact field for the POST artifact binding of the query string for the REDIRECT artifact
binding. You must set the response_http_method
argument according to the way you received the
artifact message.
|
a LassoLogin |
|
the authentication response received |
|
the method used to receive the authentication response |
Returns : |
0 on success; or
|
lasso_login_must_ask_for_consent ()
gboolean lasso_login_must_ask_for_consent (LassoLogin *login
);
Evaluates if consent must be asked to the Principal to federate him.
|
a LassoLogin |
Returns : |
TRUE if consent must be asked |
lasso_login_must_authenticate ()
gboolean lasso_login_must_authenticate (LassoLogin *login
);
Evaluates if user must be authenticated.
|
a LassoLogin |
Returns : |
TRUE if user must be authenticated |
lasso_login_process_authn_request_msg ()
lasso_error_t lasso_login_process_authn_request_msg (LassoLogin *login
,const char *authn_request_msg
);
Processes received authentication request, checks it is signed correctly, checks if requested protocol profile is supported, etc.
|
a LassoLogin |
|
the authentication request received |
Returns : |
0 on success; or
|
lasso_login_process_authn_response_msg ()
lasso_error_t lasso_login_process_authn_response_msg (LassoLogin *login
,gchar *authn_response_msg
);
Processes received authentication response.
|
a LassoLogin |
|
the authentication response received |
Returns : |
0 on success; or a negative value otherwise. |
lasso_login_process_paos_response_msg ()
lasso_error_t lasso_login_process_paos_response_msg (LassoLogin *login
,gchar *msg
);
lasso_login_process_request_msg ()
lasso_error_t lasso_login_process_request_msg (LassoLogin *login
,gchar *request_msg
);
Processes received artifact request.
|
a LassoLogin |
|
the artifact request received |
Returns : |
0 on success; or a negative value otherwise. |
lasso_login_process_response_msg ()
lasso_error_t lasso_login_process_response_msg (LassoLogin *login
,gchar *response_msg
);
Processes received assertion response.
|
a LassoLogin |
|
the assertion response received |
Returns : |
0 on success; or
|
lasso_login_validate_request_msg ()
lasso_error_t lasso_login_validate_request_msg (LassoLogin *login
,gboolean authentication_result
,gboolean is_consent_obtained
);
Initializes a response to the authentication request received.
|
a LassoLogin |
|
whether user has authenticated succesfully |
|
whether user consent has been obtained |
Returns : |
0 on success; or
|