Is there a way to skip python-O365 Account authentication or make it possible to complete it on a UI?


I want to read outlook emails and save the attachments, and I’m using python-O365 module for that. The problem is this module requires account authentication in order to access outlook.

The workflow is in this way:

  1. User accesses the function/api, which then uses predefined/hardcoded credentials to connect to the outlook account.
credentials = (client, secret)
account = Account(credentials)
  1. At this point the function provides a url in the console for the user to go visit and provide consent and asks the user to paste the authenticated url back in the console. Image below for reference.

Console Image

The problem here is that I want this authentication to be done on UI, not in the console. Im pushing this API to a server, where it will be not possible for the user to access the console to get this url and paste back the authenticated url.

Is there a way to either skip this authentication on whole? Or atleast a way to redirect the user directly to this mentioned url in console and provide the authenticated url to console directly from UI?

Asked By: Abhinav



I got my answer myself. Basically I imported the functions that are being used in O365 library into my code, and reworked them a bit to get what I wanted done.

Here it goes,

So by default on a GET request, this django API shows the link that user needs to visit, sign-in and provide consent.(client and secret are hardcoded).

consent_url, _ = con.get_authorization_url(**kwargs) This line of code is being used in oauth_authentication_flow function in O365 module to print out the consent_url in console. I used it to just return the consent_url to UI.

Once user sign-in and consent is provided and they copy the token-url to paste it back to console, result = con.request_token(token_url, **kwargs) this line of code is used in the same oauth_authentication_flow function in O365 module to check if access token and refresh token are successfully generated and stored.

So using a POST request, now a user can submit the token_url back to my django API to get access to O365 api without relying on console.

def setupMail(request,**kwargs):
    client = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    credentials = (client, secret)
    scopes=['basic', 'message_all']
    global account
    account = Account(credentials)
    protocol = MSGraphProtocol()
    con = O365.Connection(credentials, scopes=protocol.get_scopes_for(scopes),**kwargs)
    if request.method == "GET":
        consent_url, _ = con.get_authorization_url(**kwargs)
        return Response('Visit the following url to give consent: ' + consent_url)
    if request.method == "POST":
        token_url ='token')
        if token_url:
            result = con.request_token(token_url, **kwargs)  # no need to pass state as the session is the same
            if result:
                return Response('Authentication Flow Completed. Oauth Access Token Stored. '
                        'You can now use the API.')
                return Response('Something go wrong. Please try again. ' + str(bool(result)))
            return Response('Authentication Flow aborted.')
        return Response('Bad Request',status=status.HTTP_400_BAD_REQUEST)

Please let me know if there are any security concerns that I need to be worried about.

Answered By: Abhinav
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.