Authen-SCRAM
view release on metacpan or search on metacpan
$client->validate( $server_final );
}
catch {
die "Authentication failed!"
};
### SERVER SIDE ###
$server = Authen::SCRAM::Server->new(
credential_cb => \&get_credentials,
);
$username = try {
# get client-first-message
$server_first = $server->first_msg( $client_first );
# send to client and get client-final-message
$server_final = $server->final_msg( $client_final );
lib/Authen/SCRAM.pm view on Meta::CPAN
$client->validate( $server_final );
}
catch {
die "Authentication failed!"
};
### SERVER SIDE ###
$server = Authen::SCRAM::Server->new(
credential_cb => \&get_credentials,
);
$username = try {
# get client-first-message
$server_first = $server->first_msg( $client_first );
# send to client and get client-final-message
$server_final = $server->final_msg( $client_final );
lib/Authen/SCRAM/Client.pm view on Meta::CPAN
#pod =cut
has minimum_iteration_count => (
is => 'ro',
isa => Num,
default => 4096,
);
# The derived PBKDF2 password can be reused if the salt and iteration count
# is the same as a previous authentication conversation.
has _cached_credentials => (
is => 'rw',
default => sub { [ "", 0, "" ] }, # salt, iterations, derived password
);
#--------------------------------------------------------------------------#
# provided by Authen::SCRAM::Role::Common
#--------------------------------------------------------------------------#
with 'Authen::SCRAM::Role::Common';
lib/Authen/SCRAM/Client.pm view on Meta::CPAN
return $self->_join_reply(qw/c r p/);
}
#pod =method validate
#pod
#pod $client->validate( $server_final_msg );
#pod
#pod This takes the C<server-final-message> character string received from the
#pod server and verifies that the server actually has a copy of the client
#pod credentials. It will return true if valid and throw an exception, otherwise.
#pod
#pod =cut
sub validate {
my ( $self, $s_final_msg ) = @_;
my (@params) = $s_final_msg =~ $self->_server_final_re;
$self->_parse_to_session(@params);
if ( my $err = $self->_get_session("e") ) {
lib/Authen/SCRAM/Client.pm view on Meta::CPAN
#pod authenticate.
#pod
#pod This method caches the computed values -- it generates them fresh only if
#pod the supplied salt and iteration count don't match the cached salt and
#pod iteration count.
#pod
#pod =cut
sub computed_keys {
my ( $self, $salt, $iters ) = @_;
my $cache = $self->_cached_credentials;
if ( $cache->[0] eq $salt && $cache->[1] == $iters ) {
# return stored key, client key, server key
return @{$cache}[ 2 .. 4 ];
}
my $salted_pw =
derive( $self->digest, encode_utf8( $self->_prepped_pass ), $salt, $iters );
my $client_key = $self->_hmac_fcn->( $salted_pw, "Client Key" );
my $server_key = $self->_hmac_fcn->( $salted_pw, "Server Key" );
my $stored_key = $self->_digest_fcn->($client_key);
$self->_cached_credentials(
[ $salt, $iters, $stored_key, $client_key, $server_key ] );
return ( $stored_key, $client_key, $server_key );
}
1;
# vim: ts=4 sts=4 sw=4 et:
lib/Authen/SCRAM/Client.pm view on Meta::CPAN
server and returns the C<client-final-message> character string containing the
authentication proof to be sent to the server. This will throw an exception
should an error occur.
=head2 validate
$client->validate( $server_final_msg );
This takes the C<server-final-message> character string received from the
server and verifies that the server actually has a copy of the client
credentials. It will return true if valid and throw an exception, otherwise.
=head2 computed_keys
This method returns the opaque keys used in the SCRAM protocol. It returns
the 'stored key', the 'client key' and the 'server key'. The server must
have a copy of the stored key and server key for a given user in order to
authenticate.
This method caches the computed values -- it generates them fresh only if
the supplied salt and iteration count don't match the cached salt and
lib/Authen/SCRAM/Server.pm view on Meta::CPAN
#pod $server_final_msg = $server->final_msg( $client_final_msg );
#pod
#pod This takes the C<client-final-message> received from the client and returns the
#pod C<server-final-message> string containing the verification signature to be sent
#pod to the client.
#pod
#pod If an authorization identity was provided by the client, it will confirm that
#pod the authenticating username is authorized to act as the authorization id using
#pod the L</auth_proxy_cb> attribute.
#pod
#pod If the client credentials do not match or the authentication name is not
#pod authorized to act as the authorization name, then an exception will be thrown.
#pod
#pod =cut
sub final_msg {
my ( $self, $msg ) = @_;
my ( $c2wop, @params ) = $msg =~ $self->_client_final_re;
$self->_set_session( _c2wop => $c2wop );
lib/Authen/SCRAM/Server.pm view on Meta::CPAN
=head1 VERSION
version 0.011
=head1 SYNOPSIS
use Authen::SCRAM::Server;
use Try::Tiny;
$server = Authen::SCRAM::Server->new(
credential_cb => \&get_credentials,
);
$username = try {
# get client-first-message
$server_first = $server->first_msg( $client_first );
# send to client and get client-final-message
$server_final = $server->final_msg( $client_final );
lib/Authen/SCRAM/Server.pm view on Meta::CPAN
$server_final_msg = $server->final_msg( $client_final_msg );
This takes the C<client-final-message> received from the client and returns the
C<server-final-message> string containing the verification signature to be sent
to the client.
If an authorization identity was provided by the client, it will confirm that
the authenticating username is authorized to act as the authorization id using
the L</auth_proxy_cb> attribute.
If the client credentials do not match or the authentication name is not
authorized to act as the authorization name, then an exception will be thrown.
=head2 authorization_id
$username = $client->authorization_id();
This takes no arguments and returns the authorization identity resulting from
the SCRAM exchange. This is the client-supplied authorization identity (if one
was provided and validated) or else the successfully authenticated identity.
# RFC5802 example server-first-message
my $server_first =
"r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096";
my $final = $client->final_msg($server_first);
is(
$final,
"c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=",
"client final message"
) or diag explain $client;
ok( !$digest_called, "cached credentials used" );
}
};
subtest "RFC 7677 example (SHA256)" => sub {
# force client nonce to match RFC7677 example
my $client = get_client(
digest => 'SHA-256',
_nonce_generator => sub { "rOprNGfwEbeRWgbNEkqO" }
);
( run in 0.286 second using v1.01-cache-2.11-cpan-4d50c553e7e )