OAuth 2.0 {"error_description":"Invalid issuer or signature."} in Postman - azure

I'm trying to execute a REST API call in SharePoint Online. For this, I wanted to see if I can register an app in Azure AD. I believe I was able to do so and I'm able to get back a token. However, upon executing the GET request Postman always throws {"error_description":"Invalid issuer or signature."}in the body of the response.
Here're the screenshots detailing everything:
Don't mind the Postman variable {{TenantID}}. That's not the issue, I also tried with the writte-out tenant ID - doesn't make a difference.
So what I was unsure about at first was the 'Scope' parameter in the "GET NEW ACCESS TOKEN" in Postman. I tried various scopes, for example
'Sites.FullControl.All' or 'https://microsoft.sharepoint-df.com/.default'. But that didn't change the outcome. Still, is the scope I set correct for SharePoint REST API? I know that for the Microsoft Graph 'https://graph.microsoft.com/.default' works.
I also tried different app permissions, not just
'Sites.FullControl.All'
Do you have any idea what the cause of the error might be?
Thanks.

The sharepoint permission Sites.FullControl.All is of type Application.
For this type of permission you MUST use the client_credential flow.
The Client Credentials grant is used when applications request an
access token to access their own resources, not on behalf of a user.
Try to call the auth url with:
grant_type=client_credentials
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx
Otherwise if you want to access the Sharepoint on behalf of the user change the permission type to delegated

Related

I am not able to approve my Azure active directory (PIM) pending request programmatically through Graph API?

I am try to approve the prividedge identity management (PIM) request through graph api but when i try to approve it the api is return forbidden. See the below screenshots
The pending request should be approved.
First, I want to know what API permission you consented for using this graph API, because to be honest, I didn't find this graph API, I only found this document which contained the API request you used.
According to the error message, I'm afraid you gave the wrong api permission or you used client credential flow to generate the access token to call the API. So it's better to provide the request you used to generate access token.
Finally, I found an answer here which successfully call the API but with Powershell script. According to this sample, we should give PrivilegedAccess.Read.AzureAD,RoleAssignmentSchedule.ReadWrite.Directory,PrivilegedAccess.ReadWrite.AzureAD delegated API permission and use it to generate access token. We need to use auth code flow/ROPC flow so that the token generated should contain scp claim with API permissions as value. Then using that token to call the API.
You may try request below to generate the access token for a test:
POST https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id=azure_ad_app_id_consented_api_permission
&scope=PrivilegedAccess.Read.AzureAD RoleAssignmentSchedule.ReadWrite.Directory PrivilegedAccess.ReadWrite.AzureAD
&username=user_name_better_to_use_account_with_Global_Administrator_role
&password=password
&grant_type=password

Obtain SharePoint specific access token for a non-user application

I am working on a PHP web app that needs to make HTTP requests to the Sharepoint API with Sites.Selected permission to a specific SharePoint site. It is NOT viable for me to provide a user sign-in experience so I need to treat it as a non-user/daemon application.
I've read the docs and looked at many different forums for the solution but as of yet I've been unsuccessfull in obtaining a SPO specific access token, although I think I'm close.
I am using this StackOverflow answer as a guide: https://stackoverflow.com/a/63386756/19038862
This is what I've done:
Registered an Azure App: (Image of my Azure App Overview)
Created a client secret in the App dashboard: (Image of the client secret page)
Successfully sent a request to https://login.microsoftonline.com/{{app_tenant_id}}/oauth2/v2.0/token using the client secret in Postman: (Image of Postman request)
The request made in step 3 returns an access token (I assume a MS Graph access token?), but it DOES NOT return a refresh token, which is what the afforementioned StackOverflow answer suggests you need to "swap" for an SPO specific access token.
How do I obtain this refresh token so that I can swap it for a SPO access token? Or what better way is there to get my hands on a SPO specific access token from a non-user app?
I wrote this gist to guide you into getting Sites.Selected access to the desired site:
https://gist.github.com/ruanswanepoel/14fd1c97972cabf9ca3d6c0d9c5fc542
This guide shows you how to configure this as Application permissions, and via the Graph API.
I've found going through the Graph API is the best way to go.
Also strangely it's not possible to get delegated Sites.Selected permissions. You must set it up as an Application permission.
In the guide is described that you have to get a delegated auth token from graph but you are getting an application auth token. The token response of this flow does not contain a refresh_token. See here.
But you already wrote that you are not able to provide a user sign-in experience. One workaround would be to once manually get the access_token and refresh_token of a user with the delegated flow and then periodically get a new access_token with the refresh_token on your server. You could store these values in your database and update them when you fetch a new one.
First, the daemon-based client credential flow does not return a refresh token for you. You also can't redeem the refresh token of the graph API for an access token for SPO, which are two completely different API resources.
To get an access token for SPO you just need to set scope to: https://{tenant-name}.sharepoint.com/.default.

