Created
January 17, 2022 04:29
-
-
Save sudosoul/8a083c50368678ca9315bdb64ee60172 to your computer and use it in GitHub Desktop.
Ansible HTTP Digest Authentication- Resolve "Unsupported digest authentication algorithm 'SHA-256'" error from URI Module - Manually create Authorization Header
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
########################################################################################## | |
# HTTP Digest Auth with URI Module POC | |
# | |
# Usage: | |
# 1. Create a new playbook called `test.yml` | |
# | |
# 2. Run it via: | |
# ``` | |
# ansible-playbook test.yml \ | |
# -i inventory/some-inventory-directory \ | |
# -l some-host-defined-in-the-above-inventory | |
# -e ansible_python_interpreter=/usr/bin/python3 | |
# ``` | |
# | |
# @author Rob Mullins <rob{{AT}}unqork.com> | |
########################################################################################## | |
- name: HTTP Digest Auth with URI Module POC | |
connection: local | |
hosts: all | |
gather_facts: false | |
##################################################################################################### | |
pre_tasks: | |
##################################################################################################### | |
# Define preknown defaults | |
##################################################################################################### | |
- set_fact: | |
api: | |
username: "apiUser" | |
password: "apiKey" | |
url: "https://example.com/api/v1.0/category/abc123/product/abc123" | |
requestMethod: "GET" | |
digestRequestValues: | |
# nonceCount - Prevents relay-attacks... indicates that this our first request with using the below cnonce value | |
nc: "00000001" | |
# clientNonce - A random string we create, used as a mutual secret in conjunction with 'nc' | |
cnonce: "{{ 99999999 | random | to_uuid | hash('md5') }}" | |
- set_fact: | |
api: "{{ api | combine( {'uri' : api.url.split('.com') | last }) }}" | |
##################################################################################################### | |
tasks: | |
##################################################################################################### | |
# Get Digest Auth response data | |
##################################################################################################### | |
- name: Make initial request to receive digest response data. | |
uri: | |
url: "{{ api.url }}" | |
method: "{{ api.requestMethod }}" | |
status_code: 401 | |
register: unauthorizedApiResponse | |
- name: Create a dictionary containing the digest data from the www-authenticate response header. | |
set_fact: | |
digestResponseHeaderValues: "{{ digestResponseHeaderValues | default({}) | combine ({ (item.split('=')[0] | trim) : (item.split('=')[1] | regex_replace('\"', \"\")) }) }}" | |
with_items: "{{ unauthorizedApiResponse.www_authenticate.replace('Digest','').split(',') }}" | |
##################################################################################################### | |
# Calculate the SHA-256 hashed digest response value | |
# See https://en.wikipedia.org/wiki/Digest_access_authentication#Overview for the formula | |
##################################################################################################### | |
- name: "Calculate HA1 from the digest response formula - sha256(username:realm:password)" | |
set_fact: | |
digestRequestValues: "{{ digestRequestValues | combine ({ 'HA1' : [api.username, digestResponseHeaderValues.realm, api.password] | join(':') | hash('sha256') }) }}" | |
- name: "Calculate HA2 from the digest response formula - sha256(requestMethod:URI)" | |
set_fact: | |
digestRequestValues: "{{ digestRequestValues | combine ({ 'HA2' : [api.requestMethod, api.uri] | join(':') | hash('sha256') }) }}" | |
- name: "Build array containing the digest response values in proper sequence (HA1:nonce:nc:cnonce:qop:HA2)" | |
set_fact: | |
digestRequestValues: "{{ digestRequestValues | combine({ 'response' : ( ( digestRequestValues['response'] | default([]) ) + [item]) }) }}" | |
with_items: | |
- "{{ digestRequestValues.HA1 }}" | |
- "{{ digestResponseHeaderValues.nonce }}" | |
- "{{ digestRequestValues.nc }}" | |
- "{{ digestRequestValues.cnonce }}" | |
- "{{ digestResponseHeaderValues.qop }}" | |
- "{{ digestRequestValues.HA2 }}" | |
- name: "Create the final encrypted digest response string by joining the above elements - sha256(HA1:nonce:nc:cnonce:qop:HA2)" | |
set_fact: | |
digestRequestValues: "{{ digestRequestValues | combine({ 'response' : (digestRequestValues['response'] | join(':') | hash('sha256')) }) }}" | |
##################################################################################################### | |
# Send request with our manually constructed Digest Authorization header | |
##################################################################################################### | |
- name: "Build array containing each element of the digest (authorization) header" | |
set_fact: | |
digestAuthorizationHeader: "{{ digestAuthorizationHeader | default([]) + [item]}}" | |
with_items: | |
- "Digest username=\"{{ api.username }}\"" | |
- "realm=\"{{ digestResponseHeaderValues.realm }}\"" | |
- "nonce=\"{{ digestResponseHeaderValues.nonce }}\"" | |
- "uri=\"{{ api.uri }}\"" | |
- "cnonce=\"{{ digestRequestValues.cnonce }}\"" | |
- "nc={{ digestRequestValues.nc }}" | |
- "qop={{ digestResponseHeaderValues.qop }}" | |
- "response=\"{{ digestRequestValues.response }}\"" | |
- "algorithm=\"{{ digestResponseHeaderValues.algorithm }}\"" | |
- name: "Create the final digest Authorization comma separated string" | |
set_fact: | |
digestAuthorizationHeader: "{{ digestAuthorizationHeader | join(', ') }}" | |
- name: Check to see if cluster already exists | |
uri: | |
url: "{{ api.url }}" | |
method: "{{ api.requestMethod }}" | |
status_code: 200,404 | |
headers: | |
Authorization: "{{ digestAuthorizationHeader }}" | |
register: authorizedApiResponse | |
# Print the API response | |
- debug: "msg={{authorizedApiResponse}}" | |
##################################################################################################### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment