Bio-Das-ProServer

 view release on metacpan or  search on metacpan

lib/Bio/Das/ProServer/Authenticator/ip.pm  view on Meta::CPAN

use base qw(Bio::Das::ProServer::Authenticator);

our $VERSION = do { my ($v) = (q$LastChangedRevision: 688 $ =~ /\d+/mxsg); $v; };

sub authenticate {
  my ($self, $params) = @_;

  # Reset stored IP
  delete $self->{'ip'};
  # IP addresses checked:
  # 1. All IPs from the X-Forwarded-For header
  # 2. The socket address
  my @query_ips = $params->{'request'} ? split /\s*,\s*/mxs, $params->{'request'}->header('X-Forwarded-For') : ();
  if ($params->{'peer_addr'}) {
    push @query_ips, inet_ntoa( $params->{'peer_addr'} );
  }
  @query_ips = map {
    Net::IP->new($_) || croak 'Unable to determine client IP: '.Net::IP::Error
  } @query_ips;

  # Check each client IP against each whitelist IP range
  for my $query (@query_ips) {
    for my $whitelist (@{$self->{'allow_ip'}}) {

lib/Bio/Das/ProServer/Authenticator/ip.pm  view on Meta::CPAN

behaviour in a more subtle fashion (e.g provide different data for different
sites).

=head1 DESCRIPTION

Authenticates requests according to a 'whitelist' of IP address ranges. Requests
from clients not within one of these ranges are denied.

The IP addresses that are checked against the whitelist are:
  1) that of the socket connection
  2) those listed in the X-Forwarded-For HTTP header

The latter is necessary for clients and servers operating behind proxies.

IMPORTANT NOTE:
Because IP addresses can be spoofed by clients, this is NOT a robust method of
securing data.

=head1 CONFIGURATION AND ENVIRONMENT

The whitelist for IP addresses is configured in the source INI section, using

lib/Bio/Das/ProServer/Authenticator/ip.pm  view on Meta::CPAN


=head1 SUBROUTINES/METHODS

=head2 authenticate : Applies authentication to a request.

  Requires: a hash reference containing details of the DAS request
  Returns:  either nothing (allow) or a HTTP::Response (deny)

  my $allow = $oAuth->authenticate({
    'peer_addr' => $, # packed (socket IP address)
    'request'   => $, # HTTP::Request object (for X-Forwarded-For header)
    ...
  });

=head2 ip : Gets the authenticated IP address

  my $sIp = $oAuth->ip();

=head2 init : Initialises the IP whitelist

=head1 DIAGNOSTICS

lib/Bio/Das/ProServer/Authenticator/ip.pm  view on Meta::CPAN


=item L<Socket|Socket>

=item L<Bio::Das::ProServer::Authenticator|Bio::Das::ProServer::Authenticator>

=back

=head1 BUGS AND LIMITATIONS

Clients that are separated from the server by an anonymising HTTP proxy (i.e.
one that does not reveal the client's IP address in the X-Forwarded-For HTTP
header) will always fail this method of authentication.

Note that clients may spoof an IP address in the X-Forwarded-For header.
Therefore this method of authentication is not a robust security precaution.

=head1 INCOMPATIBILITIES

None reported.

=head1 AUTHOR

Andy Jenkinson <andy.jenkinson@ebi.ac.uk>

t/32-auth-ip.t  view on Meta::CPAN

              },
});

my $resp = $auth->authenticate({ 'peer_addr' => inet_aton('1.1.1.1') });
isa_ok($resp, 'HTTP::Response', 'socket IP authentication (deny)');

$resp = $auth->authenticate({ 'peer_addr' => INADDR_LOOPBACK });
ok(!$resp, 'socket IP authentication (allow)');

my $req = HTTP::Request->new();
$req->header('X-Forwarded-For' => '1.1.1.1');
$resp = $auth->authenticate({ 'request' => $req });
isa_ok($resp, 'HTTP::Response', 'header IP authentication (deny)');

$req->header('X-Forwarded-For' => inet_ntoa(INADDR_LOOPBACK));
$resp = $auth->authenticate({ 'request' => $req });
ok(!$resp, 'header IP authentication(allow)');

$req->header('X-Forwarded-For' => '111.111.111.100');
$resp = $auth->authenticate({ 'request' => $req });
isa_ok($resp, 'HTTP::Response', 'range IP authentication (deny)');

$req->header('X-Forwarded-For' => '111.111.111.112');
$resp = $auth->authenticate({ 'request' => $req });
ok(!$resp, 'range IP authentication (allow)');

$req->header('X-Forwarded-For' => '111.222.1.111');
$resp = $auth->authenticate({ 'request' => $req });
isa_ok($resp, 'HTTP::Response', 'CIDR IP authentication (deny)');

$req->header('X-Forwarded-For' => '222.222.1.111');
$resp = $auth->authenticate({ 'request' => $req });
ok(!$resp, 'CIDR IP authentication (allow)');

$req->header('X-Forwarded-For' => '2.2.1.2');
$resp = $auth->authenticate({ 'request' => $req });
isa_ok($resp, 'HTTP::Response', 'additive IP authentication (deny)');

$req->header('X-Forwarded-For' => '2.2.2.2');
$resp = $auth->authenticate({ 'request' => $req });
ok(!$resp, 'additive IP authentication (allow)');



( run in 0.224 second using v1.01-cache-2.11-cpan-26ccb49234f )