Azure DevOps OAuth2. TF400813: The user is not authorized to access this resource - azure-devops

I have implemented an OAuth2 app for Azure DevOps. My website takes user (User A) to authorize the app using the below URL.
Step1
https://app.vssps.visualstudio.com/oauth2/authorize?scope=vso.code_full (skipped the other parameters)
The above URL works fine and returns with a code+userInfo after user authorization. Now I get an access token passing the code returned from the app using the below API call.
https://app.vssps.visualstudio.com/oauth2/token
I can further fetch all the organizations associated with user's (User A ) account using the below API call
Step2
https://app.vssps.visualstudio.com/_apis/accounts?api-version=6.0-preview&memberId=xyz
Now I want to fetch the repositories inside a particular organization. For that I make the below API call.
Step3
https://dev.azure.com/**organization_name**/_apis/git/repositories?api-version=5.0
The avove URL works fine and returns to the repositories inside the specified organization.
Everything fine so far.
Now another user (user B) is trying to connect with my app and he can authorize the app and my application can fetch the organizations under that authenticated user's account. e.g. everything fine until step2. But it fails on step3 e.g. it fails to fetch the repositories inside user's (user B) organization. The API call in step3 returns with following error
TF400813: The user is not authorized to access this resource.
kindly help.
To further clarify, I suspect that issue is with Authenticated user (user B ) , as the whole process works fine for one authenticated user (user A ) but fails for the other user (user B). So there must be something different with second authenticated user. But I am not sure what is it as I am not an Azure guy.
Also Note that when I am logged in with User A or User B , I can view my organizaions/projects/repos , also I can add/delete organizations/projects/repos. (I am the organization Owner)
Then If I am able to view my organizations/repos with a logged in user , and the same user is authenticating the OAuth app then why the Access token produced by the user is not authorized to access the repos in the User B's account ?

I have found the missing part here.
It is that I have to go to the organization's settings like at the below URL
https://dev.azure.com/my_organization_name/_settings/organizationPolicy
and check the first check box under Application connection policies which is Third party application acces via OAuth
by checking in this option , I am able to fetch the repos under User B's account as well.
It's a shame that Microsoft has no documentation for this. Another reason to hate Microsoft products.

Related

Is it okay to use an OAuth2 authorization code as proof of a successful login?

I have a database with emails and passwords, and a Flutter app that lets those users log into the app by providing their email and password (the old fashioned way).
Now, some of those users are part of an organization that has a separate website where they use Microsoft/Office 365 accounts to sign in. Of course they want to be able to log into my app using their Office 365 accounts as well, instead of having to remember and type a different password in the app than they normally use on their organizations website.
So I've been looking at their website, which uses Microsoft Azure as a the backend. From their current login page I could find the tenantID, clientID, redirectURL and scope. From this I am able to get an authorization code back from the login.microsoftonline.com authorization endpoint. However, as my app is not registered in the organizations Azure account, I don't have a clientSecret so I can't call the token endpoint and get an idToken.
I'm using a WebView to display the login to their organizations website, so I can grab the authorization code from the redirect URL when they are redirected.
So my question is if I can use the authorization code directly to verify that the user has successfully signed in using their Office 365 account? All I need to know is that the user has an account at the organization, and that they could provide a valid email and password to login.
If they are redirected to the redirect URL with an autorization code, it means that they successfully logged in. Then I could consider them logged in to my app as well, based on the email provided to the Office 365 authorization endpoint. Because if they couldn't log in to their Office 365 they wouldn't get an authorization code, right?
No, the authorization code only has meaning to the identity provider, in this case Azure AD. It doesn't prove anything to your app.
What you could do is try response_type=code+id_token in the authorization URL.
If ID tokens have been configured as returnable from the authorization endpoint (this is done in the app registration configuration), you will get back a signed id token that you can verify.

Microsoft Graph API: Getting ErrorAccessDenied for multi-tenant application with application permission

