Impersonation Using Recursive Web Services - Part II
Indonesian:
Didalam SharePoint ada beberapa method/property yang “terlarang” untuk digunakan oleh user. Salah satunya adalah, property “Roles” dari SPUser yang berguna untuk melihat role-role yang dimiliki oleh user yang bersangkutan. Otorisasi minimal yang diperlukan untuk mengetahui role-role user adalah “Manage Group”, padahal adakalanya si user hanya perlu tahu role-role yang dimilikinya sendiri. Ada beberapa cara yang dapat digunakan untuk mengatasi keterbatasan ini, salah satunya adalah dengan teknik impersonation (berpura-pura sebagai user lain dan biasanya adalah administrator site).
Pada bagian pertama, sudah dijelaskan langkah-langkah pembuatan project web service di Sharepoint. Bagian ke-2 ini akan melanjutkan implementasi teknik “Impersonation using recursive web services”.
English:
There are some methods/properties which requires special authority in Sharepoint development. One of the most importance property is “Roles” of SPUser. Imagine, when a user needs his/her Roles, he/she won’t be able to access that property because of the restriction. The minimal authority to enumerate user roles is “Manage Group” - unfortunatelly giving “Manage Group” to user will also gives him/her an Administrative rights. There are some techniques overcome this limitation, one of the proposed solution is impersonation.
In the first part, we’ve demonstrate how to prepare web service project in Sharepoint. In this part, we will continue the implementation of “impersonation using recursive web services”.
Indonesian: (see English version)
Pada bagian pertama kita sudah berhasil mempersiapkan sebuah project web service di Sharepoint. Sekarang kita akan menambahkan code di project untuk melakukan proses yang dilakukan oleh “GetRoleCollectionFromUser” dari web service UserGroup.asmx.
2. Menambahkan Code
- Hapus Services1.asmx, dan buat UserGroupProxy.asmx
- Tambahkan beberapa code dibawah, agar UserGroupProxy.asmx memiliki skema yang sama dengan web service aslinya.
[WebService(Namespace=”http://schemas.microsoft.com/sharepoint/soap/directory/”,
Description=“Web service to proxy original webservice.”
)]
public class UserGroupProxy : System.Web.Services.WebService
{_**private SPWeb currentWeb;
private string serviceUrl;
**public UserGroupProxy()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
try
{
currentWeb = SPControl.GetContextWeb(Context);
serviceUrl = currentWeb.Url + “/_vti_bin/UserGroupProxy.asmx”;
}
catch{}
}
_}**[WebMethod(Description=“Generate document number, based on current pattern”)]
public System.Xml.XmlNode GetRoleCollectionFromUser(string userLoginName)
{
System.Xml.XmlNode resultXml;
try
{
****UserGroup userGroup = new UserGroup();
userGroup.Url = currentWeb.Url + “/_vti_bin/UserGroup.asmx”;
resultXml = userGroup.GetRoleCollectionFromUser(userLoginName);
}
catch
{
**/********************************************
UserGroupProxyWS userGroup = new UserGroupProxyWS();
userGroup.Url = serviceUrl;
userGroup.Credentials = new System.Net.NetworkCredential(****REPLACE******);
****resultXml = userGroup.GetRoleCollectionFromUser(userLoginName);
__********************************************/
}**__return resultXml;
}
}
Bagian yang diberi latar belakang merah, UserGroup userGroup = new UserGroup(); , sengaja langsung memanggil web service aslinya (UserGroup.asmx) agar pekerjaan kita menjadi lebih cepat (tidak perlu membuat konstruksi response XML lagi). Bagian tersebut adalah proses pencarian role yang dimiliki oleh seorang user, dan bisa diperoleh dengan
SPUser currentUser = this.currentWeb.CurrentUser
SPRoleCollection roles = currentUser.Roles
Bagian yang berlatar belakang kuning, adalah bagian yang memanggil diri sendiri (rekursif) dengan hak akses yang lebih tinggi. Setelah proses kompilasi selesai, kita dapat menggunakan wsdl.exe dari VS.NET 2003 command prompt untuk membuat class proxy web service yang dapat digunakan untuk memanggil UserGroupProxy.asmx.
Dari proses diatas akan diperoleh class baru UserGroupProxy yang dapat digunakan untuk memanggil web service yang baru dibuat. Edit nama file dan nama class yang diperoleh dari operasi diatas, menjadi UserGroupProxyWS.cs dan nama class menjadi UserGroupProxy. Tambahkan class yang baru tadi kedalam project dan jangan lupa masukkan ke dalam namespace yang sama dengan namespace project web service yang telah dibuat dari awal tadi.
Selanjutnya, buka remark (bagian berlatar-belakang kuning) pada class UserGroupProxy dan lakukan kompilasi ulang. Kita lihat bahwa, pada bagian yang berwarna kuning tersebut UserGroupProxy memanggil dirinya sendiri melalui class proxy web service UserGroupProxyWS. Pada saat proses eksekusi UserGroupProxyWS hak akses user yang digunakan ditingkatkan menjadi lebih tinggi dengan merubah properti Credentials dalam class tersebut. (**tentu saja informasi, user, password dan domain [****REPLACE****] harus disimpan disuatu tempat dalam bentuk terenkripsi, dan proses tersebut tidak disertakan disini**)
Pada titik ini kita sudah berhasil membuat impersonation dengan menggunakan recursive web services. Proses selanjutnya adalah mengintegrasikan web service yang sudah dibuat kedalam SharePoint.
3. Mengintegrasikan web service kedalam Sharepoint
Proses integrasi web service kedalam Sharepoint sangat mudah dan bisa dilihat dari web site Microsoft. Secara sederhana langkah-langkahnya adalah,
a. Memindahkan binary web service kedalam directory ISAPI\BIN
b. Membuat file disco/wsdl dari web service dengan menggunakan disco.exe
c. Merubah sebagian isi file *.disco dan *.wsdl agar sesuai dengan format Sharepoint.
Menambahkan referensi mengenai web service baru tersebut kedalam file spdisco.aspx.
Hasilnya adalah web service yang sudah siap dijalankan dengan teknik virtualisasi di Sharepoint.
Pengetesan
Untuk mencoba apakah teknik yang dilakukan berhasil, kita dapat membuat script sederhana dengan menggunakan visual basic. Pada bagian pertama, dapat kita lihat bahwa akses ke method “GetRoleCollectionFromUser” gagal karena adanya pembatasan hak akses.
Tanpa harus merubah syntax yang digunakan, dan cukup dengan merubah alamat web service menjadi web service rekursif, maka script dibawah ini dapat dijalankan dengan sukses. Sehingga, semua user akhirnya dapat mengetahui role apa saja yang dimilikinya.
--o0o–[](http://cakriwut.files.wordpress.com/2006/08/usergroupproxyready.gif)
English: (baca dalam Bahasa Indonesia)
In the first part we have already prepared web services project in Sharepoint. Now, we are going to put some code into our project to execute process done by “GetRoleCollectionFromUser” from UserGroup.asmx web services.
2. Adding Code and Recursive Web Service
- Remove Services1.asmx from the project and add new web service UserGroupProxy.asmx
- Examine the code, and add following code (bold) so we will have exactly same schema with original web service.
[WebService(Namespace=”http://schemas.microsoft.com/sharepoint/soap/directory/”,
Description=“Web service to proxy original webservice.”
)]
public class UserGroupProxy : System.Web.Services.WebService
{_**private SPWeb currentWeb;
private string serviceUrl;
**public UserGroupProxy()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
try
{
currentWeb = SPControl.GetContextWeb(Context);
serviceUrl = currentWeb.Url + “/_vti_bin/UserGroupProxy.asmx”;
}
catch{}
}
_}**[WebMethod(Description=“Generate document number, based on current pattern”)]
public System.Xml.XmlNode GetRoleCollectionFromUser(string userLoginName)
{
System.Xml.XmlNode resultXml;
try
{
****UserGroup userGroup = new UserGroup();
userGroup.Url = currentWeb.Url + “/_vti_bin/UserGroup.asm”;
resultXml = userGroup.GetRoleCollectionFromUser(userLoginName);
}
catch
{
**/********************************************
UserGroupProxyWS userGroup = new UserGroupProxyWS();
userGroup.Url = serviceUrl;
userGroup.Credentials = new System.Net.NetworkCredential(****REPLACE******);
****resultXml = userGroup.GetRoleCollectionFromUser(userLoginName);
__********************************************/
}**__return resultXml;
}
}
The red coloured background, _UserGroup userGroup = new UserGroup();_, is calling the original web service (UserGroup.asmx) in purpose to make our coding job faster (we don’t need to construct XML response anymore, don’t we?). It is a process to search user roles, which normally can be coded as
SPUser currentUser = this.currentWeb.CurrentUser
SPRoleCollection roles = currentUser.Roles
The yellow coloured background, is a recursive part which self execute using higher credentials. After compiling the project, we can use wsdl.exe from VS.NET 2003 command prompt; to create proxy class to call UserGroupProxy.asmx.
From that process we will have new class UserGroupProxy to execute the new web service. Change file and classname to UserGroupProxyWS.cs and UserGroupProxy for the class. Add the new class (and file) into the project and don’t forget to edit the namespace; so the new class is collected in the same namespace with the earlier class in the project.
Next, un-remarked (yellow background) in UserGroupProxy class and rebuild the project. Examine that in the yellow part, UserGroupProxy execute itself recursively through proxy class web service UserGroupProxyWS. When the application executes UserGroupProxyWS it raised user credentials by specifiying new credential in Credentials property from that UserGroupProxyWS. (**of course user, password and domain information [****REPLACE****] must be kept in encrypted form in somewhere, its your responsibility to decide config or register**)
Now we already have new impersonation using recursive web services techniques. The next task is to integrate our web service into Sharepoint.
3. Integrating web service into Sharepoint
Integrating web service into Sharepoint is easy task and documented in SDK. You can also go to Microsoft site to see it in detail. Here I’ll give you brief steps to integrate it,
a. Copy new binary to ISAPI\BIN directory
b. Create new disco/wsdl file from our web services using disco.exe
c. Edit *.disco and *.wsdl file to comply with Sharepoint processing factory.
Add new reference about the new service in spdisco.aspx.
And, voila our new web service now in Sharepoint - and ready for virtualization.
Testing
To check whether this technique successfully resolve the problem, we can create new vbs script.
The first script fails to execute “GetRoleCollectionFromUser” , and returning an error because of access limitation.
The second script, we modify the web service URL and no other code modification, and the method executes sucessfully. Now, any users have access to “GetRolesCollectionFromUser” method to see any roles he/she might have.
--o0o–