Pages

Friday, 20 September 2013


  1. RunWithElevatedPrivileges?
  2. Why can’t we use RunWithElevatedPrivileges in event handlers?
  3. Impersonation Improvements in SharePoint 2010 Event Receivers?
  4. Best recommended practice use of it?
  5. Best recommended practice to use of it in Event Receivers?
  6. Best recommended practice to use of it in Feature Receivers?
  7. RunWithElevatedPrivileges in visual studio workflows:
  8. Is RunWithElevatedPrivileges allowed in sandbox solution?
  9. By using which credentials the RunWithElevatedPrivileges will run?
  10. Difference between SPSecurity.CodeToRunElevated and SPSecurity. RunWithElevatedPrivileges?


Impersonation:
Impersonation is the process of executing code in the context (or on behalf) of another user identity.
What are the Impersonation methods in SharePoint 2010?
  • RunWithElevatedPrivileges to impersonate as System Account user
  • Passing User Token inside SPSite to impersonate as particular user
  • Using Windows API
SPUserToken:
The SPSite object takes an SPUserToken object in its constructor in order to support impersonation.To impersonate the system, use the SystemAccount.UserToken property of the current SPSite context, such as:
var site = new SPSite(SPContext.Current.Site.ID, SPContext.Current.Site.SystemAccount.UserToken);

Difference between RunWithElevatedPrivileges Vs SPUserToken:
  • RunWithElevatedPrivileges to impersonate as System Account user
  • Passing User Token inside SPSite to impersonate as particular user
RunWithElevatedPrivileges?
As per the msdn: Executes the specified method with Full Control rights even if the user does not otherwise have Full Control. 

Whenever we use SPSecurity.RunWithElevatedPrivileges (), it will execute the code under the context of Application Pool identity, so you must ensure that the App Pool account is a member of a site collection group with sufficient perms to add/edit/delete or whatever your code is trying to do. If not, the code will quietly break without popping an exception.

Method: Microsoft.SharePoint. SPSecurity.RunWithElevatedPrivileges

The code will not run within the elevated privilege if the object accessed was not created within the SPSecurity.RunWithElevatedPrivileges block. The main reason for doing so is to ensure that all the objects are in the context of the App Pool's identity.


SPSecurity.RunWithElevatedPrieveleges, there are too much tricks that you should take care of.
For Instance: You must create the new SPSite objects inside the delegate because SPSite objects created outside do not have Full Control even when referenced inside the delegate.

RunWithElevatedPrivileges does not work when HTTPContext is null:
RunWithElevatedPrivileges don’t work when HTTPContext (SPContext to be more specific) is null. So, you will not have elevation of privilege when using RunWithElevatedPrivileges in Console Application, Workflow, Timer Job or Event handlers not initiated by a request in browser.

What is the need of defining SPSite, SPWeb objects especially in RunWithElevatedPrivileges block? 
If you use instances of SPSite or SPWeb, obtained prior to the RunWithElevatedPrivileges block, it won't work as expected because they are already associated to a non-elevated security context[ means current logger user] 

Why can’t we use SPContext.Current.Web inside RunWithElevatedPrivileges:
SPContext.Current.Web can not be used directly with in the RunWithElevatedPrivileges block as the SPWeb object becomes a instance of current logged-in user's context and it gives the below error if tries to update any content in the same Web with READ only access.
Error : Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
To address the issue, a new instance of SPSite and SPWeb should be cerated within the RunWithElevatedPrivileges code block as above. 

Impersonation Improvements in SharePoint 2010 Event Receivers?
Instead of using RunWithElevatedPrivileges, In SharePoint 2010, there are new properties namely OriginatingUserToken, UserDisplayName and UserLoginName which help the developers to revert back to the original user who triggered the event very easily. 

I will update once get the clear idea on what use of the new properties OriginatingUserToken, UserDisplayName and UserLoginName introduced in SharePoint 2010.

RunWithElevatedPrivileges in visual studio workflows:
No need to use any elevated privileges when working with workflows because it runs under SharePoint System Account by default (the App Pool account).

Is RunWithElevatedPrivileges allowed in sandbox solution?
You cannot use SPSecurity.RunWithElevatedPrivileges method in case of Sandboxed solution. The main reason is Sandbox solutions execute in User Code service with limited privileges.

