File Coverage

blib/lib/OIDC/Client/Role/ClientAuthenticationHelper.pm
Criterion Covered Total %
statement 58 59 98.3
branch 13 14 92.8
condition 2 3 66.6
subroutine 11 11 100.0
pod n/a
total 84 87 96.5


line stmt bran cond sub pod time code
1             package OIDC::Client::Role::ClientAuthenticationHelper;
2 3     3   194866 use utf8;
  3         402  
  3         71  
3 3     3   598 use Moose::Role;
  3         631120  
  3         25  
4 3     3   21186 use namespace::autoclean;
  3         10905  
  3         28  
5 3     3   292 use feature 'signatures';
  3         8  
  3         703  
6 3     3   27 no warnings 'experimental::signatures';
  3         5  
  3         178  
7 3     3   615 use Readonly;
  3         5221  
  3         288  
8 3     3   28 use Carp qw(croak);
  3         7  
  3         224  
9 3     3   714 use Mojo::Util qw(b64_encode);
  3         284498  
  3         277  
10 3     3   843 use Crypt::JWT ();
  3         43489  
  3         1837  
11              
12             =encoding utf8
13              
14             =head1 NAME
15              
16             OIDC::Client::Role::ClientAuthenticationBuilder - Client Authentication Builder
17              
18             =head1 DESCRIPTION
19              
20             This Moose role covers private methods for building client authentication data.
21              
22             =cut
23              
24              
25             requires qw(log_msg
26             id
27             secret
28             private_key
29             client_assertion_lifetime
30             client_assertion_audience
31             generate_uuid_string
32             private_key_jwt_encoding_options
33             client_secret_jwt_encoding_options);
34              
35              
36             Readonly my $CLIENT_ASSERTION_TYPE => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';
37              
38              
39 26     26   57 sub _build_client_auth_arguments ($self, $method, $url) {
  26         46  
  26         66  
  26         41  
  26         38  
40              
41 26         54 my (%headers, %form);
42              
43 26 100       114 if ($method eq 'client_secret_basic') {
    100          
    100          
    100          
    50          
44 10         357 $headers{Authorization} = 'Basic ' . b64_encode(join(':', $self->id, $self->secret), '');
45             }
46             elsif ($method eq 'client_secret_post') {
47 8         276 $form{client_id} = $self->id;
48 8         283 $form{client_secret} = $self->secret;
49             }
50             elsif ($method eq 'client_secret_jwt') {
51 3         86 $form{client_id} = $self->id;
52 3         18 $form{client_assertion_type} = $CLIENT_ASSERTION_TYPE;
53 3         20 $form{client_assertion} = $self->_build_client_assertion(0, $url);
54             }
55             elsif ($method eq 'private_key_jwt') {
56 4         120 $form{client_id} = $self->id;
57 4         22 $form{client_assertion_type} = $CLIENT_ASSERTION_TYPE;
58 4         33 $form{client_assertion} = $self->_build_client_assertion(1, $url);
59             }
60             elsif ($method eq 'none') {
61 1         45 $form{client_id} = $self->id;
62             }
63             else {
64 0         0 croak("Unsupported client auth method: $method");
65             }
66              
67 26         267 return (\%headers, \%form);
68             }
69              
70              
71 7     7   14 sub _build_client_assertion ($self, $use_private_key, $url) {
  7         14  
  7         13  
  7         15  
  7         10  
72              
73 7         50 $self->log_msg(debug => 'OIDC: building client assertion');
74              
75 7         410 my $now = time;
76 7         305 my $exp = $now + $self->client_assertion_lifetime;
77 7   66     268 my $aud = $self->client_assertion_audience // $url;
78 7         38 my $jti = $self->generate_uuid_string();
79              
80 7         218 my %claims = (
81             iss => $self->id,
82             sub => $self->id,
83             aud => $aud,
84             jti => $jti,
85             iat => $now,
86             exp => $exp,
87             );
88              
89 7 100       283 my $jwt_encoding_options = $use_private_key ? $self->private_key_jwt_encoding_options
90             : $self->client_secret_jwt_encoding_options;
91              
92 7 100       56 return Crypt::JWT::encode_jwt(
93             %$jwt_encoding_options,
94             payload => \%claims,
95             key => $use_private_key ? $self->private_key : $self->secret,
96             );
97             }
98              
99              
100             1;