Web Uygulamalarında Dynamics 365 Web API ‘ye Javascript İle Erişim

Bu yazı 04 Mayıs 2019 tarihinde Medium/@dynamics365 altında yayınlanmıştır. 17 Mayıs 2020 tarihinde emregulcan.com altında taşınmıştır.

İçerikler, yazının oluşturulduğu tarih için geçerli olup, Microsoft Dynamics 365 CE, Power Platform ve Azure hizmetlerinin sürekli iyileştirme ve güncelleme döngüsünden dolayı paylaşılan bilgilerde değişiklikler meydana gelmiş olabilir.

Merhaba,

Önceki yazımızda Application User üzerinden S2S (Server-to-Server) entegrasyon ile Dynamics 365 CE (CRM) Web API ‘ye erişim konusunu detaylı olarak incelemiştik ve S2S entegrasyon yapısında Client (Application) ID ve Client Secret bilgilerini kullanarak OAuth Client Credentials Grant yapısı üzerinden Access Token elde etmiştik. Fakat bu yöntemin Javascript ile uygulamasının güvenlik açısından doğru olmadığını belirtmiştim.

Eğer web projelerinizde Dynamics 365 CE (CRM) ‘de yönetici yetkisiyle işlem yapmanız gerekiyorsa bunu client-side kodlarınızda değil backend olarak kullanacağınız bir Web API ya da Azure Functions vb. üzerinden çözmeniz güvenlik açısından çok daha doğru olacaktır.

Bu yazıda web uygulamalarında Javascript ile Dynamics 365 CE (CRM) Web API erişimini ve ADAL.js kullanarak Active Directory Authentication işlemlerini detaylı olarak anlatacağım.

Daha önce hazırlamış olduğumuz Active Directory Application bilgilerini kullanarak Active Directory Authentication işlemi yapabilmek için Microsoft tarafından sunulan ADAL for JS isimli kütüphaneyi kullanacağız. Bu kütüphanenin sağlamış olduğu fonksiyonlar ile Authentication işlemini tamamlayıp, eğer kullanıcı başarılı olarak login olursa bir Access Token elde edeceğiz. Dynamics 365 CE (CRM) Web API ile yapacağımız tüm işlemlerde bu Access Token ‘ı kullanacağız.

Azure Active Directory Authentication işlemleri için Microsoft tarafından sağlanan tüm kütüphanelere https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries ve https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-v2-libraries adresinden erişebilirsiniz.

ADAL for JS open-source bir kütüphane, hem kodlarını incelemek hem de Issue kayıtlarına ulaşmak isterseniz https://github.com/AzureAD/azure-activedirectory-library-for-js adresine bakabilirsiniz.

Yazıyı hazırladığım tarihte güncel sürüm 1.0.17 olarak belirtilmiş, aşağıdaki <script> tag ‘ını kullanarak web sayfanıza ekleyebilirsiniz, ayrıca NPM ya da Bower ‘da kullanabilirsiniz.

<script src='https://secure.aadcdn.microsoftonline-p.com/lib/1.0.17/js/adal.min.js' />

