Authorization and Microsoft Graph Security API

Microsoft

Understanding authorization when calling the Microsoft Graph Security API

High-level summary: Security data accessible via the Microsoft Graph Security API is very sensitive and is protected using both permissions (aka scopes) and Azure AD (AAD) roles.

Microsoft Graph Security API supports two types of application authorization:

  • Application-level authorization, where there is no signed-in user (e.g. a SIEM scenario).
    Here the permissions/scopes granted to the application determine authorization.
    Note: this option can also support cases where Role-Based Access Control (aka RBAC) is managed by the application.
  • User delegated authorization, where a user who is a member of the AAD tenant is signed in.
    Here the user must be a member of an AAD Limited Admin role - either Security Reader or Securty Administrator, in addition to the application having been granted the required permissions

We distinguish between two types of client applications: the Microsoft Graph Explorer, and custom client applications.

If calling from Graph Explorer:

  • The AAD tenant admin must explicitly grant consent for the requested permissions to the Graph Explorer application
  • The user must be a member of the Security Reader Limited Admin role in AAD (either Security Reader or Security Administrator)
  • Note: Graph Explorer does not support application-level authorization

If calling from a custom/your own application:

  • The AAD tenant admin must explicitly grant consent to your application. This is required both for application-level authorization as well as for user delegated authorization
  • If using user delegated authorization, the user must be a member of the Security Reader or Security Administrator Limited Admin role in AAD

The following section contains a detailed technical explanation of using the Authorization mechanisms.

 

Managing authorization in Microsoft Graph Security API client applications

Security data provided via the Microsoft Graph Security API is sensitive and must be protected by appropriate authentication and authorization mechanisms. To register and create a client application that can access the Microsoft Graph Security API, the following steps must be performed:

Who

Action

Application developer or owner

Register application as an enterprise application

Tenant Admin

Grant permissions to the application

Tenant Admin

Assign Limited Administrator roles to users

Application developer

Sign-in as the user and use application to access Graph Security API

 

To clarify:

  • Application registration only defines which permissions the application needs in order to run.
    It does NOT grant these permissions to the application.
  • The Azure AD tenant administrator MUST explicitly grant the permissions to the application.
    This MUST be done per tenant and performed every time the application permissions are changed in the application registration portal.
  • Let’s assume we have: an application: App, two AAD tenants: T1 and T2, and two scopes, or permissions: P1 and P2.
    • Application App registered to require permission P1
    • When users in tenant T1 get an AAD token for this application, the token does not contain any permissions (see next bullet)
    • The AAD Admin of tenant T1 explicitly grants permissions to the application App. From this moment on, when users in tenant T1 get an AAD token for App, it will contain permission P1
    • When users in tenant T2 get an AAD token for application App, the token does not contain any permissions - because the admin of tenant T2 did not yet grant permissions to App.
      The procedure of granting permission must be performed per tenant and per application
    • The application App has its registration changed to now require permissions P1 and P2
    • When users in tenant T1 get an AAD token for App, it only contains permission P1. Permissions granted to an application are recorded as snapshots of what was granted -
      they do not change automatically after the application registration (permission) changes
    • The admin of tenant T2 grants permissions P1 and P2 to the application App.
      From this moment on, when users in tenant T2 get AAD token for App, the token will contain permissions P1 and P2

Note: for the same application (App), the AAD token for the application in tenant T1 and that for the application in tenant T2 contain different permissions, since the tenant admins each granted different permissions to the application (App)

  • To make App work again in tenant T1, the admin of tenant T1 must explicitly grant permissions P1 and P2 to the application (App)

Register an Application in v2.0 endpoint

Reference link

What you need:

Application Name: a string used for the application name

Redirect URL: where the authentication response from AAD is sent to.
To begin with, you can use the test client web app homepage.

Required Permissions: the permissions that your application requires to be able to call Microsoft Graph

What you need to do:

  1. Go to https://apps.dev.microsoft.com/ and sign in.
    Note: there is no need to be a tenant admin. You will be redirected to “My applications” list
  2. Click the “Add an app” button, and enter an Application Name to create a new application
  3. It will navigate to the registration page for the new application.
    Click “Add Platform”, choose “Web”. In the Redirect URL, enter the Redirect URL.
  4. Go to section “Microsoft Graph Permissions” and under “Delegated Permissions”, click the “Add” button. A popup dialog appears; choose required permissions (aka scopes).
    See this document for detailed scopes. The Microsoft Graph Security API requires “SecurityEvents.Read.All” scope for GET queries, and “SecurityEvents.ReadWrite.All” scope for PATCH/POST queries.
  5. Scroll down to the bottom of the page and click on the “Save” button

