NAME
Mojolicious::Plugin::Authentication::OIDC - OpenID Connect
implementation integrated into Mojolicious
SYNOPSIS
$self->plugin('Authentication::OIDC' => {
client_secret => '...',
well_known_url => 'https://idp/realms/master/.well-known/openid-configuration',
public_key => "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
});
# in controller
say "Hi " . $c->current_user->firstname;
use Array::Utils qw(intersect);
if(intersect($c->current_user_roles->@*, qw(admin))) { ... }
DESCRIPTION
Mojolicious plugin for OpenID Connect
authentication.
Designed to work with an OpenID Connect provider like Keycloak, in
confidential access mode. Its design goal is to be configured "all at
once" and then little-to-no effort should be needed to support it
elsewhere -- this is largely achieved via hooks ("on_success",
"on_error", "on_login", "on_activity") and handlers ("get_token",
"get_user", "get_roles")
Controller actions "OpenIDConnect#redirect" and "OpenIDConnect#login"
are registered, and can be mapped to routes implicitly (see
"make_routes") or manually routed to (e.g., via
Mojolicious::Plugin::OpenAPI).
For the auth workflow, clients should be sent to
"OpenIDConnect#redirect" (via "redirect_path" if "make_routes" is
enabled). Once the client authenticates to the identity server, they'll
be sent to "OpenIDConnect#login" (via "login_path", again, if
"make_routes" is enabled). Upon successful login, the "on_login" hook
will be called, followed by the "on_success" hook, which should send the
client to a post-login page. Then, on every server access on/after
login, the "on_activity" hook will be called.
Controllers may get information about the logged in user via the
"current_user" and "current_user_roles" helper methods.
METHODS
Mojolicious::Plugin::Authentication::OIDC inherits all methods from
Mojolicious::Plugin and implements the following new ones
register( \%params )
Register plugin in Mojolicious application, including registering
Mojolicious::Plugin::Authentication::OIDC::Controller::OpenIDConnect as
a Mojolicious controller.
Configuration is done via the "\%params" HashRef, given the following
keys
make_routes
Optional
A flag to indicate whether routes should be registered for
"redirect_path" and "login_path" pointing to "redirect" in
Mojolicious::Plugin::Authentication::OIDC::Controller::OpenIDConnect and
"login" in
Mojolicious::Plugin::Authentication::OIDC::Controller::OpenIDConnect,
respectively. Set to false if you are handling these routes some other
way, for instance in a Mojolicious::PLugin::OpenAPI spec.
Default: true
client_id
Optional
The application's unique identifier, to the auhorization server
Default: the application moniker (lowercase)
client_secret
Required
A secret value known to the authorization server, specific to this
application
well_known_url
Required
A discovery endpoint that informs the application of the authorization
server's specific configuration and capabilities
Example:
"https://idp.domain.com/realms/master/.well-known/openid-configuration"
public_key
Required
The RSA public key corresponding to the private key with which the
authorization tokens are signed by the authorization server. Format is a
PEM/DER/JWT string accepted by "decode_jwt" in Crypt::JWT's "key"
parameter.
redirect_path
Optional
The path for the route which redirects users to the authorization
server. Only used when "make_routes" is enabled, for configuring the
path of that route.
Default: "/auth"
login_path
Optional
The path section of the URL to be used as the OIDC "redirect_uri". The
full URL will be constructed based on the scheme/host/port of the
request. This path is also used for route registration if "make_routes"
is enabled.
Default: "/auth/login"
get_user ( $token )
Optional
A callback that's given the auth token data as its only argument. It
should return the application's "user" instance corresponding to that
data (e.g., a database record object), creating any references as
necessary.
Default: Simply returns the auth token data as a HashRef
get_token ( $controller )
Optional
A callback that's given a Mojolicious controller as its only argument.
It should return the encoded authorization token. This allows the
application to choose where and how the token is stored on the client
side and sent to the server.
Default: returns the "token" value of the Mojo session
get_roles ( $user, $token )
Optional
Given a "user" instance (produced by "get_user") and a decoded
authorization token as arguments, returns an ArrayRef of roles
pertaining to that user.
Default: returns an empty ArrayRef
role_map (%map)
Optional
A mapping of external roles (e.g., from Authorization Server) to
internal roles used by the application's authorization framework. If
this option is specified, roles not present in its keys are deleted, all
others will be mapped.
on_login ( $controller, $user )
Optional
A hook to allow the application to respond to a successful user login,
such as updating the user's "last_login" date.
Default: "undef"
on_activity ( $controller, $user )
Optional
A hook to allow the application to respond to any request by a logged-in
user, such as updating the user's "last_activity" date.
Default: "undef"
on_success ( $controller, $token )
Optional
A hook invoked when the user's authorization request succeeds. This code
should address storage of the authentication token on the frontend.
Default: Stores the (encrypted) token in the "token" key of the Mojo
session and redirects to "/login/success"
on_error
Optional
A hook invoked when the user's authorization request fails.
Default: renders the Authorization Server's response (JSON)
current_user
Returns the user record (from "get_user") for the currently logged in
user. If no user is logged in, or any failure occurs in reading their
access token, returns "undef"
current_user_roles
If a user is logged in, returns their roles (as determined by
"get_roles"). Otherwise, returns "undef"
AUTHOR
Mark Tyrrell ""
LICENSE
Copyright (c) 2024 Mark Tyrrell
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.