当我尝试使用Cortana Bot用户令牌(这是一个Graph令牌)来使用ClientAssertionCertificate
/ ClientCredential
为另一个消费Web API应用程序生成“代表”令牌时,我收到错误(如下所述)通过将其AppId
作为使用Cortana Bot用户令牌生成的ResourceId
和userAssertion
传递给另一个消费Web API。
当检查我们的Bot AAD设置时,它与其他消费Web API(API B)一起配置为有效的应用程序以及Graph应用程序。我们是否需要在AAD中进行任何其他设置才能获得代表令牌?
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
以下是我们尝试为其他消费Web API(API B)获取代表令牌的流程和示例代码。
流程步骤:
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;
}
output = await authContext
.AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion)
.ConfigureAwait(false);
我的理解是:首先从Cortana访问ms图形API获取用户令牌;然后你想使用用户令牌在Microsoft Bot Framework API中生成OBO令牌;最后,您希望使用OBO令牌从Microsoft Bot Framework API访问API B.
您想在Microsoft Bot Framework API中获取OBO令牌,您应该使用API ID和秘密,为此,我从未尝试过这个。
在我这边,我使用v1端点,我创建了两个API(API A和B),我的流程是:首先,我的应用程序为API A请求token1;
接下来,使用token1从API A请求API B的OBO令牌2;
最后,使用OBO令牌2从API B请求aad图API的OBO令牌3。
对于v1端点中的OBO,请阅读link1。
对于v2端点中的OBO,请阅读link2。
我们可以通过将我们的依赖自定义API(API B)“user_impersonation”范围配置为我们的Bot的Cortana通道配置来解决此问题。通过此配置更改,我们无需从Microsoft Bot应用程序为API B生成On-Behalf-Of令牌。
感谢所有支持为此线程提供解决方案的人...