What to save for future steps:

  • Application Id
  • Redirect URL
  • List of required permissions 

Granting Permissions to an Application

Application registration only defines which permission the application requires - it does not grant these permissions to the application. An Azure AD tenant administrator must explicitly grant these permissions by making a call to the admin consent endpoint.

Reference link 

What you need:

Application Id: the application ID from application registration portal

Redirect URL: the string you set in the application registration portal for authentication response

What you need to do:

In a text editor, create following URL string:

https://login.microsoftonline.com/common/adminconsent?client_id=<Application Id>&state=12345&redirec...

In a web browser, navigate to this URL, and sign-in as a tenant administrator; the popup dialog shows the list of permission the application requires, as specified in the application registration portal.
Click “OK” to grant the application these permissions.

Note: this step grants permissions to the application - not to users. This means that all users belonging to the AAD tenant that using this application will be granted these permissions - even non-admin users 

Assigning AAD roles to users

Once an application is granted permissions, everyone with access to the application (i.e. members of the AAD tenant) will receive the granted permissions. To further protect sensitive security data, the Microsoft Graph Security API also requires users be assigned the Azure AD Security Reader role.

Reference links: admin role  assign roles

What you need:

A tenant admin must perform this step

What you need to do:

The admin must:

  • Sign-in to azure portal (http://portal.azure.com)
  • In the menu, select Azure Active Directory > Users
  • Select the name of the desired user
  • Select Manage > Directory role
  • Select “Limited administrator”, check the checkbox “Security reader”
  • Click on the “Save” button to save the change

Create an authentication code

Reference link

What you need:

Application ID: the application ID from application registration portal

Redirect URL: where the authentication response from AAD is sent to.
To begin, you can use http://localhost or the test client web app homepage

Application Key (optional): the key of the application, used when developing an application that will use application-only authentication code (i.e. will not support user delegated authentication)

What you need to do:

There are code samples demonstrating on how to get authentication tokens for in various kinds of applications, authentication libraries are also provided.

Type of applications

Authentication Library

Desktop apps - iOS

MSAL.framework: Microsoft Authentication Library Preview for iOS

Desktop apps - Android

Microsoft Authentication Library (MSAL)

Desktop apps - .Net

Microsoft Authentication Library (MSAL)

Web apps - JavaScript SPA

Microsoft Authentication Library for JavaScript Preview

Web apps - .Net Web Server

OpenIdConnection, Cookies, SystemWeb

Web apps - NodeJS Web App

 

 

If the applications do not use any of the existing libraries, please follow this doc

  1. Get a code from AAD. The query to call contains parameter for Application ID, Redirect URl and required permissions.
  2. Use the code to get an access token

If you use OpenId Connect library, please see this doc and call app.UseOpenIdConnectAuthentication()

Note: In the library, when requesting user delegated authentication tokens, the parameter for the library is “Requested Scopes”. Use “User.Read” for this parameter instead of using whatever the registered application requires. The “Requested Scopes” parameter does NOT affect the permissions contained in the returned authentication tokens, since these are determined by the permissions that the tenant admin granted the application.

Using .Net MSAL library as example:

var accessToken = (await client.AcquireTokenAsync(scopes)).AccessToken;

Note that scopes in above example should be minimum permission such as “User.Read”. However the returned access token can contains scopes such as “User.Read.All” or “User.ReadWrite.All” which were granted by tenant admin for current user tenant.

What You receive:

A token (string) is returned by AAD that contains your authentication info and the permissions required by the application. Assign this token to the HTTP header as a bearer token, as in the code below:

request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);

Microsoft Graph will validate the information contained in this token and grant, or reject, access. 

To view claims contained in the returned token, use NuGet library System.IdentityModel.Tokens.Jwt.

JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

var securityToken = tokenHandler.ReadToken(accessToken) as JwtSecurityToken;

  

In case you encounter an Authentication failure

The response from Microsoft Graph contains a header called client-request-id, which is a GUID.
If access is denied, please specify this GUID when seeking support, so we can help investigate the cause of this authentication failure.

9 Replies

Hi,

 

I'm trying to access the secure score endpoint via my app. The app and user have the required permissions as per this post, however, I am still getting a 403 when attempting to call any of the security endpoints. The app is able to successfully call other graph endpoints.

Is it possible to get more info about exactly why access is denied? The response body just states that the token or user do not have required permissions. An example request id is: "b58137f1-37ea-40fb-93bb-20497b922df6".

 

The same user is able to make requests to the endpoint just fine using the Graph Explorer app. I have also compared the token permissions in the scp claim and given my app (and token) identical permissions but still, I get 403!

 

