Closed kenoir closed 5 years ago
I had a play with the Azure CLI this evening.
You can log in with:
$ az login --allow-no-subscriptions
It gives you a login token; you open a browser and enter that token.
Then you can get the tenant ID:
$ az account show
{
"environmentName": "AzureCloud",
"id": "{ID}",
"isDefault": true,
"name": "N/A(tenant level account)",
"state": "Enabled",
"tenantId": "{TENANT_ID}",
"user": {
"name": "A.Chan@wellcome.ac.uk",
"type": "user"
}
}
The SSO SAML request format is documented here: https://docs.microsoft.com/en-us/azure/active-directory/develop/single-sign-on-saml-protocol#authnrequest
Based on that and the Node tool, you take a blob of XML like this:
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="id{id}" Version="2.0" IssueInstant="{dt.datetime.now().isoformat()}" IsPassive="false" AssertionConsumerServiceURL="https://signin.aws.amazon.com/saml" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">{appIdUri}</Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"></samlp:NameIDPolicy>
</samlp:AuthnRequest>
zlib compress it, base64 encode and then fire at an Azure URL:
https://login.microsoftonline.com/{TENANT_ID}/saml2?SAMLRequest={SAML_REQUEST}
If it can authenticate you, then I think we're in business.
Possible useful pieces:
az rest
with --skip-authorization-header
az account get-access-token
, and maybe send that in the HTTP Auth header?Right now I get an error whenever I fire XML into Azure:
AADSTS750016: Parameter 'SAMLRequest' must be unique in HTTP SAML message.
But there might be a thread worth tugging on there.
Okay, so this constructs a valid SAML request that logs you in if you go through the browser – I just can’t find a way to do it with the CLI:
# az login --allow-no-subscriptions
import base64
from urllib.parse import urlencode
import zlib
import requests
def deflate_and_base64_encode(value):
compressor = zlib.compressobj(wbits=-15)
return base64.b64encode(
compressor.compress(value.encode("utf8")) + compressor.flush()
)
import uuid
saml_param = deflate_and_base64_encode(
f'''<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="{uuid.uuid4()}" Version="2.0" IssueInstant="2019-07-23T13:31:26.000Z" IsPassive="false" AssertionConsumerServiceURL="https://signin.aws.amazon.com/saml" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://signin.aws.amazon.com/saml#14</Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"></samlp:NameIDPolicy>
</samlp:AuthnRequest>'''
)
params = urlencode({"SAMLRequest": saml_param})
url = "https://login.microsoftonline.com/$TENANTID/saml2?" + params
print(url)
Also dumping this file here as a record of what the headless browser is doing.
Further investigation this evening: the only cookie it cares about is ESTSAUTH
.
Done?!
@alexwlchan did you get this working?
@gtmtech I used https://github.com/alexwlchan/azure-aws-credentials for a while, and now we all use https://github.com/sportradar/aws-azure-login
Using a chrome plugin is less than ideal
Some specific issues:
Downloads
folder is insecure