How do you authorize Outlook.com with Microsoft Graph? - office365api

Cut my life into pieces, this is my last resort.
Seriously, I can't find this info anywhere! I thought Graph supported Outlook.com. I saw this question which referenced the Outlook Api vs the Graph Api, but how do I authorize an Outlook.com account for this?
I'm sending the user to https://login.microsoftonline.com/common/oauth2/authorize with the parameters:
response_type = code
client_id = <my client id>
redirect_uri = <my redirect_uri>
state = <csrf>
resource = https://outlook.office.com/
to sign in. It takes them to the Office 365 sign in, and when you type #outlook.com, it tries to redirect you, only to go back to the 365 login page and do it all over.
I can authorize Office 365 just fine, but not Outlook.com. I can provide more info if needed, I just figure I'm hitting the wrong endpoint or something.

Currently we have two versions of the authentication endpoint. The version less endpoint (https://login.microsoftonline.com/common/oauth2/authorize) only supports work and school accounts (Office365) the v2.0 auth endpoint (https://login.microsoftonline.com/common/oauth2/v2.0/authorize) supports both work and school and personal accounts.
To use a personal account (hotmail.com, outlook.com, live.com) with Microsoft Graph, you start by registering you app in apps.dev.microsoft.com, then follow the instructions in this article:
https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-scopes/. Try that and let me know how it goes.

Related

Scope "allsites.write" doesn't exist on the resource

I'm trying to set up programmatic access to a corporate Sharepoint Online site from a desktop app. My org has an Office 365 subscription.
I've set up a registered app in the Azure portal, granted the AllSites.Write permission:
Now, I'm trying to navigate to the following URL in a browser control:
URL = "https://login.microsoftonline.com/" + Tenant + "/oauth2/v2.0/authorize?" +
"client_id=" & ClientID +
"&response_type=code" +
"&redirect_uri=foo%3A%2F%2Fback" +
"&response_mode=query" +
"&scope=user.read%20allsites.write"
As soon as I do that, there's no UI, I immediately get a callback with the following error message:
AADSTS650053: The application 'MyApp' asked for scope 'allsites.write' that doesn't exist on the resource '00000003-0000-0000-c000-000000000000'. Contact the app vendor.
The scope is right there. What am I missing?
The same logon flow worked with a slightly different scope (Sites.ReadWrite.All), but then I found out that the Graph API didn't expose SharePoint list item attachments and decided to fall back to the legacy SharePoint REST API. Changed the scopes on the portal, changed the scopes in the logon URL, got the error.
The stale logon session couldn't get in the way, could it? Normally, when scopes change, the OAuth UI pops the permissions window, doesn't it?
Got past this error, but now Sharepoint Online doesn't accept my token, says "Invalid issuer or signature". For the record, when I provide the scope https://microsoft.sharepoint-df.com/AllSites.Write or https://{mytenant}.sharepoint.com/AllSites.Write, the logon flow works.
UPDATE: accepts now. For that, I had to use the older version of the OAuth endpoints: https://login.microsoftonline.com/{tenant}/oauth2/authorize for initiation of the logon flow, and https://login.windows.net/{tenant}/oauth2/token?api-version=1.0 to exchange the code for the token. The latter takes the resource parameter, which is to be https://{tenant}.sharepoint.com.
The endpoint at https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token, which is specified all over the Graph docs, doesn't take the resource parameter, which seems to be essential here (or maybe it's called something else).

Getting invalid authorization_code, error AADSTS70000: The provided value for the 'code' parameter is not valid. The code has expired

I'm using an Office 365 Family account, and getting an incorrect authorization code back, using the following url:
'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=[CLIENT ID]&response_type=code&redirect_uri=[REDIRECT URI]&response_mode=query&scope=offline_access%20Calendars.ReadWrite%20Files.ReadWrite.All%20User.Read%20openid%20profile&state=12345';
The code I received on one attempt was: M.R3_BAY.44e411b5-8fcf-f0be-2356-d56fd3293055, and they all have that format whenever I try, which is not what it should be like, and does not decode on jwt.
Can anyone please tell me what's going wrong? I've been searching for months for an answer without any luck.
If this is the authorization code, it is not meant to be decoded.
You are supposed to exchange it for tokens, which are in JWT format.
Documentation: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-access-token
If this is in fact an access token, it could be for a personal Microsoft account. I've seen different format tokens there before.
You currently allow all Office 365 accounts and personal Microsoft accounts since you use common endpoint on v2.0.
If you only mean to support all Office 365 accounts, you can use organizations instead.