Have been struggling with this for some time now. Seemingly everything is configured correctly. Anything to shed some more light on exactly what is required would be greatly appreciated.

 

Thanks,

Matt

Hi Matt,

 

To access SecureScore, you need to meet the product's Role-Based Access Control (RBAC) - in this case to belong to one of the groups listed below - broken out into Read access and Write access:

(for convenience, listing both required Graph Scopes and AAD Roles):

 

Read:

Scopes

 

  • GraphPermissions.SecurityEventsReadAllScope

Roles    

  • AadRoles.ExchangeServiceAdministratorRole
  • AadRoles.SharePointServiceAdministratorRole
  • AadRoles.HelpdeskAdministratorRole
  • AadRoles.UserAccountAdministratorRole
  • AadRoles.ServiceSupportAdministratorRole
  • AadRoles.SecurityReaderRole
  • AadRoles.SecurityAdministratorRole
  • AadRoles.CompanyAdministratorRole

 

Write (Patch):

Scopes:

  • GraphPermissions.SecurityEventsReadWriteAllScope

Roles:

  • AadRoles.SecurityAdministratorRole
  • AadRoles.ExchangeServiceAdministratorRole
  • AadRoles.SharePointServiceAdministratorRole
  • AadRoles.CompanyAdministratorRole

Hope this helps - great if you could confirm after applying the above

Michael

Hi Michale,

 

Thanks very much for coming back to me.

 

So the user and the app appear to have the appropriate roles/permissions. I even went so far as granting the app all possible permissions and giving the user all possible roles. I have created new test users and new app registrations and tried many other things. Still, I'm getting a 403.

 

This makes me think it's somehow not a problem with permissions but some other configuration issue with the app, ad or tenant. I'm using our companies sandbox tenant, so other engineers are always playing with the config. I plan on trying it out on a different tenant once one becomes available to me.

 

Are you aware of any configuration other than permissions or roles which might cause a 403 response from this endpoint?

 

Thanks again.

 

Matt

 

Edit 16 Oct '18:

 

So I have tried another tenant and am facing the same issue...

 

I think it must be a problem with the configuration of my app since all the users I have tried have access to the secure score via other means (Web portal and Graph explorer app).

 

The app is a JS SPA using the MSAL-Angular library and the implicit auth flow. The MSAL config is as follows:

 

consentScopes: [
  'User.Read',
  'SecurityEvents.Read.All'
],
protectedResourceMap: [
  [
'https://graph.microsoft.com/beta/organization',
['User.Read']
],
  [
'https://graph.microsoft.com/beta/security/secureScores',
['SecurityEvents.Read.All']
]
]

 

I have tried many other configurations but this is the simplest I believe should work.

 

Any ideas what I might be doing wrong?

 

Thanks again.

 

Matt

Hi Brandon,

Yes, App-only AuthNZ is also supported - and covered in the documentation - please note that this approach assumes that Role Based Access Control (RBAC) will be implemented by the calling application.

The Graph Security API GitHub code samples include a C# Auth Helper App that will let you test and see the contents of the Auth token - both for User/Delegated or for App-only (different tabs).

Also make sure you specify the required scopes for App-Only during app registration 

 

Hope this helps

Michael

Michael,

 

I appreciate your reply! I was still not able to find a code example of app authenticate. All of the listed example only contain code for user it seems unless I keep over looking something. I might just be misunderstanding something due to inexperience but I appreciate your help thus far

Hi Brendon,

You can download the Auth Helper sample code here:
https://github.com/microsoftgraph/Graph-Security-API-Auth-Sample

When you compile and run the application, you'll see three tabs in the app's UI:

  •  User delegated authorization
  • Application-only authorization
  • Help

Select the second, and provide the AppId and AppKey (Secret) - after verifying that you defined App-Only permissions in the app registration (http://apps.dev.microsoft.com

 

I hope this solves the issue for you

Michael

Hey @Michael Shalev, thank you for the insight on api authorizations!

Are there any security implications to be wary of when granting application-level authorization for an application? or is this merely the same authorization level as the delegated privileges but without the need for a user sign-in?

@jyisas There are significant security considerations when using application auth, specifically: this will bypass role based access control (RBAC) enforcement which is defined and enforced at user level, i.e when User/Delegated auth mode is used.

The recommended practice when using app-level auth would be to enforce necessary access control in the app calling the Graph Security API

@Michael Shalev

 

It's unfortunate that there is no option  to use the "Security Operator" role just for the implementation use cases where there is only the requirement to read and update (e.g. close) MS Graph Security API security alerts under a delegated permissions scenario. In that case the only option available seems to require the "Security Admin" role to be assigned. At the same time there are also challenges with monitoring and alerting options if we use app-level auth.