Best recommended practice use of it:
Can’t use SPContext inside the code being RunWithElevatedPrivileges. We may get “access denied” error if instead write the SPWeb site = SPContext.Current.Web inside the RunWithElevatedPrivileges, because your web was created in the context of the current user.

Best recommended practice is: Take the current context outside the SPSecurity.RunWithElevatedPrivileges block and then create a new instance of SPSite and SPWeb inside the block which will run under application pool identity.

Simply to say is: The objects you’re working with need to be recreated within your RunWithElevatedPrivileges code block.
  

Recommended practice #1: 
  1. private void Test()  
  2. {  
  3.     Guid webID = SPContext.Current.Web.ID;  
  4.     Guid siteID = SPContext.Current.Site.ID;  
  5.     SPSecurity.RunWithElevatedPrivileges(delegate()  
  6.     {  
  7.         using (SPSite site = new SPSite(siteID))  
  8.         {  
  9.             using (SPWeb web = site.OpenWeb(webID))  
  10.             {  
  11.                 // Code Using the SPWeb Object goes here  
  12.             }  
  13.         }  
  14.     });  
  15. }  
Best recommended practice #2: 
  1. private void Test()  
  2.         {  
  3.             SPSite site = SPContext.Current.Site;  
  4.             SPWeb web = SPContext.Current.Web;  
  5.   
  6.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  7.             {  
  8.                 using (SPSite CurrentSite = new SPSite(site.ID))  
  9.                 {  
  10.                     using (SPWeb CurrentWeb = CurrentSite.OpenWeb(web.ID))  
  11.                     {  
  12.                         // Code Using the SPWeb Object goes here  
  13.                     }  
  14.                 }  
  15.             });  
  16.         }  
RunWithElevatedPrivileges” in Feature Receivers: 
  1. [Guid("b321499d-9b43-410e-8a8f-779ffb81d738")]  
  2.     public class Feature1EventReceiver : SPFeatureReceiver  
  3.     {  
  4.         public override void FeatureActivated(SPFeatureReceiverProperties properties)  
  5.         {  
  6.             try  
  7.             {  
  8.                 using (SPSite spSite = properties.Feature.Parent as SPSite)  
  9.                 {  
  10.                     using (SPWeb spWeb = spSite.OpenWeb())  
  11.                     {  
  12.                         SPSecurity.RunWithElevatedPrivileges(delegate()  
  13.                         {  
  14.                             //code here  
  15.                         });  
  16.                     }  
  17.                 }  
  18.             }  
  19.             catch (Exception ex)  
  20.             {  
  21.             }  
  22.         }  
“RunWithElevatedPrivileges” in Event Receivers: Better to use the ID properties of the properties object, to get new instances of SPSite, SPWeb and SPListItem. If you need to run actions with elevated privileges on SPSite and SPWeb object use new SPSite(properties.SiteId); and site.OpenWeb(properties.RelativeWebUrl) instead of properties.web and web.site;
Best Recommended Practice #1 
  1. namespace MyCustomDlgFramework.EventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class EventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.            SPSecurity.RunWithElevatedPrivileges(delegate()  
  14.            {  
  15.                using (SPSite site = new SPSite(properties.SiteId))  
  16.                {  
  17.                    using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))  
  18.                    {  
  19.                        //code here  
  20.                    }  
  21.                }  
  22.            });  
  23.              
  24.        }  
  25.   
  26.     }  
  27. }  
Best recommended practice #2: 
  1. namespace MyCustomDlgFramework.MyEventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class MyEventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.             using (SPSite site = new SPSite(properties.WebUrl))  
  14.            {  
  15.                using (SPWeb web = site.OpenWeb())  
  16.                {  
  17.                    SPSecurity.RunWithElevatedPrivileges(delegate()  
  18.                    {    
  19.                        //Code here  
  20.                    });  
  21.                }  
  22.         }  
  23.     }  
  24.   }  
  25. }  
Best recommended practice #3: 
  1. namespace MyCustomDlgFramework.EventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class EventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.            SPSecurity.RunWithElevatedPrivileges(delegate()  
  14.            {  
  15.                using (SPWeb web = properties.OpenWeb())  
  16.                {  
  17.                    //Code here  
  18.                }  
  19.   
  20.            });  
  21.        }  
  22.   
  23.     }  
  24. }  
Chances of getting “Access Dined” error:

