Jplaudir8
Jplaudir8

Reputation: 143

Listing all users and their groups in one request with microsoft graph

I'm currently developing an app in python, which will display azure active directory users and their groups, so of course I need to figure out how to get this data by doing one http request, I have found in other answers that in this way should work:

https://graph.microsoft.com/v1.0/groups/?$expand=members

So I tried that one above and it did not work for me(also I tried by changing the API version to beta but the problem remains), I did something like this:

app.py file

import adal
import flask #web framework
import uuid
import requests

import config

app = flask.Flask(__name__)
app.debug = True
app.secret_key = 'development'

PORT = 5000  # A flask app by default runs on PORT 5000
AUTHORITY_URL = config.AUTHORITY_HOST_URL + '/' + config.TENANT
REDIRECT_URI = 'http://localhost:{}/getAToken'.format(PORT)
TEMPLATE_AUTHZ_URL = ('https://login.microsoftonline.com/{}/oauth2/authorize?' +
                      'response_type=code&client_id={}&redirect_uri={}&' +
                      'state={}&resource={}')


@app.route("/")
def main():
    login_url = 'http://localhost:{}/login'.format(PORT)
    resp = flask.Response(status=307)
    resp.headers['location'] = login_url
    return resp


@app.route("/login")
def login():
    auth_state = str(uuid.uuid4())
    flask.session['state'] = auth_state
    authorization_url = TEMPLATE_AUTHZ_URL.format(
        config.TENANT,
        config.CLIENT_ID,
        REDIRECT_URI,
        auth_state,
        config.RESOURCE)
    resp = flask.Response(status=307)
    resp.headers['location'] = authorization_url
    return resp


@app.route("/getAToken")
def main_logic():
    code = flask.request.args['code']
    state = flask.request.args['state']
    if state != flask.session['state']:
        raise ValueError("State does not match")
    auth_context = adal.AuthenticationContext(AUTHORITY_URL)
    token_response = auth_context.acquire_token_with_authorization_code(code, REDIRECT_URI, config.RESOURCE,
                                                                        config.CLIENT_ID, config.CLIENT_SECRET)
    # It is recommended to save this to a database when using a production app.
    flask.session['access_token'] = token_response['accessToken']

    return flask.redirect('/graphcall')


@app.route('/graphcall')
def graphcall():
    if 'access_token' not in flask.session:
        return flask.redirect(flask.url_for('login'))
    endpoint = config.RESOURCE + '/' + config.API_VERSION + 'groups/?$expand=members/' #https://graph.microsoft.com/v1.0/groups/
    http_headers = {'Authorization': flask.session.get('access_token'),
                    'User-Agent': 'adal-python-sample',
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'client-request-id': str(uuid.uuid4())}
    graph_data = requests.get(endpoint, headers=http_headers, stream=False).json()
    return flask.render_template('homePage.html', graph_data=graph_data)


if __name__ == "__main__":
    app.run()

config.py file:

RESOURCE = "https://graph.microsoft.com"  # Add the resource you want the access token for
TENANT = "joanperez5hotmail.onmicrosoft.com";
AUTHORITY_HOST_URL = "https://login.microsoftonline.com"
CLIENT_ID = "my-client-id";
CLIENT_SECRET = "my-client-secret";

# These settings are for the Microsoft Graph API Call
API_VERSION = 'v1.0'

Got back this following error:

error   {'code': 'BadRequest', 'message': 'Invalid request.', 'innerError': {'request-id': 'c47512f1-10c2-4a1b-aee9-6e28e5585122', 'date': '2018-07-27T20:28:08'}}

Thank you in advance!

Upvotes: 0

Views: 1671

Answers (1)

Michael Hufnagel
Michael Hufnagel

Reputation: 557

I think you are just missing a foward slash after your API version.

 endpoint = config.RESOURCE + '/' + config.API_VERSION + '/groups/?$expand=members/'

Upvotes: 2

Related Questions