使用ADAL通过Angular 2对Dynamics CRM Web API进行未经授权的HTT
我正在尝试使用Angular创建一个可以通过Web API连接到Dynamics CRM的应用程序.这些是我遵循的步骤:
1.在Azure中注册本机应用程序,授予所需的委派权限并更新清单以允许隐式流. 2.在CRM中创建应用程序用户,将其应用程序ID设置为等于我的Azure注册应用程序的客户端ID.为我的应用程序用户分配了自定义安全角色. 3.克隆了许多Angular 2快速启动Git存储库,这些存储库通过ADAL(例如this one)通过Azure AD进行身份验证. 4.更新了克隆代码的adal配置,设置了我的租户,clientId,redirectUri和端点. 到目前为止,这已经成功了.我可以通过我的浏览器启动应用程序并登录,作为我的应用程序用户或作为Azure AD一部分的其他CRM用户.这会返回一个令牌. 5.尝试将http.get发送到v8.0或v8.2(我被告知v8.2不支持跨域调用): getEntities(): Promise<any> { let token = this.adalService.getCachedToken(this.adalService.config.clientId); let headers = new Headers({ 'Authentication': 'Bearer ' + token,'Accept': 'application/json','Content-Type': 'application/json; charset=utf-8','OData-MaxVersion': '4.0','OData-Version': '4.0' }); let options = new RequestOptions({ headers: headers }); return this.http.get(`${crmURL}/api/data/v8.2/accounts`,options) .toPromise() .then((res) => { return res; }) .catch((e) => { console.error(e); }); } 6.收到此错误消息: 它写道: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. 查看我的Chrome浏览器的网络标签,我收到两个回复: 回应1 一般 Request URL:https://ms-dyn365-prevxxxxxx/api/data/v8.2/accounts Request Method:OPTIONS Status Code:200 OK Remote Address:104.44.xxx.xxx:xxx Referrer Policy:no-referrer-when-downgrade 头 Access-Control-Allow-Headers:authentication,content-type,odata-maxversion,odata-version Access-Control-Allow-Methods:GET Access-Control-Allow-Origin:http://localhost:3000 Access-Control-Expose-Headers:Preference-Applied,OData-EntityId,Location,ETag,OData-Version,Content-Encoding,Transfer-Encoding,Content-Length,Retry-After Access-Control-Max-Age:3600 Content-Length:0 Date:Thu,13 Apr 2017 10:08:01 GMT Server:Microsoft-IIS/8.5 Set-Cookie:crmf5cookie=!NDyiupL55lrWWLtPQKTK52dwbxk9wdEAHeCiec0/z/7x9KWXe2dVIdQCGvL0S/HAp7F3N0OGfeWf/70=;secure; path=/ Strict-Transport-Security:max-age=31536000; includeSubDomains Vary:Origin X-Powered-By:ASP.NET 回应2 一般 Request URL:https://ms-dyn365-prevxxxxx.crm4.dynamics.com/api/data/v8.2/accounts Request Method:GET Status Code:401 Unauthorized Remote Address:104.xx.xxx.xxx:xxx Referrer Policy:no-referrer-when-downgrade 头 Cache-Control:private Content-Length:49 Content-Type:text/html Date:Thu,13 Apr 2017 10:08:01 GMT REQ_ID:b2be65bc-xxxx-4b34-xxxx-5c39812650xx Server:Microsoft-IIS/8.5 Set-Cookie:ReqClientId=xxxxxxxx-70b5-45f9-9b84-30f59481bxxx; expires=Wed,13-Apr-2067 10:08:01 GMT; path=/; secure; HttpOnly Strict-Transport-Security:max-age=31536000; includeSubDomains WWW-Authenticate:Bearer authorization_uri=https://login.windows.net/xxxxxxxx-87e4-4d81-8010-xxxxxxxxxxxxx/oauth2/authorize,resource_id=https://ms-dyn365-prevxxxxxx.crm4.dynamics.com/ X-Powered-By:ASP.NET 注意:我能够通过邮递员成功访问Web API: 1.我在Azure中为我的应用程序输入https://www.getpostman.com/oauth2/callback作为回调URL. 2.我打开Postman,设置如下参数并按下Request Token: Token Name: Token Auth URL: https://login.windows.net/common/oauth2/authorize?resource=https://ms-dyn365-prevxxxxxx.crm4.dynamics.com Access Token URL: https://login.microsoftonline.com/common/oauth2/token Client ID: xxxxxxxx-ebd3-429c-9a95-xxxxxxxxxxxx Callback URL: https://www.getpostman.com/oauth2/callback Grant Type: Authorization Code 3.这将打开我登录的网页. 4.返回一个令牌,我将其添加到Postman GET标头: Content-Type: application/json Authorization: Bearer eyJ0eXAiO... 5.在邮差中发送GET: GET https://ms-dyn365-prevxxxxxx.crm4.dynamics.com/api/data/v8.2/accounts 6.帐户已成功退回. 如果我在我的应用程序中使用相同的令牌,我仍然会收到401错误.
Access-Control-Allow-Origin表示问题是由跨域引起的.
通常,我们可以在服务器上使用JSONP或设置Access-Control-Allow-Origin标头.如果JSONP和标头都无法设置,因为服务是第三方提供者,我们还可以创建一个服务代理,允许从特定的orignal调用. 有关AJAX跨域问题的更多细节,您可以参考这个thread. 更新 在进一步调查之后,问题是服务器端问题,该问题与REST请求的特定版本有关. 8.2版本的REST目前不支持跨域.作为一种解决方法,我们可以使用8.0,对我来说效果很好,如下图所示: 附加代码演示以测试: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <base href="/"> <title></title> <script src="node_modulesangularangular.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="HomeController"> <ul class="nav navbar-nav navbar-right"> <li><a class="btn btn-link" ng-click="listAccounts()">List account info</a></li> </ul> <div ng-repeat="account in accounts"> <span>name:</span><span>{{account.name}}</span> </div> </div> </div> <script> var myApp = angular.module('myApp',[]); myApp.controller('HomeController',['$scope','$http',function ($scope,$http){ $scope.listAccounts=function(){ var req = { method: 'GET',url: 'https://{domain}.crm.dynamics.com/api/data/v8.0/accounts',headers: { 'authorization': 'Bearer eyJ0eXAiO...' } }; $http(req).then(function(response){ $scope.accounts=response.data.value },function(){ }); } }]); </script> </body> </html> 为Angular 2附加测试代码示例: https://github.com/VitorX/angular2-adaljs-crm (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |