zoukankan      html  css  js  c++  java
  • 在插件中使用Secure Configuration

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复409或者20200510可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

    在插件中使用Secure Configuration 的官方文档请参考 Write a plug-in 的 Pass configuration data to your plug-in 章节,本博文参考了 What is Unsecure/Secure Configuration on a Dynamics CRM/365 for Enterprise Plugin? 。在Action中获取输入参数和设置输出参数的值则参考了  Setting Output Parameters in Plugins for Custom Actions

    首先我需要修改前面博文 Dynamics 365通过Action调用Graph API获取用户经理信息  创建的Action,将其所有的步骤去掉,然后激活。如下:

    我使用的插件代码如下,我这里面获取了secure configuration的值。

    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    using System;
    using System.Net.Http;
    using System.IO;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Xml.Linq;
    using System.Linq;
    
    namespace DemoPlugins
    {
        public class GetUserManagerActionPost : IPlugin
        {
            private readonly string _secureString;
    
            public GetUserManagerActionPost(string unsecureString, string secureString)
            {
                if (String.IsNullOrEmpty(secureString))
                {
                    throw new InvalidPluginExecutionException("Secure strings are required for this plugin to execute.");
                }
    
                _secureString = secureString;
            }
    
            public void Execute(IServiceProvider serviceProvider)
            {
                ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
                tracingService.Trace($"Enter {this.GetType()} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService orgSvc = serviceFactory.CreateOrganizationService(context.UserId);
                try
                {
                    string userEmail = string.Empty;
                    if (context.InputParameters.Contains("UserEmail") && context.InputParameters["UserEmail"] is string)
                    {
                        userEmail = context.InputParameters["UserEmail"].ToString();
                    }
                    if (string.IsNullOrEmpty(userEmail))
                    {
                        if (context.InputParameters.Contains("User") && context.InputParameters["User"] is EntityReference)
                        {
                            var user = (EntityReference)context.InputParameters["User"];
                            userEmail = orgSvc.Retrieve("systemuser", user.Id, new ColumnSet("internalemailaddress")).GetAttributeValue<string>("internalemailaddress");
                        }
                    }
                    if (string.IsNullOrEmpty(userEmail))
                    {
                        throw new InvalidPluginExecutionException("EmailAddr is empty!");
                    }
                    tracingService.Trace($"UserEmail = {userEmail} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                    XElement secureXml = XElement.Parse(_secureString);
                    var clientId = (from item in secureXml.Descendants("ClientId") select item).FirstOrDefault().Value;
                    var clientSecret = (from item in secureXml.Descendants("ClientSecret") select item).FirstOrDefault().Value;
                    var tenantId = (from item in secureXml.Descendants("TenantId") select item).FirstOrDefault().Value;
                    var scope = (from item in secureXml.Descendants("Scope") select item).FirstOrDefault().Value;
                    string tokenUrl = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
                    AuthResponse authRepsonse = null;
                    using (HttpClient httpClient = new HttpClient())
                    {
                        var authRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
                        var requestBody = new StringContent($"client_id={clientId}&scope={scope}&client_secret={clientSecret}&grant_type=client_credentials");
                        requestBody.Headers.ContentType.MediaType = "application/x-www-form-urlencoded";
                        authRequest.Content = requestBody;
                        var authResponseStr = httpClient.SendAsync(authRequest).Result.Content.ReadAsStringAsync().Result;
                        tracingService.Trace($"authResponseStr = {authResponseStr} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                        using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(authResponseStr)))
                        {
                            DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(AuthResponse));
                            authRepsonse = (AuthResponse)deseralizer.ReadObject(ms);
                        }
                        if (authRepsonse != null && !string.IsNullOrEmpty(authRepsonse.access_token))
                        {
                            var request = new HttpRequestMessage(HttpMethod.Get, $"https://graph.microsoft.com/v1.0/users/{userEmail}/manager?$select=displayName,mail");
                            //request.Headers.Add("otherheraderitem", "headeritemvalue");
                            //request.Content = new StringContent(inJson, Encoding.UTF8, "application/json");
                            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authRepsonse.access_token);
                            var getUserResponseStr = httpClient.SendAsync(request).Result.Content.ReadAsStringAsync().Result;
                            tracingService.Trace($"getUserResponseStr = {getUserResponseStr} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(getUserResponseStr)))
                            {
                                DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(GetUserResponse));
                                var getUserResponse = (GetUserResponse)deseralizer.ReadObject(ms);
                                context.OutputParameters["ManagerName"] = getUserResponse.displayName;
                                context.OutputParameters["ManagerEmail"] = getUserResponse.mail;
                            }
                        }
                        else
                        {
                            throw new InvalidPluginExecutionException($"Get access token error!" + authResponseStr);
                        }
                    }
                    tracingService.Trace($"Leave {this.GetType()} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                }
                catch (Exception ex)
                {
                    tracingService.Trace($"{this.GetType()} encountered unexpected exception: {ex.Message + ex.StackTrace} on {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss:ms")}");
                    throw new InvalidPluginExecutionException(ex.Message + ex.StackTrace);
                }
            }
        }
    
        public class AuthResponse
        {
            public string access_token { get; set; }
            public int expires_in { get; set; }
            public int ext_expires_in { get; set; }
            public string token_type { get; set; }
        }
    
        public class GetUserResponse
        {
            public string displayName { get; set; }
    
            public string mail { get; set; }
        }
    }

    创建或者更新插件插件程序集后,需要注册步骤。

    注册的步骤如下,注意,一定要注册在PostOperation阶段。

    我使用的Secure Configuration示例:

    <GraphAuthInfo>
    <ClientId>xxx</ClientId>
    <TenantId>xxxx</TenantId>
    <ClientSecret><![CDATA[xxx]]></ClientSecret>
    <Scope><![CDATA[https%3A%2F%2Fgraph.microsoft.com%2F.default]]></Scope>
    </GraphAuthInfo>
    

      

  • 相关阅读:
    DataReader对象
    程序员感悟——路该怎么走
    采访:服务器系统企业选择了谁? java程序员
    Android 设置Activity大小不再全屏原理 java程序员
    学习软件开发千万不要犯的错误 java程序员
    XML布局技巧 java程序员
    Android 书籍 java程序员
    使用jQuery开发一个响应式超酷整合RSS信息阅读杂志 java程序员
    软件开发工程师的20条编程经验 java程序员
    jsp中文乱码完美解决方案(原创) java程序员
  • 原文地址:https://www.cnblogs.com/luoyong0201/p/Dynamics_365_Plugin_Development_Using_Secure_Configuration.html
Copyright © 2011-2022 走看看