Я неправильно генерирую подпись OAuth или есть другая проблема с этим клиентским кодом Perl / OAuth? - PullRequest
0 голосов
/ 13 ноября 2018

ОК, я схожу с ума здесь.Большую часть недели я потратил на работу с Fiddler, журналом Rest API, журналами Apache, Postman и т. Д., И я не приблизился к решению.Надеюсь, это даст кому-то посмешище (как это легко) и мне решение (для моего здравого смысла).

У меня установлена ​​Wordpress 4.9.8, размещенная на hostgator.У меня установлен WP REST API - плагин OAuth 1.0a Server, и я пытаюсь аутентифицироваться с помощью OAuth из сценария Perl.Я успешно подключился к Postman, используя учетные данные, сгенерированные путем регистрации приложения в пользовательском интерфейсе (Wordpress> Пользователи> Приложения), но не могу взломать код с помощью curl или perl-скрипта (или php или чего-либо еще, что я пробовал),Поскольку Postman работает (когда он не генерирует пробел в сигнатуре OAuth), я считаю, что плагин действительно работает.Ниже приведен мой код, в котором я попытался следовать спецификации, касающейся параметров, сортировки, кодировки URI, кодировки utf8 и т. Д. Все «выглядит хорошо» при изучении заголовков / параметров запросов в Fiddle или в плагине REST API Log (довольно малоинструмент, что) и все же, нет любви.

Спасибо за любой совет или направление.

Код клиента:

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;
use JSON;
use URI::Escape;
use Digest::HMAC_SHA1 qw( hmac_sha1 );
use MIME::Base64 qw( encode_base64 );
use Encode;
use Data::Dumper;

my $timestamp = time();
my $method    = 'GET';
my $url       = "https://hoppingmadmonkey.com/wp-json/myapiplugin/v2/greeting";

my $client_secret = "GelrnAAr1nCe5fzmTqzrU82PsfKCmKlDOZrLPakQRkH4sizJ";
my $token_secret  = "mdeVuJnrs8VSDJNJfMNPQRqBkG8xadfK0jAYjDGhmKOeaY7O";

#my $nonce = $ARGV[0];          # test with Postman generated parameters
#$timestamp = $ARGV[1];         # test with Postman generated parameters
#my $signature = $ARGV[2];      # test with Postman generated parameters

my %params = (
        oauth_consumer_key => "NCo8bflKU9LI",
        oauth_signature_method => "HMAC-SHA1",
        oauth_realm        => "https://hoppingmadmonkey.com",
        oauth_timestamp    => $timestamp,
        oauth_token        => "2GeFG7MkXliq2OBOSSCSRBPX",
        oauth_version      => "1.0",
);

$params{oauth_nonce}    = create_nonce();
#$params{oauth_nonce}    = $nonce;              # test with Postman generated parameters
$params{oauth_timestamp} = $timestamp;

my $key            = create_key($client_secret,$token_secret);
my ($params,$base) = build_base_string($method, $url, \%params);
my $signature      = create_signature($base, $key);


#for (sort keys %params) { print "$_=$params{$_}", "\n"; }
print "params: $params\n\n";
print "basestring: $base\n\n";
print "key: $key\n\n";
print "signature [$signature]\n\n";

$params{oauth_signature} = $signature;          # -- set signature for GET query string

my $request_string = build_request_string($url,\%params);
print "\nrequest_string [$request_string]\n\n";

my $ua = LWP::UserAgent->new();
$ua->default_header("Authorization", "Basic user:pass");
my $response = $ua->get($request_string);
print Dumper $response, "\n";
exit;

my $curlcmd = qq{/usr/bin/curl -i -X GET "$request_string"};
#`$curlcmd 2>&1`;


sub create_signature {
        my ($t,$k) = @_;
        my $str = encode_base64(hmac_sha1($t,$k));
        chomp $str;
        return $str;
}


# Create unique nonce
#
sub create_nonce {
        my $str = `/bin/cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 11 | head -n 1`;
        chomp $str;
        return $str;
}

