VSO scope in Azure AD identity provider - azure

I am building a bot which will be calling Azure DevOps to update the work item (scope required - vso.work_write Update Work item ). For this I want to have the user authenticate itself using OAuth. Following Authentication doc I created the bot channel registration followed by identity provider and then registering the identity provider in my bot. Now when I go to my identity provider under API permission -> Add a permission -> Azure Devops all I see is a "user_impersonation" permission whereas my requirement is to add a vso.work_write permission to modify ado work items.
How can I add a vso.work_write permission to my identity provider so that my bot picks up the required scope while building the token ? Or is there any method to manually enter the scope in the bot code ?
Note :- I tried giving "user_impersonation" scope and generating the token with that scope but I still get a 401.
Edit 1 :-
I am able to generate a jwt token but using that token I am not able to hit ado endpoint that's why I am suspecting it to be a scope issue only.

You could try the following steps:
You could use the URL: https://token.botframework.com/.auth/web/redirect to create an App registration.
Grant the user_impersonation to the APP and generate the secret.
Go to Bot service -> Settings -> OAuth Connection Settings -> Add Setting
Select the Azure Active Directory and input the info.
Scopes: openid, email, profile, and offline_access. You could select openid
Based on your description, the vso.work_write scope exists in the Outh Token and PAT (Personal Access token).
You can also refer to the doc to generate the Azure Devops outh token and use it in the Bot Service settings.
Here is a ticket with the similar issue, you could refer to it.

Related

How to use aad authentication or managed identity to access resources with torus system in azure?

We previously used keyvault and connectionstring to access resources in azure. However it will generate many parameters needed. We want to simplify the process.
We wanted to use aad authentication.
Firstly, we tried certificate-based aad authentication https://learn.microsoft.com/en-us/azure/cosmos-db/sql/certificate-based-authentication first, it works. But the thing is, in keyvault the certificates are set auto-rotation, but in aad app, we can only manually upload new certificate each time (I know there are methods like VM extension or extra software can do auto renewal, but it's complicated. We just want change configs in azure portal and change service code to access.) In this situation, when certificates becomes more and more, it's not suitable to manually renew each cert in each aad app. I notice in some places it says setting tls/ssl settings which makes auto-renewal, but currently in azure portal, it just can manually upload certificates. Only in function app can do tls/ssl settings.
Secondly, then we notice another one as managed identity. It simply says azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/"); to get token. But the thing is, current login tenantid is microsoft.onmicrosoft.com, but the resources and the subscriptions are all in prdtrs01.onmicrosoft.com through torus account.
Even I try with string accessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/", prdtrs01tenantid) still does not work, saying AADSTS50020: User account '{EmailHidden}' from identity provider '...' does not exist in tenant 'PRDTRS01' and cannot access the application '...'. It seems just cannot get token from prdtrs01 tenantid.
Also, I tried to replace the aad app used in first method with the function app used in second method to do certificate-based authentication. However the function app does not have a clientid, just principalId and user managed identity's clientid. Both ids fail with ClientAssertionCertificate credential = new ClientAssertionCertificate(clientId, cert); in certificate-based authentication. It finally says "Client assertion contains an invalid signature. [Reason - The key was not found., Thumbprint of key used by client".
In all, I described several ways we tried, but all failed. Can anyone help?
Thanks
AADSTS50020: User account '{EmailHidden}' from identity provider
'...' does not exist in tenant 'PRDTRS01' and cannot access the
application
As per this first error , it means that the account you are using to access the application is not a part of the tenant that the application is hosted on.
Make the application as a Multi-Tenant Application :
You can convert the application to accept users from multiple tenants. In this way you can give access to users who are not in your tenant without having to add them to the tenant where the application is in.
Maybe account type is set to Accounts in this organizational directory only.
You may have to change it to Accounts in any organizational directory.
Go to Azure portal -> Azure Active Directory -> Manage -> App Registrations --> your app name -> Supported Account Types
(or)
Add the user to the tenant as guest :
You may need to add the user to the tenant that the application is hosted in. You can follow this document to add the user with your domain as a Guest User to the tenant. And grant access to the application for the said user.
However, if your authentication call is for specific tenant i.e., https://login.microsoftonline.com/yourtenantname or_id, users from other organizations won't be able to access the application and are required to be added as guests in the tenant specified in the request.
In your case, try to authenticate request like https://login.microsoftonline.com/organizations or https://login.microsoftonline.com/common

