You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Express.js的Web应用通过NTLM认证对接本地IFD架构Dynamics CRM

嘿,刚好之前做过类似的跨网络用Node/Express连接Dynamics CRM的场景,给你梳理下靠谱的实现方案和细节:

核心认证方案选择

因为你的Express应用部署在CRM网络之外,且是用管理员凭据做服务端程序化访问,OAuth 2.0的Client Credentials(客户端凭据)流是最适合的——这是服务对服务的认证方式,不需要用户交互,完全靠应用自身的凭据获取访问权限。

具体实现步骤

1. 先搞定Dynamics CRM侧的配置

这一步是基础,必须在Azure AD和CRM里做好配置:

  • 在Azure AD中注册一个新的应用程序,记下三个关键信息:客户端ID(Client ID)、客户端密钥(Client Secret)、租户ID(Tenant ID)
  • 登录你的Dynamics CRM实例,给这个Azure AD应用分配系统管理员(或者对应权限的角色,比如只读需求的话可以分配系统定制员或特定实体权限)
  • 确认你的CRM实例URL(比如 https://yourorg.crm.dynamics.com),后续要用到

2. 安装依赖包

用npm安装官方推荐的认证库和HTTP请求库:

npm install @azure/msal-node axios express

注:别用已经被弃用的adal-node,微软现在主推@azure/msal-node

3. 编写认证与数据获取代码

下面是完整的Express示例代码,包含token获取、CRM数据请求和路由暴露:

const msal = require('@azure/msal-node');
const axios = require('axios');
const express = require('express');
const app = express();
const port = 3000;

// MSAL核心配置,替换成你自己的信息
const msalConfig = {
    auth: {
        clientId: '你的客户端ID',
        authority: 'https://login.microsoftonline.com/你的租户ID',
        clientSecret: '你的客户端密钥'
    }
};

// 初始化MSAL客户端
const cca = new msal.ConfidentialClientApplication(msalConfig);

// 封装获取CRM访问令牌的函数
async function getCRMAccessToken() {
    const tokenRequest = {
        // Scope格式必须是CRM实例URL + /.default
        scopes: ['https://yourorg.crm.dynamics.com/.default']
    };

    try {
        const response = await cca.acquireTokenByClientCredential(tokenRequest);
        return response.accessToken;
    } catch (error) {
        console.error('令牌获取失败:', error);
        throw error;
    }
}

// 示例:获取CRM中的账户实体数据
async function fetchCRMAccounts() {
    const accessToken = await getCRMAccessToken();
    const crmApiUrl = 'https://yourorg.crm.dynamics.com/api/data/v9.2/accounts';

    try {
        const response = await axios.get(crmApiUrl, {
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0',
                'Accept': 'application/json'
            }
        });
        // 返回CRM返回的实体数据列表
        return response.data.value;
    } catch (error) {
        console.error('CRM数据请求失败:', error.response?.data || error.message);
        throw error;
    }
}

// 暴露Express路由给前端已登录用户访问
app.get('/api/crm/accounts', async (req, res) => {
    try {
        const accounts = await fetchCRMAccounts();
        res.json(accounts);
    } catch (error) {
        res.status(500).json({ message: '无法获取CRM数据,请检查配置' });
    }
});

// 启动服务器
app.listen(port, () => {
    console.log(`Express服务已启动:http://localhost:${port}`);
});

4. 关键注意事项

  • 网络连通性:确保你的Express服务器所在网络能访问CRM实例URL——如果是在线版Dynamics 365,公网一般没问题;如果是本地部署的CRM,需要配置VPN或防火墙规则允许外部访问
  • 权限校验:别只在Azure AD注册应用就完事!一定要在CRM里给这个应用分配安全角色,否则会返回403权限不足错误
  • Token缓存优化:上面的示例每次请求都获取新token,生产环境建议加个缓存逻辑(比如用Redis),避免频繁请求Azure AD浪费资源
  • API版本:示例中用的是v9.2,可以根据你的CRM版本调整对应的API版本号

5. 测试验证

启动Express服务器后,访问http://localhost:3000/api/crm/accounts,如果能返回CRM中的账户数据,说明整个流程跑通了;如果报错,先检查token是否获取成功,再排查权限和网络问题。

内容的提问来源于stack exchange,提问作者An0nC0d3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:27:55