0
votes

ADAL has been depreciated in favor of MSAL. Trying to implement MSAL in simple PythonCGI (without flask).

https://msal-python.readthedocs.io/en/latest/

https://github.com/Azure-Samples/ms-identity-python-webapp

Below is working code for ADAL.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import cgi
import cgitb; cgitb.enable()  # for troubleshooting
from msal import PublicClientApplication
import adal


form = cgi.FieldStorage()
code = form.getvalue('code')
token = form.getvalue('token')
redirect_uri  = 'http://************'
resource      = '************'
client_id     = '************'
header = ''
message=''

if not code and not token:
    auth_template = 'https://adfs.blah.com/adfs/oauth2/authorize?response_type=code&client_id={}&redirect_uri={}'
    authorization_url = (auth_template).format(client_id, redirect_uri)
    header = '<meta http-equiv="refresh" content="0;url=' + authorization_url + '"/>'
elif code != "" and not token:
    authority_url = 'https://adfs.blah.com/adfs'
    context = adal.AuthenticationContext(authority_url, validate_authority=False,)
    token = context.acquire_token_with_authorization_code(code, redirect_uri, resource, client_id)
    refresh_token = token['refreshToken']
    token = context.acquire_token_with_refresh_token(refresh_token, client_id, resource,)
    token_userid = token["userId"].split("@",1)[0].upper()
    message=token_userid

print("Content-Type: text/html;charset=utf-8")
print()

#    put css link? the header section vs using <style> in the page <link rel="stylesheet" href="report.css" />
print("""
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
{header}
</head>
<body>
{message}
</body>
</html>
 """.format(header=header,message=message))

Problem I think I am having is getting a valid code back using MSAL.

I dont think my server is setup to give back a Client Secret.

So I tried to get a code using ADAL, and then using the code from ADAL as input to MSAL to get a Token back.

if not code and not token:
    auth_template = 'https://adfs.blah.com/adfs/oauth2/authorize?response_type=code&client_id={}&redirect_uri={}'
    authorization_url = (auth_template).format(client_id, redirect_uri)
    header = '<meta http-equiv="refresh" content="0;url=' + authorization_url + '"/>'
elif code != "" and not token:
    result=msal.ConfidentialClientApplication(client_id, client_credential=None, authority=None, validate_authority=True, token_cache=None, verify=True, proxies=None, timeout=None, client_claims=None)
    message=result.acquire_token_by_authorization_code(code, ["User.ReadBasic.All"], redirect_uri=None,)

But seems the input data structure is malformed based on this error.

{'error': 'invalid_grant', 'error_description': 'AADSTS9002313: Invalid request. Request is malformed or invalid.\r\nTrace ID: 9fdb3fe4-23b0-4779-9e65-3e3e13951500\r\nCorrelation ID: 51d1d399-7732-4c99-8266-ef89c0f74b2c\r\nTimestamp: 2019-10-16 05:32:05Z', 'error_codes': [9002313], 'timestamp': '2019-10-16 05:32:05Z', 'trace_id': '9fdb3fe4-23b0-4779-9e65-3e3e13951500', 'correlation_id': '51d1d399-7732-4c99-8266-ef89c0f74b2c', 'error_uri': 'https://login.microsoftonline.com/error?code=9002313', 'suberror': 'bad_token'}

Looking for some help on what a Simple Python CGI MSAL would look like?

Thanks in Advance.

Peace, Eric

1

1 Answers

0
votes

Well if you already have your cgi script working with ADAL Python, you can at least use it as a base line, and start your troubleshooting process like this for MSAL Python.

  • Create a PublicClientApplication (you do not have to create a ConfidentialClientApplication, unless your app got assigned a secret or cert). Call its get_authorization_request_url() with relevant paramaters. Now you can compare its returned url with the one you used in the first half of your script https://adfs.blah.com/adfs/oauth2/authorize?response_type=code&client_id={}&redirect_uri={}.

    • Oh wait, actually, I think that might be the issue. You were using a hand-crafted authorize URL which is suitable for the ADFS server that you are using, possibly an ADFS 2016 or below (because you fed it with the "resource" parameter sent by the 2nd half of your cgi script). MSAL Python can work with newer versions of ADFS directly (which accepts a "scope" parameter), or older versions of ADFS indirectly when they are federated behind Azure AD (meaning, MSAL Python talks to AAD, AAD talks to your corp's on-prem ADFS).

    • Nonetheless, it doesn't harm to try completing the 2 legs of get_authorization_request_url() and acquire_token_by_authorization_code() both in MSAL Python, rather than mixing and matching. If that won't work for you, perhaps you would have to stay with ADAL Python for a longer time. Don't worry. ADAL Python won't go away. Existing features in ADAL Python would continue to work.