# Create oauth key for generating hmac-sha1 signature
#
sub create_key {
        my ($cs,$ts) = @_;
        $cs = encode('utf8',uri_escape($cs));
        $ts = encode('utf8',uri_escape($ts));
        return "$cs&$ts";
}


# Build basestring for generating hmac-sha1 signature
#
sub build_request_string {
        my ($u,$p) = @_;
        my %params = %$p;

        my $str = $u . '?';
        my @tmp;
        for (sort keys %params) {
                $p = uri_escape($_) . '=' . uri_escape($params{$_});
                push @tmp, $p;
        }
        $str .= join '&', @tmp;
        return $str;
}


# build the base string parameter for creating the signature
#
sub build_base_string {
        my ($m,$u,$phash) = @_;
        my %params = %$phash;

        my $str = $method;
        $str .= '&' . uri_escape($u) . '&';
        my @tmp;
        for (sort keys %params) {
                push @tmp, uri_escape("$_=$params{$_}");
        }
        $params = join '&', @tmp;
        $str .= join '&', @tmp;
        return $params,$str;

}

1;

Результат выполнения этого из командной строкиэто:

dnu [test] ::>./oauth-perl.pl
params: oauth_consumer_key%3DNCo8bflKU9LI&oauth_nonce%3DJrGdlVLXpB4&oauth_realm%3Dhttps%3A%2F%2Fhoppingmadmonkey.com&oauth_signature_method%3DHMAC-SHA1&oauth_timestamp%3D1542134239&oauth_token%3D2GeFG7MkXliq2OBOSSCSRBPX&oauth_version%3D1.0

basestring: GET&https%3A%2F%2Fhoppingmadmonkey.com%2Fwp-json%2Fmyapiplugin%2Fv2%2Fgreeting&oauth_consumer_key%3DNCo8bflKU9LI&oauth_nonce%3DJrGdlVLXpB4&oauth_realm%3Dhttps%3A%2F%2Fhoppingmadmonkey.com&oauth_signature_method%3DHMAC-SHA1&oauth_timestamp%3D1542134239&oauth_token%3D2GeFG7MkXliq2OBOSSCSRBPX&oauth_version%3D1.0

key: GelrnAAr1nCe5fzmTqzrU82PsfKCmKlDOZrLPakQRkH4sizJ&mdeVuJnrs8VSDJNJfMNPQRqBkG8xadfK0jAYjDGhmKOeaY7O

signature [2pJRR1fz0uUdUWHlUjHFWlXFbL4=]


