File Coverage

blib/lib/LWP/Authen/Wsse.pm
Criterion Covered Total %
statement 21 49 42.8
branch 0 6 0.0
condition 0 15 0.0
subroutine 7 10 70.0
pod 0 3 0.0
total 28 83 33.7


line stmt bran cond sub pod time code
1             package LWP::Authen::Wsse;
2 1     1   767 use 5.004;
  1         3  
  1         34  
3 1     1   5 use strict;
  1         3  
  1         30  
4 1     1   12 use warnings;
  1         2  
  1         38  
5 1     1   870 use English qw( -no_match_vars );
  1         2064  
  1         5  
6              
7             $LWP::Authen::Wsse::VERSION = '0.05';
8              
9 1     1   1361 use Digest::SHA1 ();
  1         846  
  1         23  
10 1     1   1054 use MIME::Base64 ();
  1         838  
  1         41  
11              
12             =head1 NAME
13              
14             LWP::Authen::Wsse - Library for enabling X-WSSE authentication in LWP
15              
16             =head1 VERSION
17              
18             This document describes version 0.05 of LWP::Authen::Wsse, released
19             December 27, 2005.
20              
21             =head1 SYNOPSIS
22              
23             use LWP::UserAgent;
24             use HTTP::Request::Common;
25             my $url = 'http://www.example.org/protected_page.html';
26              
27             # Set up the WSSE client
28             my $ua = LWP::UserAgent->new;
29             $ua->credentials('example.org', '', 'username', 'password');
30              
31             $request = GET $url;
32             print "--Performing request now...-----------\n";
33             $response = $ua->request($request);
34             print "--Done with request-------------------\n";
35              
36             if ($response->is_success) {
37             print "It worked!->", $response->code, "\n";
38             }
39             else {
40             print "It didn't work!->", $response->code, "\n";
41             }
42              
43             =head1 DESCRIPTION
44              
45             C allows LWP to authenticate against servers that are using
46             the C authentication scheme, as required by the Atom Authentication API.
47              
48             The module is used indirectly through LWP, rather than including it directly in
49             your code. The LWP system will invoke the WSSE authentication when it
50             encounters the authentication scheme while attempting to retrieve a URL from a
51             server.
52              
53             You also need to set the credentials on the UserAgent object like this:
54              
55             $ua->credentials('www.company.com:80', '', "username", "password");
56              
57             Alternatively, you may also subclass B and override the
58             C method. See L for more details.
59              
60             =cut
61              
62 1     1   7 use constant WITHOUT_LINEBREAK => q{};
  1         1  
  1         661  
63              
64             sub authenticate {
65 0     0 0   my $class = shift;
66 0           my ( $ua, $proxy, $auth_param, $response, $request, $arg, $size ) = @_;
67              
68 0           my ( $user, $pass ) = $ua->get_basic_credentials(
69             $auth_param->{realm}, $request->url, $proxy
70             );
71              
72 0 0 0       ( defined $user and defined $pass ) or return $response;
73              
74 0           my $now = $class->now_w3cdtf;
75 0           my $nonce = $class->make_nonce;
76 0           my $nonce_enc = MIME::Base64::encode_base64( $nonce, WITHOUT_LINEBREAK );
77 0           my $digest = MIME::Base64::encode_base64(
78             Digest::SHA1::sha1( $nonce . $now . $pass ), WITHOUT_LINEBREAK
79             );
80              
81 0 0         my $auth_header = ( $proxy ? 'Proxy-Authorization' : 'Authorization' );
82 0           my $wsse_value = 'UsernameToken ' . join( ', ',
83             qq(Username="$user"), qq(PasswordDigest="$digest"),
84             qq(Nonce="$nonce_enc"), qq(Created="$now"),
85             );
86              
87 0           my $referral = $request->clone;
88              
89             # Need to check this isn't a repeated fail!
90 0           my $r = $response;
91 0           my $failed;
92 0           while ($r) {
93 0           my $prev = $r->request->{wsse_user_pass};
94 0 0 0       if ( $r->code == 401
      0        
      0        
      0        
95             and $prev
96             and $prev->[0] eq $user
97             and $prev->[1] eq $pass
98             and $failed++ )
99             {
100             # here we know this failed before
101 0           $response->header(
102             'Client-Warning' => "Credentials for '$user' failed before" );
103 0           return $response;
104             }
105 0           $r = $r->previous;
106             }
107              
108 0           $referral->header( $auth_header => 'WSSE profile="UsernameToken"' );
109 0           $referral->header( 'X-WSSE' => $wsse_value );
110              
111 0           $referral->{wsse_user_pass} = [ $user, $pass ];
112              
113 0           $ua->request( $referral, $arg, $size, $response );
114             }
115              
116             sub make_nonce {
117 0     0 0   Digest::SHA1::sha1( time() . {} . rand() . $PID );
118             }
119              
120             sub now_w3cdtf {
121 0     0 0   my ( $sec, $min, $hour, $mday, $mon, $year ) = gmtime();
122 0           $mon++;
123 0           $year += 1900;
124              
125 0           sprintf(
126             '%04s-%02s-%02sT%02s:%02s:%02sZ',
127             $year, $mon, $mday, $hour, $min, $sec,
128             );
129             }
130              
131             1;
132              
133             =head1 SEE ALSO
134              
135             L, L, L.
136              
137             =head1 AUTHORS
138              
139             Audrey Tang Eaudrey@audrey.orgE
140              
141             =head1 COPYRIGHT
142              
143             Copyright 2004, 2005 by Audrey Tang Eaudrey@audrey.orgE.
144              
145             This program is free software; you can redistribute it and/or
146             modify it under the same terms as Perl itself.
147              
148             See L
149              
150             =cut
151