Note: Elevation of privilege occurs only if new SPSite created inside the block : 

  1. private void Test()  
  2.         {  
  3.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.             {  
  5.                 SPWeb currentWeb = SPContext.Current.Web;  
  6.                 SPList spList = currentWeb.Lists["MyList"];  
  7.             });  
  8.         }  
  1. private void Test()  
  2. {  
  3.     SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.     {  
  5.         using (SPSite currentSite = new SPSite(SPContext.Current.Site.Url))  
  6.         {  
  7.             using (SPWeb currentWeb = currentSite.OpenWeb())  
  8.             {  
  9.                 // Access granted as System account!!   
  10.             }  
  11.         }  
  12.     });  
  13. }  
  1. private void Test()  
  2.         {  
  3.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.             {  
  5.                 SPSite site = SPContext.Current.Site;  
  6.                 SPWeb web = SPContext.Current.Web;  
  7.                 web.AllowUnsafeUpdates = true;  
  8.   
  9.                 SPList list = web.Lists["MyList"];  
  10.                 SPListItem item = list.GetItemById(1);  
  11.                 item["MyField"] = "SharePoint";  
  12.                 item.Update();  
  13.   
  14.                 web.AllowUnsafeUpdates = false;  
  15.             });  
  16.         }  


Reason: SPContext.Current.Site and SPContext.Current.Web runs the List Item update code in the context of the currently logged in user and not in the context of the App Pool identity.

Friday, 13 September 2013

Difference Between Classic based Claim based and Form based authentication.

Classic Based Authentication
§  You cannot configure the Forms based authentication if your web application is using Classic Mode Authentication.You can convert a web application from Classic Mode Authentication to Claims Based Authentication. However, that can only be done using PowerShell commands and its an irreversible process.
§  Classic authentication supports authentication types like Kerberos, NTLM,  anonymous.
§  Classic is more commonly seen in 2007 environments.
Claim Based Authentication
§  It enables authentication from windows as well as non-windows based systems. This also provides the capability to have multiple authentication in a single URL.
§  Claims based authentication uses claims identities against a against a trusted identity provider.
§  Claims are the recommended path for new deployments in SharePoint 2010.
Form Based Authentication
§  Forms-based authentication is used when we use Claim based authentication. Forms-based authentication is used to implement customized logic for authenticating users without having to worry about session management using cookie.

§  It gives developer more access to specify which files on the site can be accessed and by whom, and allows identification of a login page.

Monday, 2 September 2013

SharePoint 2013 App with Workflow is not working.

I have installed workflow manager and verified that I am able to run the sharepoint 2013 workflow from sharepoint designer.
I am also able to deploy and run sharepoint hosted app. Now I have added a new item workflow in sharepoint hosted app , it contains write to history. after deploying I noticed my workflow is not working as history list does not contain any data.
Please come up with the solutions.       

Monday, 26 August 2013

How to move Add new item link to top location in SharePoint 2010

Add new item link to top:

Recently my client request to me for moving “Add new Item” link to top location instead of bottom of every web part. Actually for adding new item user first click on tab (in ribbon bar) and then click on New Item button. Which is taking time and not a very good practice.
Secondly, if there are many items are saved in list or library then user have to scroll down and then click on Add new item link. That is also tedious.
Solution:
We will use jQuery for moving Add new item link from bottom to top location, for this we generically add the following script in master page. It will move all the Add new item links to top of each web part at run time in browser.
<script src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js“ type=”text/javascript”></script>
<script language=”javascript” type=“text/javascript”>
$(document).ready(function () {
$(“td.ms-addnew“).parent().parent().parent().each(function () {
$(this).insertBefore($(this).prev());
});
});
</script>
You can also add this script to CEWP on page and the result will be same but on specified page.

Wednesday, 14 August 2013

Export To PDF in sharepoint 2010/C#

Export To PDF in sharepoint 2010/C#

I had an requirement to export some data to PDF format in Sharepoint application pages.

First You have to download and attach a DLL from ItextSharp.dll .(Can be downloaded from Here).Add it into  your webpart or solution  or for application pages.

For application pages and for inline coding add following  lines