Access token not working Azure AD custom policy

I made a custom policy for Azure B2C, added jwt.ms as a reply URL and everything seems to be working fine. When I log in, I get redirected to jwt.ms showing the token and it's contents. However when I try to link my angular frontend to this custom policy, it does not seem to work. In need the response type id_token token, but when I use this response type I get the error "This application does not have sufficient permissions against this web resource to perform the operation."
When I use the response type id_token it seems to work fine and I get a reply with the JWT token.
I thought the problem might be in the Implicit grant settings under applications, so I have tried enabling Access tokens and ID tokens for all applications but this did not help.
Implicit grant settings
The request looks as follows:
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize
?p=b2c_1a_signup_signin&client_id={client_id}
&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2F&response_type=id_token%20token
&scope=openid%20https%3A%2F%2F{tenant}.onmicrosoft.com%2Fapi%2Fuser_impersonation
&nonce={nonce}
&state={state}
So if you replace the characters it looks like this:
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize
?p=b2c_1a_signup_signin&client_id={client_id}
&redirect_uri=http://localhost:4200/&response_type=id_token token
&scope=openid https://{tenant}.onmicrosoft.com/api/user_impersonation
&nonce={nonce}
&state={state}
I expect the login flow to return both the JWT ID token and an access token.
Edit:
I created a whole new B2C tenant with a standard Signupsignin user flow and I still experience the same issues. So I concluded that it is not a custom policy issue, but an issue caused by a configuration in Azure or the front-end application.
After a lot of experiment I come to know about your problem. I guess you are not trying in a right format. Even I don't know which document you are refereed to. Okay the first problem is...
You are getting this error "This application does not have sufficient permissions against this web resource to perform the operation"
Reason
You have not set API access in your target application on azure portal. To achieve that you have add API access on your application.
Let say you have two Published scopes on your B2C tenant application like below:
Create API Access
To avoid above error Add API access. To do that , go to your application select API access after that you will see a Add button on top. click and right side API access window will be open just click Ok. See the below screen shot:
After successful API Access It should looks like below
Note: Hope It will solve your error while you are trying to send request.
B2C id_token and Access Token
Follow the below steps for Id_token
ID Token Access Process
https://YourB2CTenant.b2clogin.com/tfp/YourB2CTenant.onmicrosoft.com/YourPolicy/oauth2/v2.0/authorize?
client_id= YourApplicationId
&redirect_uri= Your reply from Application
&scope=openid
&response_type=id_token
Take a look below at Id_token:
Note: Just fill out the above format and paste at your browser with no space between. If is it correct then a sign in page will be
prompted. After sign in you will be given id_token on your browser.
B2C Access Token
Follow the below format In POSTMAN:
Grant Type:authorization_code
Callback URL: Your Reply URL
AuthURL:https://YourTenant.b2clogin.com/YourTenant.onmicrosoft.com/YourFlow/PolicyName/oauth2/v2.0/authorize?
Access Token URL:
https://YourTenant.b2clogin.com/YourTenant.onmicrosoft.com/oauth2/v2.0/token?p=YourFlow/PolicyName
Client ID: Your Application Id
Client Secret = Application Key
Scope= any of your Published scopes
Post Man request Process
Go to postman and click on Authorization Tab and Select type as OAuth 2.0 See the below screen shot:
For getting access token click on Get New Access Token You will be prompt following window fill out it with above mentioned format.
After hitting Request Token button you will be prompted a sign in window after successful login you will get access_token in response. Like below:
Note: In B2C there is no supported way to get `Id-Token and access_token together in a single request. You have to achieve it in
separate request. For more details you could refer here
If you still have any problem please feel free to share here in comment. Thank you and happy coding!

Microsoft Graph API: how to get access token without browser

I would like to upload a given file to Sharepoint. I'm using the Microsoft Graph API.
The documentation follows this workflow:
1. If no token, redirect the user to the Microsoft signin page.
2. The user is then redirected to the application, with an access token
3. Use access token to have an authorization bearer
4. Do what you gotta do...
My problem is the sign-in part. I don't want my users to be redirected to the Microsoft signin page. I want my application to connect and get the access token in the background (with cURL or whatever).
How can I do that? Why is the "open in browser" necessary?
I tried to replicate the sign-in process, but all I get back is the HTML response from the signin page.
Thanks in advance.
Your application act as a single-tenant service or daemon app.
The documentation about this scenario is here : https://developer.microsoft.com/en-us/graph/docs/authorization/app_only
The application must be registered in the AzureAD directory corresponding to the Office365 tenant
A first request is made by passing the application unique identifier and secret key as registered in the directory. This request returns an access token
The access token can now be used in the Authorization header of the following request to the Microsoft Graph API.
This method (of using Client ID and Secret) works well but there are other ways which may be better suited for similar scenarios.
The one major thing which is missing in access token generated this way is a user, meaning the token only contains the identity of the OAuth application (client) which called it but is not associated with any user for the request.
This could have a couple of implications:
Since the token is not associated with a specific user you will not know who performed the operation. In your example, you would not know who uploaded the file (and other similar information may be missing).
Access token without users will not work at all for some methods. For those, you need a delegated token.
Creating a delegated token requires some effort, if you are interested you can find the details in my article:
Getting Access Token for Microsoft Graph Using OAuth REST API

How to create user (work account) on Azure Active Directory using Graph API

I am relatively new to Azure Active Directory and the Graph API. My goal is to be able to write a python program which invokes the Graph APIs to create users in the Azure Active Directory. Let us assume that I have the credentials of the Global Admin for my Azure Active Directory.
I am following the documentation provided at this link. I am successfully able to create a user by using the Graph Explorer as I am using the Global Admin's credentials to login. However, I am unable to do the same via my python program (or even Postman REST client). I get an error message stating "Insufficient privileges to complete the operation." I am using the following python library to obtain an access token using the client credentials: ADAL python library
It looks like I am not following the correct procedure while obtaining the access token to make my call. I even tried obtaining the access token directly using a REST client. It would be great if someone could review the steps below to highlight any mistakes:
Step 1: Hit the following endpoint
[HTTPS]/login.microsoftonline.com/[my-organization]/oauth2/authorize?client_id=[client-id]&response_type=code&response_mode=query&resource=00000002-0000-0000-c000-000000000000
Step 2: Note down the 'code' query parameter from the above request. Then make the following request.
POST [HTTPS]/login.windows.net/[my-orgranization]/oauth2/token?api-version=1.0
HEADERS:
Content-type application/x-www-form-urlencoded
BODY:
code=[code received from Step 1]
client_id=[client id of my app in Azure]
client_secret=[client secret of my app in Azure]
grant_type=authorization_code
scope=openid
Please note that the values above were URL encoded appropriately.
I have even tried sending the global admin's credentials (username/password) in Step 2 as a last ditch effort but to no avail.
Any pointers in this regard would be greatly appreciated.
Thanks in advance.
The error you are receiving is a result of the configuration of your application. Specifically, you need to configure your app to have the proper permissions to create users when calling the AAD Graph API.
Take a look here at the permission scopes available through the AAD Graph API.
To create users you will need either Directory.ReadWrite.All or Directory.AccessAsUser.All. You can check that you have done this all correctly by looking at your access token, and confirming that these claims appear in your access token.
If you do not have these claims, go back to your app registration and make sure to add the appropriate permissions to the AAD Graph API.
Note that when you update your application's permissions, you will need to force a consent prompt again to consent to the new permissions you are requesting, otherwise the authentication will continue to succeed with the OLD permissions you have requested. In order to force consent, simply add &prompt=consent to the end of the authorize URL.
Let me know if this helps!

Resources