Unable to access users calendar using application daemon token

I have been trying to access a user's data using the MS graph API. I have been following the official documentation and I have correctly configured the apps and the permission.
I am also following this code_sample and using this I have been able to fetch the daemon token for the application.
Using the token I am able to successfully fetch the data against the following endpoint:
https://graph.microsoft.com/v1.0/users/204e3e4f-xxxx-xxxx-xxxx-509934e1
The data looks like:
{"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users/$entity","businessPhones":[],"displayName":"developers#outlook.com Tiwari","givenName":"developers#outlook.com","jobTitle":null,"mail":null,"mobilePhone":null,"officeLocation":null,"preferredLanguage":null,"surname":"Tiwari","userPrincipalName":"developers_outlook.com#EXT##webdevelopers.onmicrosoft.com","id":"204e3e4f-x-xxxxx-xxxxxxx-509934e14fa8"}
However, I can't fetch any more data than this. All the other endpoints throw a 401 Unauthorised exception even when I have checked all the Application permission for my app.
I am trying to hit the following endpoints for fetching calendar of the above user:
https://graph.microsoft.com/v1.0/users/204e3e4f-xxxx-xx-xxxxz-509934e14fa8/calendar
https://graph.microsoft.com/v1.0/users/204e3e4f-xxx-xxx-xxxxx-509934e14fa8/calendars
both of these give 401.
Can someone suggest if I am missing something. I even decompiled my jwt token and it clearly shows all the following scopes added:
"roles": [
"Schedule.ReadWrite.All",
"OnlineMeetings.Read.All",
"Mail.ReadWrite",
"OnlineMeetings.ReadWrite.All",
"User.ReadWrite.All",
"Calendars.Read",
"Mail.ReadBasic.All",
"Files.ReadWrite.All",
"User.Read.All",
"Schedule.Read.All",
"Files.Read.All",
"Organization.ReadWrite.All",
"Mail.Read",
"Calendars.ReadWrite",
"Mail.Send",
"Organization.Read.All",
"Mail.ReadBasic"
],
Please help.
To get access to calendar events you should call the following endpoint:
GET /users/{id | userPrincipalName}/events
The documentations for calendars is here: https://learn.microsoft.com/en-us/graph/api/user-list-events
From your comment on Chris Johnson's answer, you're using a personal account. App-only tokens won't work to access a personal account, and you shouldn't be able to even obtain one using a personal account, since there's no concept of an admin.
App-only requires an admin to consent, and when she does, she grants access to all resources in her tenant. Personal accounts are not in work/school tenants, so they aren't in scope. Even if you've added that personal account as a guest in the work/school tenant, their calendar is hosted outside of the tenant, and is off limits.

How to simply get a bearer token to send requests to Azure DevOps API?

