I'm trying to implement On-behalf-of user in Asp.net Web API (.net 5). I receive an access_token from the Mobile APP, send it to my Web API. The Web API uses this token to call the GRAPH API to get the user's profile details. Below is my code Startup.cs file
services.AddAuthentication("JwtBearer")
.AddJwtBearer("JwtBearer", options =>
{
options.MetadataAddress = $"https://login.microsoftonline.com/{Configuration["b2bAzureAppIdentity:TenantId"]}/v2.0/.well-known/openid-configuration";
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = $"https://sts.windows.net/{Configuration["b2bAzureAppIdentity:TenantId"]}/",
// as audience, both the client id and the identifierUri are allowed (sematically equivalent)
ValidAudiences = new[] { Configuration["b2bAzureAppIdentity:AppIdUri"], Configuration["b2bAzureAppIdentity:ClientId"] }
};
}).AddMicrosoftIdentityWebApi(Configuration, "b2bAzureAppIdentity")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
controller.cs
[HttpGet("GetMyDetails")]
[AuthorizeForScopes(Scopes = new string[] { "user.read" })]
public async Task<IActionResult> GetMyDetails()
{
var user = await _graphServiceClient.Me.Request().GetAsync();
return new OkObjectResult(user.Photo);
}
Appsettings is in the below format
"b2bAzureAppIdentity": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "",
"TenantId": "",
"ClientId": "",
"ClientSecret": "",
"AppIdUri": ""},
"DownstreamApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"},
In Azure, the API permissions and scope are set correctly, this is evident because when I make calls from postman, I'm able to get the accesstoken for on_behalf_of and use it to get the user's profile details by calling https://graph.microsoft.com/v1.0/me
In the controller at this line
var user = await _graphServiceClient.Me.Request().GetAsync();
I get an error: "No account or login hint was passed to the AcquireTokenSilent call. "
I have googled for this error and the solution says that the user should consent the scope however it has already been consented by the admin in Azure portal. Also, the fact that this is working in Postman makes be believe that the configurations for the APP and the API are correct.
Has anyone faced similar issue?
This is happening because the access_token received is not sent along with the request to get the user detail. Here's an example of how to implement on behalf of provider:
In this case the token is added to the request in the call to
WithUserAssertion
.Please let me know if this helps, and if you have further questions.