https://www.buraksenyurt.com/Burak Selim Şenyurt - WCF 4.0 RC2010-03-22T11:24:14+00:00Matematik Mühendisi Bir Bilgisayar Programcısının NotlarıBurak Selim SenyurtBlogEngine.Net Syndication Generatorhttps://www.buraksenyurt.com/opml.axdBurak Selim SenyurtMatematik Mühendisi Bir Bilgisayar Programcısının Notlarıtr-TRBurak Selim Şenyurt0.0000000.000000https://www.buraksenyurt.com/post/Workflow-Services-Custom-AuthorizationWorkflow Services - Custom Authorization2010-03-22T04:30:00+00:00bsenyurt<p><img style="float: right;" src="/pics/2010%2f2%2fblg145_Giris.jpg" alt="" />Merhaba Arkadaşlar,</p>
<p>Aşçılık zevkli ama bir o kadarda zor bir zanaattır. Hatta bazen o kadar zor bir zanaat olur ki, aşcının aldığı maaşı pek çok yazılımcı iki yılda kazanamaz. Tabi bu tip aşçılar işin ehli olan kişilerdir. Heleki tek bir mutfak değilde dünya mutfağının seçkin olanlarına ait becerileri bulunanlara paha biçilemez. Türk Mutfağından Japon mutfağına, Meksika yemeklerinden İtalyan spesiyallerine, Fransız tatlılarından Okyanus deniz ürünlerine ve daha nicelerine...</p>
<p>Tabi bir aşçı için olmassa olmazlardan birisi de yemeği için gerekli olan malzemelerin kalitesidir. Kaliteli zeytinyağı, hamur ve baharat ile yapılan spagettinin, kalitesiz olanlar ile yapılanı arasında dağlar kadar fark olabilir. Spagetti demişken bu günkü yazımızda neler yapacağımıza da bir bakalım dilerseniz. Aşçı olarak bu gün elimizde zor bir tarif var. Malzemelerimiz belli ama pişecek olan yemeğin yapımı biraz zahmetli. Haydi gelin hiç vakit kaybetmeden önlüğümüzü takıp klavyenin başına geçelim.<img title="Wink" src="/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" alt="Wink" border="0" /></p>
<p>Bu yazımızda <strong>.Net Framework 4.0</strong> tarafında geliştireceğimiz <strong>Workflow Service'</strong> lerde yetkilendirme işlemini nasıl sağlayabileceğimizi görmeye çalışacağız. Ne yazık ki <strong>Authorization</strong> işlemini kolaylaştırmak adına hazır bir yapı mevcut değil. Bu nedenle biraz kodlama yapmamız ve çalışma zamanının işleyişine bu şekilde müdahale etmemiz gerekiyor. Hatta yapacağımız özelleştirme öylesine etkili olacak ki, aradan <strong>Doğrulamayı(Authentication)</strong> bile çıkaracağız farkına varmadan. <img title="Surprised" src="/editors/tiny_mce3/plugins/emotions/img/smiley-surprised.gif" alt="Surprised" border="0" /> Ama önce yemek için gerekli malzemelerimizin neler olduğuna bir bakalım.</p>
<ul>
<li>Bir adet <strong>Workflow Service.</strong></li>
<li>Bir adet konfigurasyon dosyası<strong>(Web.config).</strong></li>
<li><strong>System.IdentityModel.dll</strong> referansı.</li>
<li><strong>ServiceAuthorizationManager</strong> türevli bir sınıf.</li>
<li><strong>Windows</strong> üzerinde tanımlanmış roller ve bu roller içerisinde yer alan kullanıcılar.</li>
</ul>
<p>Tabiki malzemeleri tedarik etmek yeterli değil. Birde tarifi bilmek lazım <img title="Wink" src="/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" alt="Wink" border="0" /> Öncelikli olarak yetkilendirme işlemini üstelenen bir sınıf yazmamız gerekiyor. Çok doğal olarak bu sınıfın <strong>Workflow Service</strong> çalışma zamanı tarafından değerlendirilebilmesi için konfigurasyon dosyası üzerinde de gerekli düzenlemeleri yapmalıyız. Sonrasında ise işi istemci tarafından gelen taleplere bırakıyor olacağız. İşe ilk olarak aşağıdaki gibi bir <strong>Workflow Service</strong> projemiz olduğunu varsayarak başlayalım.</p>
<p><img src="/pics/2010%2f2%2fblg145_Wf.gif" alt="" /></p>
<p><strong>Calculus.xamlx</strong> içeriğimiz ise aşağıdaki gibidir;(<em>Sadece Sequence elementi içeriği verilmiştir)</em></p>
<pre class="brush:xml;auto-links:false;toolbar:false" contenteditable="false"><p:Sequence DisplayName="Sequential Service" sad:XamlDebuggerXmlReader.FileName="D:\Projects\Workflow Foundation 4.0\UsingCustomAuthorization\UsingCustomAuthorization\CalculusService.xamlx" sap:VirtualizedContainerService.HintSize="277,336">
<p:Sequence.Variables>
<p:Variable x:TypeArguments="CorrelationHandle" Name="handle" />
<p:Variable x:TypeArguments="x:Int32" Name="X" />
<p:Variable x:TypeArguments="x:Int32" Name="Y" />
<p:Variable x:TypeArguments="x:Int32" Name="Sum" />
</p:Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Receive x:Name="__ReferenceID0" CanCreateInstance="True" DisplayName="ReceiveRequest" sap:VirtualizedContainerService.HintSize="255,86" OperationName="SumOp" ServiceContractName="p1:IService">
<Receive.CorrelatesOn>
<MessageQuerySet />
</Receive.CorrelatesOn>
<Receive.CorrelationInitializers>
<RequestReplyCorrelationInitializer CorrelationHandle="[handle]" />
</Receive.CorrelationInitializers>
<ReceiveParametersContent>
<p:OutArgument x:TypeArguments="x:Int32" x:Key="XValue">[X]</p:OutArgument>
<p:OutArgument x:TypeArguments="x:Int32" x:Key="YValue">[Y]</p:OutArgument>
</ReceiveParametersContent>
</Receive>
<SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendResponse" sap:VirtualizedContainerService.HintSize="255,86">
<SendParametersContent>
<p:InArgument x:TypeArguments="x:Int32" x:Key="SumResult">[X + Y]</p:InArgument>
</SendParametersContent>
</SendReply>
</p:Sequence></pre>
<p>Aslında <strong>Calculus</strong> isimli <strong>Workflow Service</strong> içerisinde yer alan <strong>SumOp</strong> isimli operasyonun görevi çok basit ve bellidir. <strong>Int32</strong> tipinden iki sayısal değerin toplanması ve sonucunun istemci tarafına geri döndürülmesi. Bizim hedefimiz sadece yetkisi olan kişilerin bu operasyonu çalıştırmasıdır. Bu durumda güvenlik ile ilişkili olarak yetki kontrolünün özel bir sınıf tarafından yapılması gerekmektedir. Söz konusu sınıf <strong>System.ServiceModel</strong> <strong>isim alanı(Namespace)</strong> altında yer alan <strong>ServiceAuthorizationManager</strong> tipinden türetilmelidir. İçeriğini ise çok sade olarak aşağıdaki gibi tasarlayabiliriz.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">using System.Collections.Generic;
using System.Security.Principal;
using System.ServiceModel;
namespace UsingCustomAuthorization
{
public class Authorizer
: ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
var authCtx = operationContext.ServiceSecurityContext.AuthorizationContext;
var identities=(List<IIdentity>)authCtx.Properties["Identities"];
foreach (var identity in identities)
{
var winIdentity = identity as WindowsIdentity;
if (winIdentity != null)
{
var winPrincipal = new WindowsPrincipal(winIdentity);
return winPrincipal.IsInRole("Administrators");
}
}
return false;
}
}
}</pre>
<p><strong>Authorizer</strong> sınıfı içerisinde <strong>CheckAccessCore</strong> metodu ezilmiş ve parametre olarak gelen <strong>operationContext</strong> değişkeninden yararlanarak gerekli yetki kontrolü yapılmıştır. Buna göre <strong>Workflow</strong> <strong>Service' </strong>ten talepte bulunan bir <strong>Windows</strong> kullanıcısı, servisin host edildiği makinede tanımlı ise, <strong>Administrators</strong> rolünde olup olmadığı kontrol edilmekte ve buna göre geriye <strong>true</strong> veya <strong>false</strong> değeri döndürülmektedir. Tahmin edileceği üzere <strong>CheckAccessCore</strong> metodunun geriye <strong>false</strong> değer döndürmesi güvenlik hatasına yol açacaktır. Burada unutulmaması gereken bir noktayı da hatırlatmak yarar var. Örneğimizde konuyu son derece basit bir şekilde ele almak istediğimizden, doğrudan <strong>Administrator</strong> rolünün kontrolünü yapıp işin içinden sıyrılmaktayız. Oysaki yetki kontrolü için harici bir listeden yararlanılabilir. Bu liste <strong>web.config</strong> dosyasında <strong>appSettings </strong>kısmında tutulabileceği gibi bir <strong>Text</strong> dosya içerisinde veya <strong>veritabanı</strong> üzerindeki bir <strong>tabloda</strong> konuşlandırılabilir. Yinede varmak istediğimiz noktayı anladığınızı düşünerek devam ediyorum.</p>
<p>Sırada çalışma zamanı için <strong>Authorizer</strong> sınıfının yetki kontrolü amacıyla kullanılacağını bildirmemiz gerekiyor. Bunun için <strong>web.config</strong> dosyasını aşağıdaki şekilde düzenlememiz yeterli olacaktır.<em>(Bu arada projemize <strong>System.IdentityModel.dll assembly'</strong> ını referans etmeyi unutmamalıyız. Aksi takdirde <strong>authCtx</strong> üzerinden hiç bir özelliğe erişemeyiz)</em></p>
<pre class="brush:xml;auto-links:false;toolbar:false" contenteditable="false"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization serviceAuthorizationManagerType="UsingCustomAuthorization.Authorizer, UsingCustomAuthorization"/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding"/>
</protocolMapping>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration></pre>
<p>Dikkat edileceği üzere <strong>serviceAuthorization</strong> elementi ile yetkilendirme davranışını ele alacak <strong>Authorizer</strong> tipi belirlenmiştir. Ayrıca iletişimin güvenli olmasını sağlamak adına <strong>protocolMapping</strong> sekmesinde <strong>wsHttpBinding</strong> bağlayıcı tipinin kullanılacağı bildirilmiştir. İşte bu kadar. <img title="Wink" src="/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" alt="Wink" border="0" /> Artık yemeğimizi orta ateşte 40 dakika kadar pişirip servis edebiliriz. Tabi servis etmeden önce tadına bakmak gerekmektedir. Nasıl mı?</p>
<p>Öncelikli olarak <strong>Administrator</strong> rolünde olan ve olmayan iki test kullanıcımız olduğunu düşünelim. Ben, örneği geliştirmekte olduğum makinede bu amaçla <strong>bsenyurt</strong> ve <strong>runi</strong> isimli iki kullanıcı oluşturdum. Bu kullanıcılardan <strong>bsenyurt</strong> <strong>Administrator </strong>rolünde iken <strong>runi User</strong> rolü içerisinde yer almakta. Dolayısıyla test sonuçlarımıza göre <strong>runi</strong> isimli kullanıcı talebi karşılığında <strong>Access Denied</strong> hata mesajını almalı. Bakalım gerçektende böylemi oldu?</p>
<p><strong>WcfTestClient </strong>uygulamamızı <strong>Run As..</strong> komutu yardımıyla önce <strong>bsenyurt</strong> kullanıcısı ile çalıştıralım. Eğer <strong>Asp.Net Developement Server'</strong> ı <strong>Visual Studio </strong>ortamına <strong>Attach' </strong>larsak <strong>CheckAccessCore </strong>metodu içeriğini de <strong>debug</strong> edebiliriz. Buna göre <strong>debug</strong> modunda aşağıdaki sonuçlar ile karşılaşırız.</p>
<p><img src="/pics/2010%2f2%2fblg145_Debug1.gif" alt="" /></p>
<p>Görüldüğü üzere <strong>bsenyurt</strong> kullanıcısı doğrulanmıştır. <strong>IsAuthenticated</strong> değerinin <strong>true</strong> olduğuna dikkat edelim. Şimdi <strong>WcfTestClient</strong> uygulamasının sonuç ekranına bakarsak toplama işleminin başarılı bir şekilde gerçekleştirildiğini görebiliriz.</p>
<p><img src="/pics/2010%2f2%2fblg145_AccessGaranted.gif" alt="" /></p>
<p>Şimdi de <strong>WcfTestClient</strong> aracını <strong>Runi</strong> isimli kullanıcı ile çalıştıralım. <strong>Debug</strong> modda aşağıdaki sonuçlar ile karşılaşırız.</p>
<p><img src="/pics/2010%2f2%2fblg145_Debug2.gif" alt="" /></p>
<p>Tahmin edileceği üzere <strong>Runi</strong> isimli kullanıcı da doğrulanmıştır. Nitekim servisin çalıştırıldığı makine de tanımlı bir <strong>Windows</strong> kullanıcısıdır. Ancak <strong>WcfTestClient</strong> uygulaması üzerinden bir toplama işlemi talebinde bulunulduğunda hata mesajı ile karşılaşılacaktır.</p>
<p><img src="/pics/2010%2f2%2fblg145_AccessDenied.gif" alt="" /></p>
<p>Volaaaaa!!! Bu çok doğaldır. Nitekim <strong>Runi</strong> isimli kullanıcı <strong>Administrators </strong>grubuna dahil değildir ve bu yüzden yetki kontrolünden geçememiştir.</p>
<p>Yapmış olduğumuz bu çalışmaya göre bir <strong>Workflow Service'</strong> ini host ettiğimiz sunucu üzerindeki <strong>Windows</strong> kullanıcılarından ve dahil oldukları grup bilgilerinden yararlanarak az bir kodlama ile doğrulama ve yetkilendirme işlemlerini gerçekleştirebiliriz. Afiyet olsun <img title="Wink" src="/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" alt="Wink" border="0" /></p>
<p><a href="https://www.buraksenyurt.com/pics/2010%2f2%2fUsingCustomAuthorization_RC.rar">UsingCustomAuthorization_RC.rar (17,67 kb)</a> <strong>[Örnek Visual Studio 2010 Ultimate RC sürümü üzerinde geliştirilmiş ve test edilmiştir]</strong></p>2010-03-22T04:30:00+00:00workflow serviceswf 4.0wcf 4.0bsenyurtBu yazımızda .Net Framework 4.0 tarafında geliştireceğimiz Workflow Service' lerde yetkilendirme işlemini nasıl sağlayabileceğimizi görmeye çalışacağız.https://www.buraksenyurt.com/pingback.axdhttps://www.buraksenyurt.com/post.aspx?id=a42af483-997f-467a-a56d-41159d0f99e30https://www.buraksenyurt.com/trackback.axd?id=a42af483-997f-467a-a56d-41159d0f99e3https://www.buraksenyurt.com/post/Workflow-Services-Custom-Authorization#commenthttps://www.buraksenyurt.com/syndication.axd?post=a42af483-997f-467a-a56d-41159d0f99e3