I'm writing a daemon app for my customers (multiple tenants) who are using outlook.
I'm using 2 application permissions that need admin consent - Mail.ReadBasic.All and
User.Read.All. my app first needs to read all the users' ids, then get all the metadata of their emails.
I've created a new tenant with office365 to test this, let's call it - test, and sent a couple of emails between 2 users.
So, at first, I'm redirecting the admin of the test org to the adminconsent endpoint, where he/she is granting application permissions to my app. This is the URL I'm using:
https://login.microsoftonline.com/organizations/v2.0/adminconsent?
client_id=<the app ID>
&state=<some state>
&redirect_uri=<my redirect URL as written in the app configuration>
&scope=https://graph.microsoft.com/.default
After calling this endpoint I can see my app listed in the test org under the Enterprise applications and can see the relevant permissions were granted by an admin.
Since I'm not getting a code from this flow (needed for the oAuth2 authentication flow), I then need to ask the admin to login again. I'm using this URL for that:
https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?
client_id=<same app ID>
&response_type=code
&redirect_uri=<same redirect URL>
&scope=https://graph.microsoft.com/.default+offline_access+openid+profile
&state=<some state>
After the login is successful I'm getting a code back to my redirect URL and after another request, I'm getting an access token. Using this access token I'm trying to access any of the following APIs:
https://graph.microsoft.com/v1.0/users
https://graph.microsoft.com/v1.0/users/user-id-of-user-in-test-org/messages
But I'm getting ErrorAccessDenied with a message: Access is denied. Check credentials and try again.
Further information:
I'm using python and the MSAL package to build the app (using the class - ConfidentialClientApplication) and the URLs for the authentication flow (but not for the adminconsent endpoint, as I couldn't find out how to do it)
Do you know what I'm doing wrong? I'm losing my mind over this... :(
This page should describe everything you need:
https://learn.microsoft.com/graph/auth-v2-service
The admin consent URL should be specific to the customer's tenant. You can use the word common if you want to allow signing into any tenant.
https://login.microsoftonline.com/{tenant}/adminconsent
You also must URL encode the redirect_uri param (and all other params). For some reason the example in that document is not URL encoded, but the value here must be URL encoded. You should see no colons, slashes, ampersands, etc. for this parameter.
For a different example that requests specific scopes for admin consent (instead of the default which is all the scopes you listed during your AAD client app registration) see https://learn.microsoft.com/azure/active-directory/develop/v2-admin-consent.
You will receive a callback to the redirect URI to indicate everything worked. This includes the tenant ID that granted you admin consent.
After that you initiate a separate token request call for the tenant ID, your application client ID and a specific requested scope. This will then return an appropriately scoped access token which you can use directly in all API calls. You can do this like so: https://learn.microsoft.com/azure/active-directory/develop/scenario-daemon-acquire-token?tabs=python#acquiretokenforclient-api
# The pattern to acquire a token looks like this.
result = None
# First, the code looks up a token from the cache.
# Because we're looking for a token for the current app, not for a user,
# use None for the account parameter.
result = app.acquire_token_silent(config["scope"], account=None)
if not result:
logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
result = app.acquire_token_for_client(scopes=config["scope"])
if "access_token" in result:
# Call a protected API with the access token below.
print(result["token_type"])
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id")) # You might need this when reporting a bug.
Hope that helps. The article above has all the details.

How to get impersonated UserGuid Id in docusign

I am trying to get the impersonated userguid from the docusign api. Per the documentation I need to call /restapi/v2/accounts/account_id/users?email=email, which is not working for me. I assume the full url would be https://admin.docusign.com/restapi/v2/accounts/account_id/users?email="sampleemail#gmail.com" .
I am getting a 404 when entering my email in the above format.
Looks like you have the incorrect domain. API Calls generally don't get made against admin.docusign.com. You'll want to make that call against the Application Server your account is on.
In the Sandbox environment that will be demo.docusign.net. In prod you'd need to make a UserInfo call to determine which server your account is on. It could be something like www.docusign.net or na2.docusign.net, but there are several possible domains.
In order to get Impersonate GUID ,
Login to admin account
Under setting options Click API and keys
Value under the user id text box is Impersonate GUID
During configuration & setup:
1. You have an account admin enter information such as account, their userId ("API User Name" in web app). Save both items.
2. You follow the "consent flow", get their consent, generate a JWT and
exchange for a token.
3. Use the /user_info call against the account
server to get the list of their accounts. If more than one account
in the array, find the one that matches what they entered in the
configuration. Get and save the associated "base_uri". You will
use that for all subsequent API calls.
Your application now has stored the account ID, the admin's "userId", and the base URI to built API URLs.
During business application operations:
Admin is "Bob". Sender is "Jill"
You need to get an access token for Jill.
1. Create JWT for Bob, exchange for access token, make GET /users?email={Jill's email). This gives you Jill's "userId".
2. Create JWT for Jill, exchange for access token.
3. Make API call as Jill, using her access token.

How can I get system user token of another facebook business to manage their audiences?

I am working to build an application which would be able to create custom audiences for many of our clients for facebook ads. I came to know that the most suitable access token for this purpose is system user token (correct me if I am wrong). To get regular user access tokens, we can make a user go through the traditional oAuth flow, I am looking for something similar to get system user access token. How can I get it for any of my clients? Thanks
You must create your system users in the Business Manager of your company:
https://business.facebook.com/settings/system-users?business_id=<YOUR_BUSINESS_ID>
Once you create a system user, you can generate a token for him associated with a given app.
Meanwhile, on your business settings (as stated in the docs) you can request access to an ad_account.
Request Access to an Ad Account: If you request access to an ad
account in Business Manager, the admin of that Business Manager can
grant you permission to work on it.
Once your client gives your Business permission to work with one or more of their ad_accounts, those ad_accounts will appear in your Business Manager. (menu on the left).
At that point, when checking the profile of your system users, you can click on assign assets to give the system user access to pages and ad_accounts.
The token you generated for the pair [system_user,app_id] does not need to be reissued to reflect the addition of assets to which the system_user has access.

How can I limit access to a set of authorized users in Azure Mobile Services?

If I add authentication in Azure Mobile Service with Google as the provider, I go and create an app, get the app_id and secret and plug it in. Great, now users can authenticate with google and get a user token. Now they are considered an "authenticated user" wrt the table permissions.
However, I don't want to authorize everyone with a google account access to my API. Is it possible to limit this to a list of known users? Must I check every request for specific user ids?
Perhaps social login is not the best choice here and I should use something else like Azure AD?
We added custom authentication provider to wams and synchronize the social account with "our" user-account that is stored in the database. For protected web api methods a user account needs to be activated first. You have to check manually whether an account is activated/ high privileged or not and return the result or unauthorized status code.
I decided to use Azure Active Directory to solve this problem. This way, I can create users in Azure AD but not have to manage users myself in the back end. With this choice I am still able to chose the only authenticated users permission level without having to check on every rest endpoint that the authentication users is one of the ones I want to grant access to.