Web sayfamızda Javascript ile Dynamics 365 CE (CRM) Web API erişimi için aşağıdaki bilgiler gerekli;

  • Dynamics 365 CE (CRM) Organization URL : Dynamics 365 CE (CRM) instance url bilgisi (http://ORGANIZASYON.crm4.dynamics.com formatında)
  • Client (Application) ID : Azure Active Directory ‘de tanımlı olan Application için Application ID bilgisi
  • Redirect (Callback) URI : Active Directory ‘de tanımlı olan Application için Redirect URI bilgisi. Development aşamasında kendi bilgisayarınızı kullanıyorsanız (localhost), bu bilginin de Application tarafında tanımlanmış olması gerekli.
  • Tenant : Azure Active Directory Tenant ID (GUID) ya da domain bilgisi. (organizasyonadı.onmicrosoft.com formatında), bu bilgi opsiyoneldir.

Dynamics 365 CE (CRM) Web API ile işlem yapacağımız için tenant bilgisini vererek çalışmamız daha doğru olacaktır. Eğer multi-tenant olarak işlem yapmak istiyorsanız diğer organizasyonlara ait kullanıcıların Dynamics 365 CE (CRM) ‘e yetkilendirmesini yapmanız gerekmekte. Bu yazının konusu olmadığı için detaylara girmiyorum.

Son olarak Active Directory 2de tanımlı Application için Manifest dosyasında oauth2AllowImplicitFlow değerinin true olması gerekiyor.

Authentication İşlemi

İlk olarak kullanıcıyı doğrulamamız gerekli, bunun için ADAL for JS kütüphanesini kullanarak kullanıcıyı Authentication ekranına yönlendirmeliyiz.

Aşağıdaki <script> tag ‘ını web sayfamıza ekleyerek başlayalım;

<script src='https://secure.aadcdn.microsoftonline-p.com/lib/1.0.17/js/adal.min.js' />

Öncelikle AuthenticationContext oluşturmamız gerekli. AuthenticationContext constructor içinde Config datası beklemekte, basit olarak aşağıdaki gibi bir Config yapısı oluşturabilirsiniz, tüm parametreler için https://github.com/AzureAD/azure-activedirectory-library-for-js/wiki/Config-authentication-context#configurable-options adresine bakabilirsiniz.

AuthenticationContext Config parametreleri
AuthenticationContext Config parametreleri

clientId parametresi zorunludur, yukarıda bahsetmiş olduğum Azure Active Directory Application bilgisini bu parametreye göndermelisiniz.

tenant parametresinin default değeri common ‘dır ve multi-tenant authentication işlemine izin verir. Bu durumda tüm Microsoft hesapları bu uygulamaya login olabilir. Eğer multi-tenant işlemlere izin vermek istiyorsanız tenant parametresini eklemenize gerek yok. Sadece belirli bir tenant için işlem yapmak istiyorsanız tenant parametresi için değer atamalısınız.

popUp parametresine true vererek login ekranının popup olarak açılmasını sağlayabiliriz. Default değeri false olduğu için bu parametreyi eklemezsek login ekranı aynı sayfada yönlendirilecektir.

callback parametresine bir fonksiyon verip, authentication işlemi için token ve error detaylarını alabilirsiniz. Burada dönen token bilgisi id_token türünde olup, API erişiminde kullanacağımız access_token ile aynı değildir. (bu parametre opsiyoneldir, kullanmayabilirsiniz)

Callback fonksiyonunun imzası aşağıdaki şekilde olmalıdır, parametreler neden düzensiz bilmiyorum :), Github sayfasında bu şekilde örnek verilmiş.

callbackFunction(errorDesc, token, error, tokenType);

id_token ‘lar authentication işlemi sonucunda ilgili kullanıcının profil bilgilerini vb. içerirler. Elde ettiğiniz id_token bilgisini https://jwt.io adresinden clear-text olarak dönüştürüp içeriğini inceleyebilirsiniz.

id_token hakkında detaylı bilgi edinmek için Takahiko Kawasaki ‘nin yazmış olduğu https://medium.com/@darutk/understanding-id-token-5f83f50fa02e yazıyı okuyabilirsiniz.

Authentication işlemini yönetmek için aşağıdaki gibi bir fonksiyon hazırlayıp, sayfanız yüklendiğinde çağırabilirsiniz ($(document).ready(function(){ authenticate(); });), böylece eğer internet tarayıcısında daha önce açılmış bir oturum varsa kullanıcı direkt olarak sayfanıza girebilir.

Authentication kodu
Authentication kodu

Kodu incelediğimizde;

authContext = new AuthenticationContext(config); ile yeni bir AuthenticationContext oluşturuyoruz, bu nesne ADAL.js kütüphanesinde bulunmakta.

user = authContext.getCachedUser(); ise oturum açmış (Authenticated) kullanıcıyı elde etmemizi sağlıyor.

Diğer satırlarda ise Authentication işleminde bir hata olup olmadığını ve sayfanın callback durumunu kontrol ediyoruz. Authentication işlemi başarıyla tamamlandıktan sonra Access Token alarak, Dynamics 365 CE (CRM) Web API ile işlem yapabiliriz.

Access Token Oluşturma ve Dynamics 365 Web API Kullanımı

Access Token alabilmek için ADAL.js ‘nin acquireToken fonksiyonunu kullanmalıyız, bu fonksiyon arkaplanda işlem yaparak Access Token almaktadır.

acquireToken fonksiyonu parametre olarak resource ve callback almaktadır.