How to create Teams Message via REST from an Application properly

I have a c# service, the service is running somewhere in the azure cloud without an user interface. some specific events should trigger new messages to a team channel.
According to this documentation, the Create Message https://learn.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-1.0&tabs=http is only supported by delegated account, not by the application tokens.
How can i create a delegated token for my service application without specific user account and without a login interface in the cloud?
Which Authentication Provider is the right one? https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?context=graph%2Fapi%2F1.0&view=graph-rest-1.0&tabs=CS
As you mentioned in the question : chatMessage , supports only the Delegated Permission type.
What exactly is Delegated Permission Type?
A permission which specify scope-based access using delegated authorization from the signed-in.
The reason on the emphasis of the above point is being that - for Delegated permission we would need the context of a user account
Coming back to your questions :
How can i create a delegated token for my service application without specific user account
You can obtain a token without a specific user account but this will not help your cause.In order to overcome this, I would suggest a creation of service account - this account has permission over the teams.Part 2 of this questions suggests which provider can help without the login prompt.
The steps include :
Register your app.
Configure permissions for Microsoft Graph on your app.
Get administrator consent.
Get an access token.
Use the access token to call Microsoft Graph.
Detailing of the steps is included in the article here : https://learn.microsoft.com/en-us/graph/auth-v2-service
without a login interface in the cloud
Now you could use the below option :
Microsoft identity platform and OAuth 2.0 Resource Owner Password Credentials
In this provider, you will be passing the creds of the service account.
POST {tenant}/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=<YOUR CLIENT ID>
&scope=user.read%20openid%20profile%20offline_access
&username=<YOUR USERNAME>
&password=<YOUR PASSWORD>
&grant_type=password
You can generate the token for your service account by above request and application can consume the chatMessage API.

Credentials prompt for access to Azure management APIs

I've been using the Azure fluent management APIs (https://github.com/Azure/azure-libraries-for-net) with some success in .NET Core.
However, I want to prompt the user to enter some credentials for a Microsoft account. Those credentials would have access to one or more Azure tenants / subscriptions, so I'd like to be able to use the result to browse and manage resources there.
This is something very close to what I would believe Azure Data Studio does: you can enter some Azure creds, and your resources will appear in the app.
I'm trying to understand the best approach for this. There seem to be a billion sites out there when you talk about Azure AD app registrations, but I haven't found a fruitful specific search query yet. I know I can register an app, get a client ID and client secret. I know I can set it to be usable by organisational accounts in the current tenant, or all tenants.
I can add the "Azure Service Management (delegated permissions : user_impersonation)" permission to my API permissions section for the app, but what's next?
If I use Microsoft.Identity.Client (as in https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon), I run into some questions:
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync! Nope, AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
I don't know what scope I want. https://management.azure.com/user_impersonation is apparently invalid.. https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs.. and my account (for instance) is associated with 3 tenants or 5 different tenants / directories - so how do I choose?
That's just what I've tried, the appropriate route might be a different one. In summary: I want a .NET Core Console app to request user credentials, and then get access to the Azure resources they have access to, in order to perform some resource management.
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
You are using the OAuth 2.0 client credentials grant to access web-hosted resources by using the identity of an application. This type of grant commonly is used for server-to-server interactions that must run in the background, without immediate interaction with a user .
AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
Azure AD provide two service : Azure AD V1.0 and Azure AD V2.0 . Please refer to Comparing the Azure AD v2.0 endpoint with the v1.0 endpoint . You can't use v1 token to acquire v2's token in a on-behalf-of flow .
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync
AS pointed above , That function is used to acquire an access token for this application (usually a Web API) from the authority configured in the application, in order to access another downstream protected Web API on behalf of a user using the OAuth 2.0 On-Behalf-Of flow. So you can't use app token which acquire using Client Credential flow .
https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
You are using the Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow , when sending a POST request to the /token v2.0 endpoint ,the scope should be :
The value passed for the scope parameter in this request should be the resource identifier (Application ID URI) of the resource you want, affixed with the .default suffix. For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value informs the v2.0 endpoint that of all the direct application permissions you have configured for your app, it should issue a token for the ones associated with the resource you want to use.
Please check the Get a tokensection in above document .
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs..
AFAIK , currently Azure AD V2.0 apps can use:
Its own API
Microsoft Outlook APIs
Microsoft Graph API
Azure AD V2.0 currently doesn't support Azure management APIs .
So you problem is you need to allows work and school accounts from Azure AD and personal Microsoft accounts (MSA) which works with Azure AD V2.0 , but you can't use Azure management APIs . You can use Azure management APIs in Azure AD V1.0 but it allows only work and school accounts to sign in to your application , unless you invite Microsoft accounts as guest user in Azure AD V1.0 ,but you need to configure to point to the tenant-specific endpoint :https://login.microsoftonline.com/{TenantId_or_Name}). during authentication if you want to login with MSA in v1.0 apps.
Update:
You can use Code flow and azure ad v1.0 endpoint , user will be redirect to AAD's login page and enter their credential. Here is code sample for .net Core .
With Azure AD V1.0 endpoint , requests are sent to an endpoint that multiplexes across all Azure AD tenants: https://login.microsoftonline.com/common . When Azure AD receives a request on the /common endpoint, it signs the user in and, as a consequence, discovers which tenant the user is from. See document here . But in this scenerio ,you can only use work and school accounts(AAD) account to login .
The code sample in your link is using Azure Service Principal for Authentication , no interactive user login . You can use OpenID Connect Owin Middleware for authentication in .net Core applications as shown here .

