Power Automate令牌用于Azure Function调用Dynamics CRM遇身份验证错误求助
核心问题根源
你在Power Automate中使用的是client_credentials授权模式,该模式生成的是应用级访问令牌——令牌仅代表应用本身的身份,完全不包含任何用户相关的声明(如sub用户ID、name用户名等)。而UserAssertion需要的是携带用户上下文的令牌(用于实现用户委派场景,即通过应用代用户访问资源),用无用户信息的应用令牌做断言自然会触发A silent sign-in request was sent but no user is signed in错误。
解决方案分场景处理
场景一:需代表启动Power Automate流的用户访问Dynamics CRM
要实现用户身份的传递,需让Power Automate获取用户委派令牌而非应用令牌:
调整Power Automate的令牌获取方式
放弃手动调用oauth2/token接口,改用Power Automate内置的HTTP动作并配置用户身份验证:- 添加HTTP动作,方法设为POST,URL使用v2.0端点:
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token - 身份验证类型选择「OAuth 2.0」,配置参数:
- 租户:你的租户ID或域名
- 受众:Azure Function对应的应用注册「公开API」中设置的应用ID URI
- 客户端ID:用于Power Automate身份验证的应用注册ID
- 权限:确保该应用拥有访问Azure Function的委派权限,且已完成管理员同意
- 此方式获取的令牌包含启动流的用户上下文,可用于后续的
UserAssertion。
- 添加HTTP动作,方法设为POST,URL使用v2.0端点:
调整Azure Function代码
确保应用注册已配置Dynamics CRM的委派权限(user_impersonation)并完成同意,同时修正资源参数(需指向你的Dynamics CRM实例,而非管理员服务端点):AuthenticationContext authContext = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}"); ClientCredential credential = new ClientCredential("{clientId}", "{clientSecret}"); // 替换为你的Dynamics CRM实例URL AuthenticationResult res = await authContext.AcquireTokenAsync("https://yourorg.crm.dynamics.com/user_impersonation", credential, new UserAssertion(req.GetBearerToken())); string bearerTokenforCRM = res.AccessToken;
场景二:无需用户身份,直接用应用身份访问Dynamics CRM
如果不需要模拟用户,直接用应用自身身份访问更简单:
配置应用注册权限
为Azure Function对应的应用注册添加Dynamics CRM的应用权限(注意是应用权限,而非委派权限),并完成管理员同意。Azure Function直接获取应用令牌
无需依赖Power Automate传递的令牌,直接在函数内用client_credentials模式获取Dynamics CRM的应用令牌:AuthenticationContext authContext = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}"); ClientCredential credential = new ClientCredential("{clientId}", "{clientSecret}"); // 替换为你的Dynamics CRM实例URL AuthenticationResult res = await authContext.AcquireTokenAsync("https://yourorg.crm.dynamics.com/user_impersonation", credential); string bearerTokenforCRM = res.AccessToken;
额外注意事项
- 优先使用Microsoft身份平台v2.0端点,兼容性和扩展性更好
- 可用
https://jwt.ms/解码令牌,验证是否包含用户声明:应用令牌仅含oid(应用ID),用户令牌会有sub(用户ID)、name等字段 - 严格区分「委派权限」(代用户访问)和「应用权限」(应用独立访问),确保权限类型与业务场景匹配
内容的提问来源于stack exchange,提问作者Kev_T