<%@ Register TagPrefix="itext" Namespace="iTextSharp.text" Assembly="itextsharp, Version=5.3.0.0, Culture=neutral, PublicKeyToken=8354ae6d2174ddca" %>
<%@ Import Namespace="iTextSharp.text.pdf" %>
<%@ Import Namespace="iTextSharp.text.html.simpleparser" %>


For coding purpose add following lines


using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;


Then add the following  code to export to PDF


private DataTable  SearchItem()
    {
        DataTable dt = new DataTable();
        SPSecurity.RunWithElevatedPrivileges(delegate
        {
            SPList list = SPContext.Current.Web.Lists["TestList"];
         
       
            string query = null;
            SPQuery qry = new SPQuery(list.DefaultView);
            //SPListItemCollection lstColl =
            int iCnt = 0;
            try
            {

                qry.ViewFields = "<FieldRef Name='LinkTitleNoMenu' /><FieldRef Name='TestColumn' />";
                    qry.Query = query;
                 
                dt= list.GetItems(qry).GetDataTable();
                 

                 
                }

            catch (Exception ex) { Response.Write(ex.Message); }
        });
        return dt;
    }
    protected void btnExport_click(object sender, EventArgs e)
    {
        DataTable dt1 = SearchItem();
     

        //Get the data from database into datatable

        GridView GridView1 = new GridView();
        GridView1.AllowPaging = false;
        GridView1.DataSource = dt1;
        GridView1.DataBind();


        Response.ContentType = "application/pdf";
        Response.AddHeader("content-disposition",
          "attachment;filename=DataTable.pdf");
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        StringWriter sw = new StringWriter();
        HtmlTextWriter hw = new HtmlTextWriter(sw);

        GridView1.RenderControl(hw);
        StringReader sr = new StringReader(sw.ToString());
        Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
        HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
        PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
        pdfDoc.Open();
        htmlparser.Parse(sr);
        pdfDoc.Close();
        Response.Write(pdfDoc);
        Response.End();
    }
 

  public override void VerifyRenderingInServerForm(Control control)
    {
    }


If you observe above code I added one function that is VerifyRenderingInServerForm this function is used to avoid the error like “control must be placed in inside of form tag”. If we setVerifyRenderingInServerForm function then compiler will think that controls rendered before exporting and our functionality will work perfectly.



After the button Click the PDf file will ask you to save or open the File.After that you can't do any post back options in that page.for doing such you have to add a little bit of code into that page within a script block.
Add the following code to that particular page



   <script type="text/javascript">

            _spOriginalFormAction = document.forms[0].action;

            _spSuppressFormOnSubmitWrapper = true;

</script>

If you are getting any dll error, try this

Adding DLL to WSP SharePoint 2010

In order to add custom dll to WSP Package , follow these steps:

  • Create new Empty SharePoint Project 
    • File->New->Project->SharePoint(2010)->Empty SharePoint Project 
    • In second screen provide test site URL
    • Select "Deploy as Farm Solution"

  • Expand package node and double click on Package.package file 




  • Click on "Advanced" Tab



  • Add the Custom dll's using the "Add" button



  • Save the project, compile and deploy. Custom dll will be part of WSP.

Happy Coding  :)

Tuesday, 13 August 2013

Download wsp from central admin sharepoint

 We can do this with the PowerShell scripting. 

 Following are the PowerShell script code to take the backup and restore it is local folder with .wsp externsion. 
?
$farm = Get-SpFarm
$file = $farm.Solutions.Item("Test.wsp").SolutionFile
$file.SaveAs("c:\Temp\Test.wsp")

Thursday, 4 July 2013

an error occurred querying a data source . infopath 2010

An error occurred querying a data source.
Click OK to resume filling out the form. You may want to check your form data for errors.


A query to retrieve form data cannot be completed because this action would violate cross-domain restrictions.

If this form template is published to a SharePoint document library, cross-domain access for user form templates must be enabled under InfoPath Forms Services in SharePoint Central Administration, and the data connection settings must be stored in a UDC file in a data connection library in the same site collection.

If this is an administrator-approved form template, the security level of the form must be set to full trust, or the data connection settings must be stored in a UDC file by using the Manage data connection files option under InfoPath Forms Services in SharePoint Central Administration.

An entry has been added to the Windows event log of the server.
Log ID:6932

Correlation ID:aebda88d-e0ec-4bd2-a0ed-6d98bd8e3810




Error occured querying a data source.Is there any solution to solve this..? Pls get me back..