I'm trying to access the signed in user's Profile Photo in the context of an email app which uses EWS to connect to Office 365.
The app is registered on portal.azure.com with the following required permissions:
Office 365 Exchange Online -> Access mailboxes as the signed-in user via Exchange Web Services
Windows Azure Active Directory -> Sign in and read user profile
The EWS part works just fine, I'm able to sign the user in, get the access and refresh tokens, and perform EWS operations using "Authorization: Bearer access_token".
The part I'm having trouble with is getting the user's profile photo.
This is the docs I'm going by:
https://msdn.microsoft.com/en-us/office/office365/api/photo-rest-operations
The API endpoint I'm trying to use is:
GET https://outlook.office.com/api/v2.0/me/photo
... with "Authorization: Bearer access_token" header.
The above API returns this response:
HTTP 403
{"error":{"code":"ErrorAccessDenied","message":"Access is denied.
Check credentials and try again."}}
What could be wrong?
According to the above docs, getting user's photo should be possible using the user.read scope.
The "Sign in and read user profile" permission I mentioned above has a tooltip saying "User.Read", so I believe that's the right scope
I've tried decoding my access token at jwt.io, it has: "scp": "full_access_as_user" - where is my User.Read scope, or does "full access" include "user.read"?
Any ideas?
This is because that you tried use v2 endpoint Rest API but you didn't register the Application with v2 endpoint.
User Photo API is only available on Azure AD v2 authentication endpoint, Not Azure AD and Oauth:
You need to go to Microsoft Application Registration Portal to register your Application. For more details , you can refer to this document.
Just for the record:
Since we were not able to use OAUTH2 APIs for this -
since and our app uses EWS (Exchange Web Services) already...
We just ended up using the GetUserPhoto command with the user's (account's) own email address.
Works fine.
Related
So I am writing a .NET 6 Core Web Api using Azure AD as authentication for the API.
Now when using Graph API as example, you need to setup Graph API scopes in the App Registration. Lets use a delegated "user.read" permission for this example.
I use Postman to receive the access token for the application by authenticating as an user against Azure AD for the API. I would expect to receive a consent-screen so I can consent to the usage of "user.read". This does not happen though.. I get logged in and receive a valid access token. In the Backend though, it will throw an error because the user / admin did not consent to the application.
How do I get around this? Why don't I get asked to consent the permissions set up in the app registration? Neither in Postman, nor in a Swagger oAuth Flow..
My current workaround for this is to use a React application and sign in over the frontend application. Using the frontend application, I get asked to consent to the permissions. After consenting, I can use postman without getting the "user didn't consent" - error.
Any ideas? What did I miss?
Let's focus on the user-consent page first. When we created an azure ad app then add api permission for it, then use this azure ad app to make your .net 6 app/react app integrate azure ad to use azure authentication, and we go to the microsoft sign in page and successfully sign in, we will see a dialog which indicating that this app require you to consent a list of permissions. The permissions are correspond to the api permissions you set for the aad app. After consent once, then it won't ask you to consent again when sign in next time.
This consent only happened when users are signed in. Let's go back to the flows used to generate access token in Azure AD. Since you used delegate permission, then you may used the recommend Auth code flow(Another flow called ROPC flow can also generate delegate access token but not recommended). When we used auth code flow, we need to sign in first, the login url should look like this:
https://login.microsoftonline.com/tenant.onmicrosoft.com/oauth2/v2.0/authorize?client_id=azure_ad_app_id
&response_type=code
&redirect_uri=http://localhost/myapp/
&response_mode=query
&scope=user.read
&state=12345
We need to use it to get the auth code, then we can use the code to generate access token, per my test, I created a new azure ad app and when I directly hit this url in the browser and sign in, it still required me to give the consent. So I'm afraid the reason why you didn't see the dialog when test in post man is that you've consent it when test in react app, or you don't use auth code flow.
I've been trying to expose an API through azure API Management and I can't figure out what I'm doing wrong. Here's the situation:
My API is going to be called from an external application
They don't have an Azure Account in the same tenant
I want to enable external calls for my API by just using a subscription key (hence, why I'm using API Management), but also want to keep my actual API secured with Azure AD.
I have an API which is secured with Azure AD using OAuth2 and published into a Windows AppService
I have an App registration for that API, which i use to authenticate (it works from postman, for example)
app registration
I have Managed Identities turned on and permissions set.
I have added the API in API management
I added the authentication-managed-identity inbound rule, used the API Id Uri of the app registration as the resource value for it.
Api Management Config
When testing an endpoint from the APIM interface, I can successfully get a bearer token, but I get a 500 exception from the API which says: Neither scope or roles claim was found in the bearer token
bearer response
Here is the decoded bearer token, it doesn't have a scp attribute
bearer decoded
I'm not sure where I can specify a scope. If I use the full scope uri (api://guid/access.api.management) it will fail when trying to get a bearer token (The resource principal named api://guid/access.api.management was not found in the tenant).
I've even tried adding the Owner role to the APIM Identity for the AppService.
Maybe I'm not using this correctly, I'm pretty new at using Azure cloud and API Management so any suggestions are welcome.
Thanks.
You have expose an api protected by Azure, and currently you have an api application. Next, you need to create another application that represents the client, and then add the client application to the api application.
Next, go to the client application.
Under 'API permissions' click on 'Add permission', then click on the 'My APIs' tab.
Find your api application and select the appropriate scope.
Click 'Add permissions'.
Grant admin consent for your APIs.
Next, you need to use the auth code flow to obtain an access token,which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
1.Request an authorization code in the browser.
https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize?
client_id={client app client id}
&response_type=code
&redirect_uri={redirect_uri}
&response_mode=query
&scope=api://{api app client id}/{scope name}
&state=12345
2.Redeem token.
Parse the token:
I managed to get it working using the client credentials flow and storing the client secret in key vault.
I am new to Microsoft Graph API. I have read many articles on the web to understand the usage of Microosft Garph API for managing users in Azure AD. I am creating a Springboot based REST API service, which needs to create users in Azure AD.
I have registered my application in Azure Active Directory. I have also 'Directory.ReadWrite.All" permission for Microsoft Graph API. I wanted to first try to create the user from Microsoft Garph explorer. In the Graph Explorer, I have to give authorization token in the Request header. In order to create authorization token, I have followed the instruction given in the link https://learn.microsoft.com/en-us/graph/auth-v2-user. I have created the following URL based on the instruction, for obtaining Access token.
https://login.microsoftonline.com/{mytenantID}/oauth2/v2.0/authorize?client_id=validclientID&response_type=code&redirect_uri=https://localhost:4200&response_mode=query&scope=Directory.ReadWrite.All&state=12345
When the above URL is accessed from the web browser, I get a message which says "Need Admin Approval". I am not the admin of the Azure AD and I do not have access to the admin of my client, so I am really stuck. Can anybody help me understand whether I will have to get admin consent each time I need to access "create user" functionality of Azure AD through MS Graph API? . I would also also need the create user functionaltiy in the Springboot API. In this case, how would Admin Consent work?. Is there anyway that the create user functionality can work without Admin consent.
I have read the following two questions in SO before posting this question
How can I find the Admin Consent URL for an Azure AD App that requires Microsoft Graph "Read directory data" permission?
Create user using Microsoft Graph
if you just want to create a user in your tenant , you can follow the steps below :
Create a new Azure AD app in your tenant, ask your tenant admin to grant "Directory.ReadWrite.All" permission to this app :
Create a app secret for your Azure AD app :
Use this secret and this Azure AD app ID to get access_token to call Microsoft Graph API :
Request URL :
POST https://login.microsoftonline.com/<-your tenant name->/oauth2/v2.0/token
Request Header :
Content-Type: application/x-www-form-urlencoded
Request Body:
grant_type:client_credentials
client_id:your client Id
client_secret: Your application secret
scope=https://graph.microsoft.com/.default
You will get an access_token from this API calling.
See the screen shot below:
3. Using the access_token we just created to call Microsoft Graph API to create a user :
As you can see , a user has been created :
If you have any further concerns , pls feel free to let me know : )
I can login to Outlook 365 in my web with MS Graph without user action. I'm using simple-oauth2 module and oauth2.ownerPassword.getToken method to generate tokens with username/password from my database.
I'd like embed Outlook.com in my web for each user (with their credentials).
Is there any way to do this?
Why would you do that?
If your application already lets the user login with Azure Ad account, you could use the on-behalf-of flow. Then your web application can request a token for another resource by sending the access token of the user for the current application.
If they aren’t logged in to Azure ad already you could have a look at the client credentials flow. Then your application will just get a token with access to all mailboxes.
I am working on a Sharepoint application. For my application, I have to fetch my details from Azure AD using Microsoft graph endpoints. I have generated the access token using /token endpoint and client_credentials grant type. When I use the token received in the response with the graph /users endpoint, I am getting an unauthorized error as shown in the below image:
On azure portal, all permissions are granted to microsoft graph API. Is there any configuration that is missing? How can I solve this unauthorized error?
Have not test with a v2.0 endpoint, if it is acceptable to use a v1.0 endpoint, you could refer to the steps.
1.Navigate to the Azure Active Directory in the portal -> App registrations -> New application registration, more details see this link.
2.Go to the AD App -> Keys -> generate a key for the AD App, copy the key value.
3.Then go to the Required permissions -> Add -> select the Microsoft Graph and Read all users' full profiles in the APPLICATION PERMISSIONS -> Save , note then don't forget to click the Grant permissions button.
4.I test it in the postman, specific the body what we need to get the access_token, the
client_id is the Application ID of the AD App, client_secret is the key vaule you copied, grant_type is client_credentials, resource is https://graph.microsoft.com/.
Sample:
POST https://login.microsoftonline.com/<Tenant ID>/oauth2/token?api-version=1.0
5.Use the access_token to call MS Graph API, in my sample, I call the List users api, it works fine.
I think you are missing the right scope in the token to use the "User" Endpoint.
Possible Scopes are:
User.ReadBasic.All
User.Read
User.ReadWrite
User.Read.All
User.ReadWrite.All
For further detail pls look here