resource parametresine Dynamics 365 CE (CRM) url bilgimizi (örnek : https://organizasyonadi.crm4.dynamics.com) gönderiyoruz.

callback ise function(errorDesc, token, error) imzalı bir fonksiyon olmalı. Biz Dynamics 365 CE (CRM) Web API ‘ye bu callback fonksiyon içinde erişeceğiz, isterseniz acquireToken fonksiyonunun içinde isterseniz bağımsız bir fonksiyon olarak yazabilirsiniz.

AuthenticationContext acquireToken fonksiyonu
AuthenticationContext acquireToken fonksiyonu

Kodu incelediğimizde;

Öncelikli olarak error ve token doğrulamasını yapıyoruz, eğer error varsa yada token değeri oluşmamışsa hata mesajını ekrana yazdırıyoruz.

Session timeout ya da oturumda olan kullanıcının parolasının değiştirilmesi vb. gibi durumlarda acquireToken fonksiyonu hata verecektir, bu durumda yeniden Authentication işlemi için yapılması için otomatik olarak login ekranına yönlendirme yapıyoruz.

config.popUp değerine göre acquireTokenPopup ya da acquireTokenRedirect fonksiyonun çağırmamız gerekli, böylece kullanıcıyı login ekranına yönlendirebiliriz.

Eğer Authentication işlemi başarılı olmuş ve token değeri alınmış ise (else bölümü), elde etmiş olduğumuz Access Token ile Dynamics 365 CE (CRM) Web API ‘den contacts bilgilerini alıyoruz.

Web API isteğini bu örnekde jQuery Ajax ile yaptım, isterseniz XmlHttpRequest kullanabilirsiniz. beforeSend içinde request ‘e Authorization Header ile token bilgisini iletiyoruz, eğer bunu yapmazsak HTTP 401 — UnAuthorized hatası alırız.

Hazırlamış olduğum demo projenin ekran görüntüleri aşağıdaki gibi.

Kullanıcı ilgili web sayfamıza giriş yaptığında aşağıdaki gibi bir ekran ile karşılaşıyor.

Karşılama ve Oturum Açma Ekranı
Karşılama ve Oturum Açma Ekranı

Giriş Yap butonuna tıkladığında 2 senaryomuz bulunmakta;

1- Mevcut internet tarayıcısında herhangi bir oturum yoksa Config.popUp ayarında belirttiğimiz şekilde Authentication ekranına yönlendirme yapılır. Eğer daha önce farklı hesaplar kullanmışsanız ekranda bunlar listelenebilir, Use another account seçeneği ile yeni bir hesap ile oturum açabilirsiniz.

Aşağıdaki ilk 2 ekran görüntüsünde single-tenant ve multi-tenant için yapılmış authentication çağrıları görünmekte.

Single-tenant olduğunda https://login.microsoftonline.com/dynamics365turkiye.onmicrosoft.com/oauth2/authorize….. olarak yönlendirilmekte.

Multi-tenant olduğunda ise https://login.microsoftonline.com/common/oauth2/authorize….. olarak yönlendirilmekte.

Authentication Popup Ekranı — single tenant
Authentication Popup Ekranı — single tenant
Authentication Popup Ekranı — multitenant
Authentication Popup Ekranı — multitenant
Authentication Popup Ekranı — Daha önce kullanılmış hesapların listesi
Authentication Popup Ekranı — Daha önce kullanılmış hesapların listesi

Eğer uygulama için yönetici tarafından genel bir izin verilmemiş ise giriş yapan kullanıcılar için aşağıdaki gibi bir onay ekranı çıkmaktadır.

Authentication Popup Ekranı — Yetkilendirme
Authentication Popup Ekranı — Yetkilendirme

2- Eğer daha önce oturum açılmış ise (ve bu hesap uygulama tarafında yetkili ise), AuthenticationContext kullanıcıyı bulduğu için “korumalı alan”a yönlendirme yapılır ve kullanıcı istediği işlemleri yapabilir.

Basit bir demo uygulama olduğu için user nesnesini kullanarak isim ve soyad ile bir karşılama yapıyoruz.

Ayrıca Dynamics 365 datalarını yükle butonu ile Web API çağrısı yaptığımız ve gelen dataları tablo olarak gösterdiğimiz bir bölüm bulunmakta.

Authentication işlemi sonrası korumalı alan
Authentication işlemi sonrası korumalı alan
Authentication işlemi sonrası korumalı alan
Authentication işlemi sonrası korumalı alan

Güvenli Çıkış butonunu kullanarak oturumu sonlandırabiliriz.


Diğer Bileşenler / Yardımcı Kütüphaneler

Community ‘de Dynamics 365 CE (CRM) Web API ile ilgili olarak bir çok yardımcı kütüphane bulunmakta, bunlardan bir kaçını aşağıda bulabilirsiniz. Ben henüz test etmedim, fakat vakit buldukca her biri için ayrı yazılar hazırlamayı düşünüyorum.

https://github.com/emregulcan/dynamics365turkiye adresinden tüm örnek kodlara ulaşabilirsiniz. Bu yazının projesi MediumD365.Web.ConnectWebAPIWithADALJS isimli web projesi. Kendi bilgilerinize göre uygulamayı çalıştırmak için organizationURI, tenant, clientId ve redirectURI bilgilerini düzenlemeniz yeterli olacaktır.

Umarım faydalı bir yazı olmuştur.

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.