request_string [https://hoppingmadmonkey.com/wp-json/myapiplugin/v2/greeting?oauth_consumer_key=NCo8bflKU9LI&oauth_nonce=JrGdlVLXpB4&oauth_realm=https%3A%2F%2Fhoppingmadmonkey.com&oauth_signature=2pJRR1fz0uUdUWHlUjHFWlXFbL4%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1542134239&oauth_token=2GeFG7MkXliq2OBOSSCSRBPX&oauth_version=1.0]

$VAR1 = bless( {
                 '_protocol' => 'HTTP/1.1',
                 '_content' => '
{"code":"json_oauth1_signature_mismatch","message":"OAuth signature does not match","data":{"status":401}}',
                 '_rc' => '401',
                 '_headers' => bless( {
                                        'connection' => 'close',
                                        'cache-control' => 'no-cache, must-revalidate, max-age=0',
                                        'date' => 'Tue, 13 Nov 2018 18:37:19 GMT',
                                        'client-ssl-cert-issuer' => '/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA',
                                        'client-ssl-cipher' => 'ECDHE-RSA-AES256-GCM-SHA384',
                                        'client-peer' => '192.185.236.193:443',
                                        'access-control-expose-headers' => 'X-WP-Total, X-WP-TotalPages',
                                        'x-robots-tag' => 'noindex',
                                        'client-warning' => 'Missing Authenticate header',
                                        'client-date' => 'Tue, 13 Nov 2018 18:37:22 GMT',
                                        'client-ssl-warning' => 'Peer certificate not verified',
                                        'content-type' => 'application/json; charset=UTF-8',
                                        'client-transfer-encoding' => [
                                                                        'chunked'
                                                                      ],
                                        'server' => 'Apache',
                                        'x-endurance-cache-level' => '2',
                                        'client-ssl-socket-class' => 'IO::Socket::SSL',
                                        'link' => '<https://hoppingmadmonkey.com/index.php/wp-json/>; rel="https://api.w.org/"',
                                        'access-control-allow-headers' => 'Authorization, Content-Type',
                                        'client-response-num' => 1,
                                        'x-content-type-options' => 'nosniff',
                                        'client-ssl-cert-subject' => '/OU=Domain Control Validated/OU=Hosted by HostGator.com, LLC./OU=PositiveSSL Wildcard/CN=*.hostgator.com',
                                        'expires' => 'Wed, 11 Jan 1984 05:00:00 GMT'
                                      }, 'HTTP::Headers' ),
                 '_msg' => 'Unauthorized',
                 '_request' => bless( {
                                        '_content' => '',
                                        '_uri' => bless( do{\(my $o = 'https://hoppingmadmonkey.com/wp-json/myapiplugin/v2/greeting?oauth_consumer_key=NCo8bflKU9LI&oauth_nonce=JrGdlVLXpB4&oauth_realm=https%3A%2F%2Fhoppingmadmonkey.com&oauth_signature=2pJRR1fz0uUdUWHlUjHFWlXFbL4%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1542134239&oauth_token=2GeFG7MkXliq2OBOSSCSRBPX&oauth_version=1.0')}, 'URI::https' ),
                                        '_headers' => bless( {
                                                               'user-agent' => 'libwww-perl/5.833',
                                                               'authorization' => 'Basic user:pass'
                                                             }, 'HTTP::Headers' ),
                                        '_method' => 'GET',
                                        '_uri_canonical' => bless( do{\(my $o = 'https://hoppingmadmonkey.com/wp-json/myapiplugin/v2/greeting?oauth_consumer_key=NCo8bflKU9LI&oauth_nonce=JrGdlVLXpB4&oauth_realm=https%3A%2F%2Fhoppingmadmonkey.com&oauth_signature=2pJRR1fz0uUdUWHlUjHFWlXFbL4%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1542134239&oauth_token=2GeFG7MkXliq2OBOSSCSRBPX&oauth_version=1.0')}, 'URI::https' )
                                      }, 'HTTP::Request' )
               }, 'HTTP::Response' );
$VAR2 = '
';

В целях целесообразности я включил свои настоящие секреты и веб-сайт.Это все тест на данный момент.Не стесняйтесь попробовать решение, если у вас есть такое время в ваших руках.Я всегда могу лишить законной силы токены, если / когда они подвергаются насилию, и, очевидно, однажды изменится / если я смогу понять проблему.

Очевидная мысль, что я неправильно генерирую подпись (Большой совет:

{"code":"json_oauth1_signature_mismatch","message":"OAuth signature does not match","data":{"status":401}}',

)

Я думаю, что я все готово во всем Интернете безрезультатно.Заранее спасибо за любые мысли.И если вы рядом с Атлантой, штат Джорджия, и помогите мне, пиво на мне.

Приветствия.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Я не мог заставить работать с Net :: OAuth, поэтому я попытался написать свой код снова с нуля и явно следуя рекомендациям на http://lti.tools/oauth/, пока мой вывод кода не совпал с их. Аллилуйя! Сейчас работает.

Одна вещь, которую я должен был добавить, и Почтальон тоже не может этого сделать, - это URL кодировать подпись. Разумеется, имеет смысл, но странно, что Почтальон пропускает его и время от времени отправляет «+».

0 голосов
/ 14 ноября 2018

Попробуйте использовать Net :: OAuth

Если вам действительно нужно исправить свою реализацию, попробуйте удалить все uri_escape и протестировать данные, которые не требуют экранирования. Похоже, у вас есть некоторые ненужные или двойной побег. Начните с функции build_base_string. Я думаю, что знак = должен быть убран.

...