'How to generate an on-behalf-of token for a middle-tier API
I'm trying to implement an on-behalf-of flow, with Microsoft Identity Platform where my Web app authenticates users, then makes a request to my Web API which in turn makes a request to the Microsoft Graph API (and returns the result to the Web app).
My problem is that I will need to pass on an on-behalf-of token to my Web API for it to be granted acces to Microsoft Graph, but I cannot manage to generate this token. (I'm trying to generate this token using Postman at the moment.)
What I want to be able to run is a code snippet provided by the official documentation here for the Microsoft Graph SDK (in the case of an OBO-flow), and what I need help with is how to generate the token for the oboToken variable.
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Identity.Client;
var scopes = new[] { "User.Read", "Presence.Read.All" };
var tenantId = "common";
var clientId = "<id of my API as registered in Azure AD / App Registrations>";
var clientSecret = "<value from Client Secret in Registerd Application / Certificates & secrets";
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var oboToken = "< WHAT NEEDS TO BE PROVIDED BY THE WEB APP >";
var cca = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.Build();
var authProvider = new DelegateAuthenticationProvider(async (request) => {
var assertion = new UserAssertion(oboToken);
var result = await cca.AcquireTokenOnBehalfOf(scopes, assertion).ExecuteAsync();
request.Headers.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
});
var graphClient = new GraphServiceClient(authProvider);
Console.WriteLine(graphClient.Me.Request().GetAsync().Result);
I've tried the following: I generate an authorization code with the following request in my browser
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=< Id of my API >
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp
&response_mode=query
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
Then, with the returned code, make the following POST request (from Postman)
https://login.microsoftonline.com/common/oauth2/v2.0/token?
client_id=< Id of my API >
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp
&grant_type=authorization_code
&code=< code returned by request above >
When I use the returned token from the response as the value of the oboToken in the code snippet, I get a
MsalServiceException: AADSTS50027: JWT token is invalid or malformed.
If I instead also include a client_secret parameter in the POST request above for a token, I get the response AADSTS90023: Public clients can't send a client secret.
How could I generate an on-behalf-of token to be able to run the provided code snippet?
Thanks in advance!
Solution 1:[1]
It seems to me that your mistake is getting an MS Graph API token with the authorization code flow.
The way it should work is:
- Web App gets an access token to the Web API using authorization code flow
- Web API receives the access token and exchanges it for an MS Graph API token using the on-behalf-of flow
- Web API calls MS Graph API
So when your Web App gets an access token, it should use a scope defined in the API app registration instead of scope=https%3A%2F%2Fgraph.microsoft.com%2F.default.
If you specify an MS Graph API scope, you get an access token for MS Graph API, meaning you are trying to call MS Graph API from the Web App, instead of your API.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | juunas |