Microsoft graph API: unauthorized error when used with sharepoint and token attached

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

Azure AD B2C Connected user change password with Graph AD API

We are using Azure AD B2C and I'm trying to implement the changePassword function for signed-in users. We have followed this tutorial https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet, and we have succeeded to make it worked.
But we want signed-in users to have the possibility to change their existing password (directly in applications). We found this method (https://msdn.microsoft.com/fr-fr/library/azure/ad/graph/api/functions-and-actions#changePassword) but we failed to make it work...
What is the standard workflow for using AD Graph API in AD B2C with signed-in users ?
I have an application linked to a B2C tenant. I have created both Android and iOS apps and I am able to connect and get tokens thanks to the sign-up or sign-in policy, this point is OK...
In parallel I have created a service app in order to use the AD Graph API (thanks to the first link above).
We have suceeded in testing some operations like get the lists of users, find a specific user, change some.... But now I want to use the method "changePassword" for the connected users (second li) and I have failed using it. I don't know which access token to provide, both tests (using the token from the app service credential or using the access token received thanks to the signin policy) have failed ??
Other question, is it normal that the app service I have created with PowerShell is not visible in the Azure Portal ??
Thanks ;)
Other question, is it normal that the app service I have created with PowerShell is not visible in the Azure Portal ??
We can locate the service principal which created by PowerShell by searching the appPrincipalId like below:
Update
To perform the change password REST API of Azure AD Graph, we need to provide the delegate access token. In this scenario, we can use resource owner password credentials flow which require users' username and password for the authentication. To use this flow we can register the service principal like below:
$app = New-AzureRmADApplication -DisplayName "appPS2" -HomePage "https://adb2cfei.onmicrosoft.com/appPS2" -IdentifierUris "https://adb2cfei.onmicrosoft.com/appPS2" -Password "123"
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId
Then we need to login the Azure classic portal to grant the delegate permission Directory.AccessAsUser.All as figure below:
Here is the code to acquire the token using the resource owner password credentials flow:
Post: https://login.microsoftonline.com/adb2cfei.onmicrosoft.com/oauth2/token
resource=https%3a%2f%2fgraph.windows.net&client_id={ $app.ApplicationId}&grant_type=password&username=fx%40adb2cfei.onmicrosoft.com&password={currentPassword}&client_secret=123
Then we can use this token to change the password of the sign-in user like below:
POST: https://graph.windows.net/adb2cfei.onmicrosoft.com/me/changePassword?api-version=1.6
authorization: bearer {access_token}
content-type: application/json
{
"currentPassword":"{currentPassword}",
"newPassword":"{newPassword}"
}

Resources