I need to create an organizational feed to host nuget packages shared among projects on our Azure DevOps environment.
After several unsuccesful attempts and research, I discovered that the only way to create an organizational feed is, by design from Microsoft mouth, the Azure DevOps API.
Source for the claim : This question on VS dev community
and The MS docs on project-scoped feeds
Basically, I just need to be able to perform a POST here :
https://feeds.dev.azure.com/{organization}/_apis/packaging/feeds?api-version=5.1-preview.1
with the body :
{
"name": "{myfeedname}",
"hideDeletedPackageVersions": true,
"upstreamEnabled": true
}
And of course, a Bearer token to authenticate myself. That's the point where I'm confused.
What is the simplest way to obtain one ? I'm logged in through my company Microsoft AD account on my computer browser on Azure DevOps. I don't see any Bearer token that I can "steal" to use in PostMan in my browser dev tools.
The API docs described some relevant info, but I'm confused on how to use it in Postman :
Security oauth2
Type: oauth2
Flow: accessCode
Authorization URL: https://app.vssps.visualstudio.com/oauth2/authorize&response_type=Assertion
Token URL: https://app.vssps.visualstudio.com/oauth2/token?client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
Scopes Name Description
vso.packaging_write Grants the ability to
create and read feeds and packages.
Here is the interface in Postman for OAuth2:
Ican see how the info in the docs relates to the fields 1 - 2 - 3 - 4, but then, what callback url should I use ? What credentials ? my Microsoft email + password from AD ?
I tried this, and all I seem to get is this from Postman :
{"$id":"1","innerException":null,"message":"A potentially dangerous Request.Path value was detected from the client (&).","typeName":"System.Web.HttpException, System.Web","typeKey":"HttpException","errorCode":0,"eventId":0}
TLDR
How do I properly proceed to get a token with Postman, or other tool to manually execute my one-time request to Azure DevOps REST API ?
notes :
Following info here : Unable to get Authorization code for Devops using Postman oAuth2.0
, leading here : https://github.com/Microsoft/azure-devops-auth-samples/tree/master/OAuthWebSample , I understand that I have to register and run a whole web application. Am I understanding this correctly ? I there a simpler way ?
I understand that I have to register and run a whole web application. Am I understanding this correctly ? I there a simpler way ?
Yes, you are right. You have to register whole web application.
As the interface in Postman for OAuth2, we need provide the CallbackUrl, ClientID, ClientSecret and so on. Then, we check the document Requesting an OAuth 2.0 token, we could to know the Callback URL is:
The client application callback URL redirected to after auth, and that
should be registered with the API provider.
So, we have to register an OAuth client app in Azure DevOps (https://app.vsaex.visualstudio.com/app/register), then we could get the following information, like:
You could check the document Authorize access to VSTS REST APIs with OAuth 2.0 for some more details.
AFAIK, there is currently no simpler way to get a bearer token to send requests to the Azure DevOps API.
Hope this helps.

Get Azure AD directory users in a Rails app

I have a Rails 6 application and I want to use Azure Active Directory as an authentication system (with open id connect, saml2 and ldap).
The authentication is done.
Now I am trying to display user information like names or email addresses. I also want to be able to export all users of a directory.
I have tried to set a configuration up like so:
In my Rails app, in the admin panel, an admin can configure Azure AD for my application
in the config, the admin copies and pastes the configuration link provided by Azure AD (a JSON response)
Then, copies and pastes the app client_id
Then, the tenant_id (directory id)
Here is a piece of code that I expected to work:
def update_oidc
identity_provider = IdentityProvider.find_by(provider_type: 'open_id_connect', id: params[:id])
client_id = params[:client_id].strip
metadata_url = params[:metadata_url].strip
tenant_id = params[:tenant_id].strip
metadata = HTTParty.get(metadata_url).parsed_response
identity_provider.update(config: {
metadata: metadata,
metadata_url: metadata_url,
client_id: client_id,
tenant_id: tenant_id,
})
if tenant_id
directory_access_url = "https://graph.windows.net/#{tenant_id}/users?api-version=1.6"
result = HTTParty.get(directory_access_url).parsed_response
identity_provider.directories.find_or_create_by(tenant_id: tenant_id).update(
business_phones: result["business_phones"],
display_name: result["display_name"],
given_name: result["given_name"],
job_title: result["job_title"],
email: result["user_principal_name"],
mobile_phone: result["mobile_phone"],
office_location: result["office_location"],
surname: result["surname"]
)
end
redirect_to identity_provider
end
As the tenant_id is the directory id, i thought that we might be able to access user info this way (and following the Microsoft Docs). The thing is, it doesn't work because even though I'm connected to my Azure AD directory in my app, when I run result = HTTParty.get(directory_access_url).parsed_response, i have an authentication error telling me the token has expired or that i need to be connected.
I don't want to use PowerShell or anything like this. I want to be able to access directories data through my app.
Can someone tell me what i'm doing wrong or come up with an idea ?
Thanks
Just according to your code, I think you want to get the collection of users via the Azure AD Graph REST API Get users using jnunemaker/httparty library.
However, it seems to be missing the required header Authorization with its value like Bearer eyJ0eX ... FWSXfwtQ as the section Authentication and authorization of the offical document Operations overview | Graph API concepts said. Meanwhile, you have done the authentication with OpenID Connect, but Azure AD Graph API requires the access token as Authorization value from OAuth2 as the content below said.
The Graph API performs authorization based on OAuth 2.0 permission scopes present in the token. For more information about the permission scopes that the Graph API exposes, see Graph API Permission Scopes.
In order for your app to authenticate with Azure AD and call the Graph API, you must add it to your tenant and configure it to require permissions (OAuth 2.0 permission scopes) for Windows Azure Active Directory. For information about adding and configuring an app, see Integrating Applications with Azure Active Directory.
Azure AD uses the OAuth 2.0 authentication protocol. You can learn more about OAuth 2.0 in Azure AD, including supported flows and access tokens in OAuth 2.0 in Azure AD.
So I'm afraid you have to get the access token manually via OAuth2 for Azure AD again for using Graph API, or just simply refer to the sample code samples/authorization_code_example/web_app.rb using the adal library of GitHub repo AzureAD/azure-activedirectory-library-for-ruby for Ruby.

Resources