OIDC-Client
view release on metacpan or search on metacpan
lib/OIDC/Client.pm view on Meta::CPAN
build_api_useragent_from_token_value);
use OIDC::Client::Utils qw(reach_data);
our $VERSION = '1.06'; # VERSION: generated by Dist::Zilla::Plugin::OurPkgVersion
=encoding utf8
=head1 NAME
OIDC::Client - OpenID Connect Client
=head1 SYNOPSIS
my $client = OIDC::Client->new(
provider => 'my_provider',
id => 'my_client_id',
secret => 'my_client_secret',
provider_metadata => \%provider_metadata,
log => $app->log,
);
# or...
my $client = OIDC::Client->new(
config => $config_provider,
log => $app->log,
);
my $authorize_url = $client->auth_url();
my $token_response = $client->get_token(code => $code);
my $claims = $client->verify_jwt_token(token => $token);
my $claims = $client->introspect_token(token => $token);
my $userinfo = $client->get_userinfo(access_token => $token);
my $token_response = $client->exchange_token(token => $token, audience => $audience);
my $ua = $client->build_api_useragent();
my $logout_url = $client->logout_url();
=head1 DESCRIPTION
Client module for OpenID Connect and OAuth 2.0 protocols.
Use this module directly from a batch or a simple script. For use from within
an application, you should instead use one of these framework plugins, which
all use this distribution :
=over 2
=item * L<Mojolicious::Plugin::OIDC>
=item * L<Catalyst::Plugin::OIDC>
=item * L<Dancer2::Plugin::OIDC>
=back
=cut
enum 'StoreMode' => [qw/session stash cache/];
enum 'ResponseMode' => [qw/query form_post/];
enum 'GrantType' => [qw/authorization_code client_credentials password refresh_token/];
enum 'ClientAuthMethod' => [qw/client_secret_basic client_secret_post client_secret_jwt private_key_jwt none/];
enum 'TokenValidationMethod' => [qw/jwt introspection/];
with 'OIDC::Client::Role::LoggerWrapper';
with 'OIDC::Client::Role::AttributesManager';
with 'OIDC::Client::Role::ConfigurationChecker';
with 'OIDC::Client::Role::ClaimsValidator';
with 'OIDC::Client::Role::ClientAuthenticationHelper';
=head1 METHODS
=head2 BUILD
Called after the object is created. Makes some basic checks and forces
the retrieval of provider metadata and kid keys.
=cut
sub BUILD {
my $self = shift;
$self->_check_configuration();
$self->_check_audiences_configuration();
$self->_check_cache_configuration();
$self->provider;
$self->id;
$self->provider_metadata;
$self->kid_keys if $self->provider_metadata->{jwks_url};
}
=head2 auth_url( %args )
my $authorize_url = $client->auth_url(%args);
Returns a scalar or a L<Mojo::URL> object containing the initial authorization URL.
This is the URL to use to initiate an authorization code flow.
The optional parameters are:
=over 2
=item response_mode
Defines how tokens are sent by the provider.
Can take one of these values:
=over 2
=item query
Tokens are sent in query parameters.
=item form_post
Tokens are sent in a POST form.
=back
lib/OIDC/Client.pm view on Meta::CPAN
if (my $extra_params = $params{extra_params} || $self->authorize_endpoint_extra_params) {
foreach my $param_name (keys %$extra_params) {
$args{$param_name} = $extra_params->{$param_name};
}
}
my $auth_url = Mojo::URL->new($authorize_url);
$auth_url->query(%args);
return $params{want_mojo_url} ? $auth_url : $auth_url->to_string;
}
=head2 get_token( %args )
my $token_response = $client->get_token(
code => $code,
redirect_uri => q{http://yourapp/oidc/callback},
);
Fetch token(s) from an OAuth2/OIDC provider and returns an
L<OIDC::Client::TokenResponse> object.
This method doesn't perform any verification on the ID token.
Call the L</"verify_jwt_token( %args )"> method to do so.
The optional parameters are:
=over 2
=item grant_type
Specifies how the client wants to interact with the identity provider.
Accepted here : C<authorization_code>, C<client_credentials>, C<password>
or C<refresh_token>.
Can also be specified in the C<token_endpoint_grant_type> configuration entry.
Default to C<authorization_code>.
=item auth_method
Specifies how the client authenticates with the identity provider.
Supported client authentication methods:
=over 2
=item *
client_secret_basic (default)
=item *
client_secret_post
=item *
client_secret_jwt
=item *
private_key_jwt
=item *
none
=back
Can also be specified in the C<token_endpoint_auth_method> configuration entry
or the global C<client_auth_method> configuration entry.
Default to C<client_secret_basic>.
=item code
Authorization-code that is issued beforehand by the identity provider.
Used only for the C<authorization_code> grant-type.
=item redirect_uri
Redirection URI to which the response will be sent.
Can also be specified in the C<signin_redirect_uri> configuration entry.
Used only for the C<authorization_code> grant-type.
=item username / password
User credentials for authorization
Can also be specified in the C<username> and C<password> configuration entries.
Used only the for C<password> grant-type.
=item audience
Specifies the Relaying Party for which the token is intended.
Can also be specified in the C<audience> configuration entry.
Not used for the C<refresh_token> grant-type.
=item scope
Specifies the desired scope of the requested token.
Must be a string with space separators.
Can also be specified in the C<scope> configuration entry.
Not used for the C<authorization_code> nor the C<refresh_token> grant-type.
=item refresh_token
Token that can be used to renew the associated access token before it expires.
Used only for the C<refresh_token> grant-type.
=item refresh_scope
Specifies the desired scope of the requested renewed token.
Must be a string with space separators.
Used only for the C<refresh_token> grant-type.
=back
=cut
sub get_token {
my $self = shift;
my (%params) = validated_hash(
\@_,
lib/OIDC/Client.pm view on Meta::CPAN
=cut
sub verify_token {
my ($self, %params) = @_;
warnings::warnif('deprecated',
'OIDC::Client::verify_token() is deprecated in favor of OIDC::Client::verify_jwt_token()');
return $self->verify_jwt_token(%params);
}
=head2 introspect_token( %args )
my $claims = $client->introspect_token(
token => $token,
token_type_hint => 'access_token',
);
Allows a Resource Server to validate a token and obtain its metadata by calling the provider's
introspection endpoint. Typically used when the access token is opaque (not a JWT).
Throws an L<OIDC::Client::Error::Provider> exception if an error is returned by the provider
or an L<OIDC::Client::Error::TokenValidation> exception if a validation error occurs.
Otherwise, returns the claims.
The parameters are:
=over 2
=item token
The token to validate.
Required.
=item token_type_hint
Hint about the type of the token submitted for introspection.
=item auth_method
Specifies how the client authenticates with the identity provider.
Supported client authentication methods:
=over 2
=item *
client_secret_basic (default)
=item *
client_secret_post
=item *
client_secret_jwt
=item *
private_key_jwt
=item *
none
=back
Can also be specified in the C<introspection_endpoint_auth_method> configuration entry
or the global C<client_auth_method> configuration entry.
Default to C<client_secret_basic>.
=item expected_audience
If the C<aud> claim is present in the provider response of the introspection endpoint,
its value must match the expected audience, otherwise an exception is thrown.
Default to the C<audience> configuration entry or the client id.
=back
=cut
sub introspect_token {
my $self = shift;
my (%params) = validated_hash(
\@_,
token => { isa => 'Str', optional => 0 },
token_type_hint => { isa => enum([qw/access_token refresh_token/]), optional => 1 },
auth_method => { isa => 'ClientAuthMethod', optional => 1 },
expected_audience => { isa => 'Str', optional => 1 },
);
my $introspection_url = $self->provider_metadata->{introspection_url}
or croak("OIDC: introspection_url not found in provider metadata");
my $auth_method = $params{auth_method} || $self->introspection_endpoint_auth_method;
my ($headers, $form) = $self->_build_client_auth_arguments($auth_method, $introspection_url);
$form->{token} = $params{token};
if (my $token_type_hint = $params{token_type_hint}) {
$form->{token_type_hint} = $token_type_hint;
}
$self->log_msg(debug => 'OIDC: calling provider to introspect token');
my $res = $self->user_agent->post($introspection_url, $headers, form => $form)->result;
my $claims = $self->response_parser->parse($res);
$claims->{active}
or OIDC::Client::Error::TokenValidation->throw("OIDC: inactive token");
if (exists $claims->{iss}) {
$self->_validate_issuer($claims->{iss});
}
if (exists $claims->{aud}) {
$self->_validate_audience($claims->{aud}, $params{expected_audience});
}
return $claims;
lib/OIDC/Client.pm view on Meta::CPAN
my $audience_infos = first { $_->{audience} eq $audience } values %$audience_alias
or return;
return $audience_infos->{scope};
}
=head2 exchange_token( %args )
my $exchanged_token_response = $client->exchange_token(
token => $token,
audience => $audience,
);
Exchanges an access token, obtained through OIDC authentication, for another access
token that is accepted by a different OIDC application.
Returns a L<OIDC::Client::TokenResponse> object.
The parameters are:
=over 2
=item token
Content of the valid access token obtained through OIDC authentication.
=item audience
Audience of the target application.
=item scope
Specifies the desired scope of the requested token.
Must be a string with space separators.
Optional.
=item auth_method
Specifies how the client authenticates with the identity provider.
Supported client authentication methods:
=over 2
=item *
client_secret_basic (default)
=item *
client_secret_post
=item *
client_secret_jwt
=item *
private_key_jwt
=item *
none
=back
Can also be specified in the C<token_endpoint_auth_method> configuration entry
or the global C<client_auth_method> configuration entry.
Default to C<client_secret_basic>.
=back
=cut
sub exchange_token {
my $self = shift;
my (%params) = validated_hash(
\@_,
token => { isa => 'Str', optional => 0 },
audience => { isa => 'Str', optional => 0 },
scope => { isa => 'Str', optional => 1 },
auth_method => { isa => 'ClientAuthMethod', optional => 1 },
);
my $token_url = $self->provider_metadata->{token_url}
or croak("OIDC: token url not found in provider metadata");
my $auth_method = $params{auth_method} || $self->token_endpoint_auth_method;
my ($headers, $form) = $self->_build_client_auth_arguments($auth_method, $token_url);
$form->{audience} = $params{audience};
$form->{grant_type} = 'urn:ietf:params:oauth:grant-type:token-exchange';
$form->{subject_token} = $params{token};
$form->{subject_token_type} = 'urn:ietf:params:oauth:token-type:access_token';
if (my $scope = ($params{scope} || $self->get_scope_for_audience($params{audience}))) {
$form->{scope} = $scope;
}
$self->log_msg(debug => 'OIDC: calling provider to exchange token');
my $res = $self->user_agent->post($token_url, $headers, form => $form)->result;
return $self->token_response_parser->parse($res);
}
=head2 build_api_useragent( %args )
my $ua = $client->build_api_useragent();
Invokes the L</"get_token( %args )"> method and builds a web client (L<Mojo::UserAgent>
object) that will have the given access token in the authorization header for each request.
This method can be useful if the client is configured for a password grant
or a client credentials grant and you simply want to build a web client to call
an API protected by OAuth2.
=cut
( run in 0.797 second using v1.01-cache-2.11-cpan-39bf76dae61 )