<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Authorization signature for API requests in APIs</title>
    <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881601#M374</link>
    <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;Because if its the sample code (“sign” function) that is incorrect then this would explain why this isn’t working for me in my production instance also…&lt;/P&gt;&lt;/DIV&gt;</description>
    <pubDate>Tue, 22 Jan 2019 15:56:45 GMT</pubDate>
    <dc:creator>Vince4</dc:creator>
    <dc:date>2019-01-22T15:56:45Z</dc:date>
    <item>
      <title>Authorization signature for API requests</title>
      <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881598#M371</link>
      <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;I am trying to use the Admin API.&lt;BR /&gt;
I’m being told my Authorization signature is invalid with a HTTP 401 response code (“Invalid signature in request credentials” - 40103 to be precise).&lt;/P&gt;
&lt;P&gt;The trouble is I’m following the guidance in the documentation here: &lt;A href="https://duo.com/docs/adminapi#authentication" class="inline-onebox" rel="nofollow noopener"&gt;Duo Admin API | Duo Security&lt;/A&gt;&lt;BR /&gt;
… including using the same signing function, and the same sample data - but not getting the same signature back!&lt;/P&gt;
&lt;P&gt;Is there anyone out there who’s got this working, and who can advise what I’m doing wrong?&lt;/P&gt;
&lt;P&gt;Here’s my sample Python code - this doesn’t touch the API, but just calculates the Authorization signature based on the values in the example:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;######################################################

import base64
from email import utils
import hmac
import hashlib
import urllib
import logging
import sys
import os

log = logging.getLogger(__name__)
out_hdlr = logging.StreamHandler(sys.stdout)
out_hdlr.setFormatter(logging.Formatter('%(asctime)s ' + os.path.basename(__file__) + ': %(message)s'))
out_hdlr.setLevel(logging.INFO)
log.addHandler(out_hdlr)
log.setLevel(logging.INFO)

def sign(method, host, path, params, skey, ikey):
        """
        Return HTTP Basic Authentication ("Authorization" and "Date") headers.
        method, host, path: strings from request
        params: dict of request parameters
        skey: secret key
        ikey: integration key
        """

        # create canonical string
        #now = utils.formatdate()
        now = "Tue, 21 Aug 2012 17:29:18 -0000"
        log.debug(now)
        canon = [now, method.upper(), host.lower(), path]
        args = []
        for key in sorted(params.keys()):
                val = params[key]
                if isinstance(val, unicode):
                        val = val.encode("utf-8")
                args.append('%s=%s' % (urllib.quote(key, '~'), urllib.quote(val, '~')))
        canon.append('&amp;amp;'.join(args))
        canon = '\n'.join(canon)

        log.info("Outputting canonical form of data to be signed")
        log.info(canon)

        # sign canonical string
        sig = hmac.new(skey, canon, hashlib.sha1)
        auth = '%s:%s' % (ikey, sig.hexdigest())

        # return headers
        return {'Date': now, 'Authorization': 'Basic %s' % base64.b64encode(auth)}

log.info("Starting Duo log retrieval")

params={"realname": "First Last",
        "username": "root"}

headers=sign(method="POST",
        host="api-xxxxxxxx.duosecurity.com",
        path="/admin/v1/users",
        params=params,
        skey="Zh5eGmUq9zpfQnyUIu5OL9iWoMMv5ZNmk3zLJ4Ep",
        ikey="DIWJ8X6AEYOR5OMC6TQ1")

log.info("Outputting headers")
log.info(headers)

#Gives output like:
#
# Starting Duo log retrieval
#
# Outputting canonical form of data to be signed
# Tue, 21 Aug 2012 17:29:18 -0000
# POST
# ■■■■ &amp;lt;- the correct host goes here, this has been obfuscated by Duo's Community forum
# /admin/v1/users
# realname=First%20Last&amp;amp;username=root
# 
# Outputting headers
# {'Date': 'Tue, 21 Aug 2012 17:29:18 -0000', 'Authorization': 'Basic RElXSjhYNkFFWU9SNU9NQzZUUTE6YzFlZjQzNzY3YzNlYjNiMzI1OGRiZGRjYTZmOGQwOTQxZTA4NWI5Mg=='}

# THIS DOES NOT MATCH ONLINE EXAMPLE at https://duo.com/docs/adminapi#authentication
# Apparently Authorization should be RElXSjhYNkFFWU9SNU9NQzZUUTE6MmQ5N2Q2MTY2MzE5NzgxYjVhM2EwN2FmMzlkMzY2ZjQ5MTIzNGVkYw==

######################################################&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 22 Jan 2019 11:20:06 GMT</pubDate>
      <guid>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881598#M371</guid>
      <dc:creator>Vince4</dc:creator>
      <dc:date>2019-01-22T11:20:06Z</dc:date>
    </item>
    <item>
      <title>Re: Authorization signature for API requests</title>
      <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881599#M372</link>
      <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;That signature example value is not right. We will get that fixed. Go ahead and actually test your code against Duo, ignoring the example value.&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 22 Jan 2019 15:18:31 GMT</pubDate>
      <guid>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881599#M372</guid>
      <dc:creator>DuoKristina</dc:creator>
      <dc:date>2019-01-22T15:18:31Z</dc:date>
    </item>
    <item>
      <title>Re: Authorization signature for API requests</title>
      <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881600#M373</link>
      <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;Thanks for the response Kristina.&lt;/P&gt;
&lt;P&gt;That’s unfortunate regarding the example being wrong - is my value correct then?&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 22 Jan 2019 15:31:57 GMT</pubDate>
      <guid>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881600#M373</guid>
      <dc:creator>Vince4</dc:creator>
      <dc:date>2019-01-22T15:31:57Z</dc:date>
    </item>
    <item>
      <title>Re: Authorization signature for API requests</title>
      <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881601#M374</link>
      <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;Because if its the sample code (“sign” function) that is incorrect then this would explain why this isn’t working for me in my production instance also…&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 22 Jan 2019 15:56:45 GMT</pubDate>
      <guid>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881601#M374</guid>
      <dc:creator>Vince4</dc:creator>
      <dc:date>2019-01-22T15:56:45Z</dc:date>
    </item>
    <item>
      <title>Re: Authorization signature for API requests</title>
      <link>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881602#M375</link>
      <description>&lt;DIV class="duo-migrated-content"&gt;&lt;P&gt;So is the example on &lt;A href="https://duo.com/docs/authapi#-api-details" class="inline-onebox" rel="nofollow noopener"&gt;Auth API | Duo Security&lt;/A&gt; correct now?&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 12 Jun 2019 20:40:25 GMT</pubDate>
      <guid>https://community.cisco.com/t5/apis/authorization-signature-for-api-requests/m-p/4881602#M375</guid>
      <dc:creator>alexhaberer</dc:creator>
      <dc:date>2019-06-12T20:40:25Z</dc:date>
    </item>
  </channel>
</rss>

