# API authentication via SAML

**URL:** <https://forum.ansible.com/t/api-authentication-via-saml/34904>\
**Category:** AWX Project\
**Tags:** awx\
**Created:** [April 1, 2021, 6:09pm UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904 "2021-04-01T18:09:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kim\_Covil](https://avatars.discourse-cdn.com/v4/letter/k/8dc957/32.png) [@Kim\_Covil](https://forum.ansible.com/u/Kim_Covil)\
**Post date:** [April 1, 2021, 6:09pm UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904/1 "2021-04-01T18:09:05Z")

</div>

Hi,

I have spent a bit of time and finally have kerberos authentication via SAML, Keycloak and FreeIPA working for AWX 17.1.0 for the web UI.

What I really want to get working though is API access from curl or ansible, without needing to pass username and password in. Is there a guide somewhere for this part? My hunting so far is looking like I need to create tokens to do any API work without usernames and passwords, and for that I would need to use the web UI to create the tokens if I want to do it with SAML auth, which feels like something is missing.

Many Thanks,

Kim

---

<div class="post-metadata">

**Author:** ![Kim\_Covil](https://avatars.discourse-cdn.com/v4/letter/k/8dc957/32.png) [@Kim\_Covil](https://forum.ansible.com/u/Kim_Covil)\
**Post date:** [April 9, 2021, 7:13pm UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904/2 "2021-04-09T19:13:56Z")

</div>

In case anyone else comes looking for this ([xkcd: Wisdom of the Ancients](https://xkcd.com/979/)), here is where I have got to:

# GET request to AWX SAML redirect, following redirections and using SPNEGO to pass kerberos credentials and cookie storage

# returns an HTML form with a SAMLResponse field (base64 encoded SAML XML response) and javascript to submit the form if in a browser, also sets an AWX sessionid cookie and various Keycloak cookies

curl -b cookies.txt -c cookies.txt -L --negotiate -u : https://$AWX\_HOST/sso/login/saml/?idp=$IDP\_ID

# POST request to AWX SAML complete endpoint passing form field values provided in the SAML response, also passing cookies retrieved previously.

# No need to pass SPNEGO flags here or follow redirects

# returns a redirect (that we can ignore), updates the AWX sessionid cookie and sets a csrftoken cookie

curl -b cookies.txt -c cookies.txt --data-urlencode “SAMLResponse@samlresponse.txt” -d ‘RelayState=TFSSO’ ‘https://$AWX\_HOST/sso/complete/saml/’

# GET/POST/PUT to api endpoints as required, providing sessionid and csrftoken cookies:

curl -b cookies.txt -c cookies.txt -L ‘https://$AWX\_HOST/api/v2/me/’

Now that I know the mechanism I need to work on getting this usable in ansible… probably via a python module.

Kind Regards,

Kim

---

<div class="post-metadata">

**Author:** ![Fabien\_Carre](https://avatars.discourse-cdn.com/v4/letter/f/3bc359/32.png) [@Fabien\_Carre](https://forum.ansible.com/u/Fabien_Carre)\
**Post date:** [October 4, 2023, 2:42pm UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904/3 "2023-10-04T14:42:58Z")

</div>

Hello,

Did you eventually implement a working solution?  
I am basically trying to do the same thing with powershell.

I am using a web form which allows me to handle the authentication through a web browser. I cannot figure out if I need to save the cookies.

Are you using everytime the same cookies or the cookies from the step right before ?

Thank you

---

<div class="post-metadata">

**Author:** ![Kim\_Covil](https://avatars.discourse-cdn.com/v4/letter/k/8dc957/32.png) [@Kim\_Covil](https://forum.ansible.com/u/Kim_Covil)\
**Post date:** [October 4, 2023, 5:29pm UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904/4 "2023-10-04T17:29:41Z")

</div>

Hi Fabien,

Yes, I did get some ansible tasks working for our environment on Linux. A bit clunky, but we haven’t spent too much more time on it and are now moving away from AWX. I have pasted some code snippets below.

We get a session cookie and csrftoken for the AWX host and store it in the hostvars for that AWX host.

> - name: Get initial awx sessionid and SAMLRequest  
> block:
> - name: start awx session  
> delegate\_to: localhost  
> become: false  
> command:  
> cmd: “curl -s ‘https://{{ awx\_host }}/sso/login/saml/?idp={{ saml\_idp }}’ -c - -w %{redirect\_url}”  
> check\_mode: false  
> changed\_when: false  
> no\_log: “{{ ansible\_verbosity \< 4 }}”  
> register: awx\_session  
> tags:
> - skip\_ansible\_lint # get\_uri module does not support SPNEGO/kerberos authentication
> - name: Set awx sessionid  
> set\_fact:  
> awx\_sessionid\_cookie: “sessionid={{ awx\_session.stdout | regex\_search(‘._\s+sessionid\s+(._)’, ‘\1’) | first }}”  
> no\_log: “{{ ansible\_verbosity \< 4 }}”
> - name: Get XHTML SAMLResponse  
> delegate\_to: localhost  
> become: false  
> command:  
> cmd: “curl -s --negotiate -u : ‘{{ (awx\_session.stdout\_lines | select(‘match’, ‘^https’) | list | first).split(’#‘)[0] }}’ -H ‘Cookie: {{ awx\_sessionid\_cookie }}’”  
> check\_mode: false  
> changed\_when: false  
> no\_log: “{{ ansible\_verbosity \< 4 }}”  
> register: awx\_session\_saml\_response  
> tags:
> - skip\_ansible\_lint # get\_uri module does not support SPNEGO/kerberos authentication
> - name: Assert that we received a SAMLResponse  
> assert:  
> that: “‘SAMLResponse’ in awx\_session\_saml\_response.stdout”  
> fail\_msg: “Did not receive a SAMLResponse from keycloak server”  
> success\_msg: “Keycloak authentication successful”
> - name: Extract SAMLResponse  
> set\_fact:  
> awx\_session\_saml\_response: “{{ awx\_session\_saml\_response.stdout\_lines | select(‘search’, ‘name="SAMLResponse"’) | first | regex\_search(‘value="([^"]\*)’, ‘\1’) }}”  
> no\_log: “{{ ansible\_verbosity \< 4 }}”
> - name: Complete SAML authentication  
> delegate\_to: localhost  
> become: false  
> command:  
> cmd: “curl -s -H ‘Cookie: {{ awx\_sessionid\_cookie }}’ -c - --data-urlencode ‘SAMLResponse={{ awx\_session\_saml\_response }}’ --data ‘RelayState={{ saml\_idp }}’ ‘https://{{ awx\_host }}/sso/complete/saml/’”  
> check\_mode: false  
> changed\_when: false  
> no\_log: “{{ ansible\_verbosity \< 4 }}”  
> register: awx\_session  
> tags:
> - skip\_ansible\_lint # get\_uri module does not support SPNEGO/kerberos authentication
> - name: Update awx\_session  
> set\_fact:  
> awx\_session:  
> cookie: “sessionid={{ awx\_session.stdout | regex\_search(‘._\s+sessionid\s+(._)’, ‘\1’) | first }}”  
> csrftoken: “{{ awx\_session.stdout | regex\_search(‘._\s+csrftoken\s+(._)’, ‘\1’) | first }}”  
> awx\_session\_saml\_response: “”  
> awx\_sessionid\_cookie: “”  
> delegate\_to: “{{ awx\_host }}”  
> delegate\_facts: true  
> no\_log: “{{ ansible\_verbosity \< 4 }}”  
> rescue:
> - name: Notify of failure to get awx session  
> debug:  
> msg: “Failed to get an awx session for {{ awx\_host }}”

Then we pass that cookie and token to all the API calls we make:

> - name: Get all job\_templates  
> delegate\_to: localhost  
> become: false  
> uri:  
> url: |  
> https://{{ awx\_host }}/api/v2/job\_templates/?page\_size={{ awx\_api\_page\_size }}  
> method: “GET”  
> return\_content: true  
> status\_code:
> - 200
> - 202  
> headers:  
> Cookie: “{{ hostvars[awx\_host].awx\_session.cookie }}; csrftoken={{ hostvars[awx\_host].awx\_session.csrftoken }}”  
> X-CSRFTOKEN: “{{ hostvars[awx\_host].awx\_session.csrftoken }}”  
> Referer: “https://{{ awx\_host }}/”  
> register: awx\_api\_job\_templates\_response  
> check\_mode: false  
> changed\_when: false

I hope that helps.

Kind Regards,

Kim

---

<div class="post-metadata">

**Author:** ![Fabien\_Carre](https://avatars.discourse-cdn.com/v4/letter/f/3bc359/32.png) [@Fabien\_Carre](https://forum.ansible.com/u/Fabien_Carre)\
**Post date:** [October 5, 2023, 10:22am UTC](https://forum.ansible.com/t/api-authentication-via-saml/34904/5 "2023-10-05T10:22:20Z")

</div>

Hello,

Thank you for your answer and your solution.

It will try to adapt my script today.

Regards,

Fabien
