I'm getting an error (mentioned below) when I'm trying to use Cortana Bot user token (which is a Graph token) to generate an "on-behalf-of" token to another consuming Web API application using ClientAssertionCertificate
/ ClientCredential
targeted to another consuming Web API by passing its AppId
as ResourceId
and userAssertion
generated by using Cortana Bot user token.
When checked our Bot AAD settings it is configured with other consuming Web API (API B) as valid application along with Graph application. Do we need to do any additional setting in AAD to get this on-behalf-of token?
AADSTS50013: Assertion contains an invalid signature.
[Reason - The provided signature value did not match the expected signature value.,
Thumbprint of key used by client: '9DB0B05B5D70DD7901FB151A5F029148B8CC1C64',
Found key 'Start=11/11/2018 00:00:00,
End=11/11/2020 00:00:00'
]
Trace ID: a440869f-b8f5-4d87-ba1a-6bd8dd7ba200
Correlation ID: 651e1fa8-2069-4489-a687-e68e5206e193
Timestamp: 2019-01-02 07:14:45Z
Following is the flow and Sample code how we are trying to get an on-behalf-of token for other consuming Web API (API B).
Flow Steps:
Following is the code sample used to generate an on-behalf-of token from Microsoft Bot Framework API:
public async Task<string> GetOnBehalfOfTokenAsync(string authority, string resource, string scope = "", string token = "")
{
AuthenticationResult output;
var clientId = ConfigurationManager.AppSettings["API-B-ClientId"];
// Read certificate which can be used for getting token to API B using ClientAssertionCertificate
// GetCert() is used to get the Certificate based on Thumbprint configured in Web.config file.
var certificate = this.GetCert();
// 'authority' is https://login.microsoftonline.com/{tenant id}
var authContext = new AuthenticationContext(authority);
var cllientCertificateCredential = new ClientAssertionCertificate(clientId, certificate);
// 'token' is the user token which was received from Cortana.
var userAssertion = (!string.IsNullOrWhiteSpace(token)) ?
new UserAssertion(token, "urn:ietf:params:oauth:grant-type:jwt-bearer",
TokenHelper.ExtractUserInfoFromAuthToken(token, "upn")) : null;
try
{
// 'resource' is the Resource Id of API B
// if UserAssertion is null then get token with ClientAssertionCertificate else get
// on-behalf-of token using UserAssertion and ClientAssertionCertificate
if (userAssertion == null)
{
output = await authContext
.AcquireTokenAsync(resource, cllientCertificateCredential)
.ConfigureAwait(false);
}
else
{
output = await authContext
.AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion)
.ConfigureAwait(false);
}
}
catch (Exception ex)
{
logger.log("Error acquiring the AAD authentication token", ex);
}
return output.AccessToken;
}
Getting an exception which was mentioned above at this step:
output = await authContext
.AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion)
.ConfigureAwait(false);
We could able to resolve this issue by configuring our dependent custom API (API B) "user_impersonation" scope to Cortana channel configuration to our Bot. With this configuration change, we do not need to generate On-Behalf-Of token to API B from our Microsoft Bot application.
Thanks to all who has supported to provide solutions for this thread...