[英]How do I call 3rd party REST service from Dynamics 365 CRM online?
I know this question is almost the same but I need to secure the call with an access token. 我知道这个问题几乎相同,但是我需要使用访问令牌来保护呼叫。
Therefore, when calling external web api from Dynamics 365 CRM online I need to set the Authorization request header with a Bearer token. 因此,当从Dynamics 365 CRM在线调用外部Web api时,我需要设置带有Bearer令牌的授权请求标头。
How do I get hold of the access token to send with the call? 如何获得随呼叫发送的访问令牌?
EDIT: We are using Azure Ad to login to Dynamics 365 CRM online and at that moment we receive a token persisted in a cookie. 编辑:我们正在使用Azure广告在线登录到Dynamics 365 CRM,这时我们收到保存在cookie中的令牌。
When we make a call to external web api we want to send that token with our call as an Authorization header. 当我们调用外部Web api时,我们希望将该令牌与我们的调用一起作为授权标头发送。
EDIT: 编辑:
We have tried to create a Plugin/Activity (C#) but there is no cookie collection (what we can see) in that context. 我们尝试创建一个插件/活动(C#),但是在该上下文中没有cookie集合(我们可以看到)。 In the example below we tried with clientid and clientcredentials but users information is not involved there.
在下面的示例中,我们尝试使用clientid和clientcredentials,但其中不涉及用户信息。
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
namespace MyPlugin
{
public class TestPlugin : IPlugin
{
private const string ClientId = "***";
private const string ClientSecret = "***";
private const string AadInstance = "https://login.microsoftonline.com/";
private const string TenantId = "***";
private const string PostLogoutRedirectUri = "https://***.crm4.dynamics.com";
public void Execute(IServiceProvider serviceProvider)
{
var tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var accessToken = GetTokenWithoutAdal().GetAwaiter().GetResult();
tracer.Trace(accessToken);
RetrieveAccounts(accessToken).GetAwaiter().GetResult();
}
private static async Task<string> GetTokenWithoutAdal()
{
var loginUrl = AadInstance + $"{TenantId}/oauth2/token";
var client = new HttpClient();
var postData = $"client_id={ClientId}&client_secret={ClientSecret}&resource={PostLogoutRedirectUri}&grant_type=client_credentials";
var request = new HttpRequestMessage(HttpMethod.Post, loginUrl) { Content = new StringContent(postData, Encoding.UTF8) };
request.Content.Headers.Remove("Content-Type");
request.Content.Headers.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var responseMessage = await client.SendAsync(request);
var jsonResponseString = await responseMessage.Content.ReadAsStringAsync();
string something = null;
//Do something
return something;
}
private static async Task<string> RetrieveAccounts(string token)
{
var webApiUrl = "https://***.test.com/v1.0";
var url = $"{webApiUrl}/accounts";
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var response = await client.GetAsync(url);
var jsonContent = await response.Content.ReadAsStringAsync();
return jsonContent;
}
}
}
A workmate has also tried using Javascript in calling a LogicApp, but no token is sent. 一个同事还尝试使用Javascript来调用LogicApp,但是没有发送令牌。
function callLogicApp() {
fetch('https://dynamicstestapi.azure-api.net/manual/paths/invoke',
{
method: 'POST',
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
credentials: 'include',
mode: 'cors',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Ocp-Apim-Subscription-Key': 'e1e884bbe9a945a9a4dbcabff49e59d8'
}
})
.then(res => res.json())
.then(console.log);
}
EDIT: 编辑:
This is what I want, users access token (only payload from JWT) 这就是我想要的,用户访问令牌(仅来自JWT的有效负载)
{
"aud": "https://myapi.net",
"iss": "https://sts.windows.net/******-****-4c1e-b346-2a28ef579dea/",
"iat": 1567158525,
"nbf": 1567158525,
"exp": 1567162425,
"acr": "1",
"aio": "ASQA2/8MAAAA1czfs/LOnB0mRwLY****ZF4tHvcoN+oOwpFUE1F6cgU=",
"amr": [
"pwd"
],
"appid": "6792c685-bbf7-****-b15f-7b047edd2db6",
"appidacr": "1",
"family_name": "Lastname",
"given_name": "Firstname",
"ipaddr": "194.114.***.***",
"name": "Firstname Lastname",
"oid": "0ba39690-fb32-****-8d6c-3e4826b2f05b",
"puid": "10030000826E****",
"scp": "Directory.Read.All User.Read",
"sub": "3C04Virz0afCxbAfY5****YfNgnC9HR7y3Mqcbgu5wg",
"tenant_region_scope": "EU",
"tid": "6f310cfb-5ece-****-b346-2a28ef579dea",
"unique_name": "fname.lname@domain.com",
"upn": "fname.lname@domain.com",
"uti": "U9v1VNGnY0i****-wHlCAA",
"ver": "1.0"
}
This is what I can get with clientid and clientsecret (only payload from JWT) 这就是我可以通过clientid和clientsecret获得的信息(仅来自JWT的有效负载)
{
"aud": "https://myapi.net",
"iss": "https://sts.windows.net/******-****-4c1e-b346-2a28ef579dea/",
"iat": 1567161484,
"nbf": 1567161484,
"exp": 1567165384,
"aio": "42FgYKhpmv0+****3SV/FZvuDbduAA==",
"appid": "3401bb09-a6f2-****-846a-ef4570b3a8bd",
"appidacr": "1",
"idp": "https://sts.windows.net/******-****-4c1e-b346-2a28ef579dea/",
"oid": "125746e6-4f03-****-8cf9-d568b9fce035",
"sub": "125746e6-4f03-****-8cf9-d568b9fce035",
"tid": "6f310cfb-5ece-****-b346-2a28ef579dea",
"uti": "QiEIwm3560-****ZLz4RAA",
"ver": "1.0"
}
I have realized that my client actually want a mix of authentication/autorization and tracing. 我已经意识到我的客户实际上想要身份验证/授权和跟踪的结合。
We also got it confirmed from Microsoft that it is not possible to retrieve the users access token in D365 online and send it along with the call to the 3rd party rest service. 我们还从Microsoft确认,无法在线检索D365中的用户访问令牌并将其与呼叫一起发送给第三方休息服务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.