digitoimistodude / avoine-sso-login
Integrate login to Avoine SSO.
Package info
github.com/digitoimistodude/avoine-sso-login
Type:wordpress-plugin
pkg:composer/digitoimistodude/avoine-sso-login
Requires (Dev)
This package is auto-updated.
Last update: 2026-08-06 14:29:48 UTC
README
Note
Please note: this is a developer oriented plugin. It has no settings screen and does nothing on its own, so it is not a download-and-activate plugin. It expects a developer to configure the credentials, call the login URL from a theme template and add the site specific membership checks with filters.
The plugin is not distributed in the WordPress plugin directory and is provided as is. Contributions are welcome: send a pull request, issue, or email koodarit@dude.fi.
Avoine SSO Login WordPress plugin
Integrates Avoine Sense SSO with WordPress. Users authenticate against the Avoine SSO service, and the plugin creates and maintains a shadow WordPress user for each of them. Shadow users cannot log in with a WordPress password and cannot reset one.
A persistent object cache (Object Cache Pro, Redis Object Cache, memcached or similar) is strongly recommended. SSO user activity checks are stored in WP_Object_Cache, and without a persistent backend every request that checks activity calls the Avoine API again.
Requirements
- WordPress 5.0 or newer
- PHP 8.0 or newer
- An Avoine Sense service ID and communications key, provided by Vitec Avoine
Setup
The plugin reads its configuration from two environment variables.
AVOINE_SSO_SERVICE_IDis the ID for the SSO serviceAVOINE_SSO_KEYis the communications key for the SSO service
Important
Both are read with getenv(). Defining them as PHP constants with define() in wp-config.php does not work. On Bedrock style installs put them in .env, and note that phpdotenv v5 createImmutable() populates $_ENV and $_SERVER but not getenv().
If real environment variables are not available, set the values with the avoine_sso_login\service\id and avoine_sso_login\api\key filters in a mu-plugin instead:
add_filter( 'avoine_sso_login\service\id', function() { return 'your-service-id'; } ); add_filter( 'avoine_sso_login\api\key', function() { return 'your-communications-key'; } );
When the credentials are missing, avoine_sso_get_login_url() returns false and the login link renders empty without any error message.
Once the credentials are in place, render a login link from a page template:
<a href="<?php echo esc_url( avoine_sso_get_login_url( home_url( '/members/' ) ) ); ?>"> <?php esc_html_e( 'Log in', 'textdomain' ); ?> </a>
By default every SSO user is treated as active. Membership and access rules are site specific, so add them with the avoine_sso_login\login\user_is_active and avoine_sso_login\user\is_active filters.
Auth flow
Login
- User is sent to log in url get with
avoine_sso_get_login_urlfunction - From SSO service, user is redirected back to WP
- Existence for SSO user is checked
- User activity checks are done if added any via filters
- If user does not exist, new shadow WP user is created
- If user exists, shadow WP user details are updated
- User is redirected to url that was specified when getting login url, defaults to home
- Every two days, if not altered via hook, user activity is checked
Logout
- When logging out, user is sent to logout url by using
avoine_sso_get_logout_urlfunction - SSO service calls domain.fi/sso-logout which still has the WP shadow user logged in
- WP shadow user is logged out with default WP logout functions and actions
Functions
These are the only functions a theme or another plugin should call.
avoine_sso_get_login_url( string $return_url = null ) : string|false
Returns the SSO login url. The optional parameter is the url the user is redirected to after a successful login, defaulting to home_url(). Returns false if the service ID is not configured.
avoine_sso_get_logout_url() : string|false
Returns the SSO logout url.
avoine_is_sso_user( int $user_id = null ) : bool
Whether the user logged in through SSO. Defaults to the current user.
avoine_is_sso_user_active( int $user_id = null ) : bool
Whether the user is still active according to SSO data. Defaults to the current user. Returns false for users that did not log in through SSO. The result is stored in the object cache.
Filters
Setup
apply_filters( 'avoine_sso_login\service\id', string $service_id )
The SSO service ID. Defaults to the AVOINE_SSO_SERVICE_ID environment variable.
apply_filters( 'avoine_sso_login\api\key', string $api_key )
The SSO communications key. Defaults to the AVOINE_SSO_KEY environment variable.
apply_filters( 'avoine_sso_login\service\domain', string $domain )
The SSO service domain. Defaults to tunnistus.avoine.fi.
apply_filters( 'avoine_sso_login\api\url', string $api_url )
The full SSO API endpoint. Defaults to https://{$domain}/mmserver.
apply_filters( 'avoine_sso_login\login\return_url', string $return_url )
Where the user is sent after a successful login. Overrides the value passed to avoine_sso_get_login_url().
apply_filters( 'avoine_sso_login\logout\url', string $logout_url )
The SSO logout url. Defaults to https://{$domain}/sso-logout/.
apply_filters( 'avoine_sso_login\failed\redirect_url', string $redirect_url )
Where the user is sent when the login fails. Defaults to wp_login_url().
Auth flow
apply_filters( 'avoine_sso_login\login\user_is_active', bool $active, object $sso_user, object $sso_user_info )
Whether the SSO user is allowed to log in. Defaults to true, so every SSO user is accepted until you implement your own membership rules here.
apply_filters( 'avoine_sso_login\logout\message', string $message )
The message shown if the SSO logout page becomes visible to the user.
User creation
apply_filters( 'avoine_sso_login\user\create\user_login', string $user_login, object $sso_user, object $sso_user_info )
The user_login for the shadow user. Defaults to a unix timestamp combined with the SSO local ID.
apply_filters( 'avoine_sso_login\user\create', array $userdata, object $sso_user, object $sso_user_info )
All data passed to wp_insert_user() when the shadow user is created.
User data
apply_filters( 'avoine_sso_login\user\create\user_email\use_original', bool $use_original )
Whether the real email address from SSO is used for the shadow user. Defaults to false, in which case a generated address on the site domain is used.
apply_filters( 'avoine_sso_login\user\data', array $userdata, object $sso_user, object $sso_user_info )
The data passed to both wp_insert_user() and wp_update_user().
apply_filters( 'avoine_sso_login\user\mapping_id', string $mapping_id, object $sso_user, object $sso_user_info )
The unique identifier used to match an SSO user to a shadow user. Defaults to $sso_user->local_id.
User activity
apply_filters( 'avoine_sso_login\user\is_active', bool $active, int $wp_user_id, string $ssoid, object $sso_user_info )
Whether the user is still active, evaluated when avoine_is_sso_user_active() is called and the status is not cached. Defaults to true.
apply_filters( 'avoine_sso_login\user\is_active\expiration', int $expiration )
Cache lifetime for the activity check in seconds. Defaults to two days, or whatever the WordPress auth_cookie_expiration filter returns.
Actions
Auth flow
do_action( 'avoine_sso_login\succes\auth\before', WP_User $wp_user, object $sso_user )
The SSO user has been validated and the shadow user resolved, but is not logged in yet.
do_action( 'avoine_sso_login\succes\auth\after', WP_User $wp_user, object $sso_user )
The shadow user has been logged in.
do_action( 'avoine_sso_login\login\user_is_active\after', object $sso_user, object $sso_user_info )
The login time activity check has been done.
do_action( 'avoine_sso_login\failed' )
The login failed after a valid SSO redirect was captured.
do_action( 'avoine_sso_login\logout\after' )
The SSO service called the logout url and the shadow user has been logged out.
User creation
do_action( 'avoine_sso_login\user\create\before', object $sso_user, object $sso_user_info )
A new shadow user is about to be created.
do_action( 'avoine_sso_login\user\create\after', int $new_user_id, object $sso_user, object $sso_user_info )
A new shadow user has been created.
User activity
do_action( 'avoine_sso_login\user\is_active\after', int $wp_user_id, bool $active )
An activity check has been done outside the login flow.
User action preventions
do_action( 'avoine_sso_login\user\prevented_wp_login' ) do_action( 'avoine_sso_login\user\prevented_password_reset' ) do_action( 'avoine_sso_login\user\prevented_password_reset\email' )
A shadow user tried to log in with a WordPress password, reset their WordPress password, or would have been sent a password change email.
Legacy hook names
Every hook above has an older alias from the 1.x series. They still fire, but new code should use the namespaced names.
avoine_sso_service_id // avoine_sso_login\service\id avoine_sso_communications_key // avoine_sso_login\api\key avoine_sso_login_return_url // avoine_sso_login\login\return_url avoine_sso_logout_url // avoine_sso_login\logout\url avoine_sso_login_redirect_failed // avoine_sso_login\failed\redirect_url avoine_sso_logout_message // avoine_sso_login\logout\message avoine_sso_login_check_is_user_active // avoine_sso_login\login\user_is_active avoine_after_login_check_sso_is_user_active // avoine_sso_login\login\user_is_active\after avoine_sso_create_userdata // avoine_sso_login\user\create avoine_sso_after_create_user // avoine_sso_login\user\create\after avoine_sso_user_mapping_id // avoine_sso_login\user\mapping_id avoine_sso_is_user_active // avoine_sso_login\user\is_active avoine_sso_is_user_active_expiration // avoine_sso_login\user\is_active\expiration avoine_after_sso_is_user_active // avoine_sso_login\user\is_active\after avoine_sso_before_sso_login // avoine_sso_login\succes\auth\before avoine_sso_login // avoine_sso_login\succes\auth\after avoine_sso_after_logout // avoine_sso_login\logout\after avoine_sso_login_failed // avoine_sso_login\failed