impersonate as different user inside the webpart code - sharepoint

I use the sharepoint lists as a database.
I want to somehow impersonate as different user inside the webpart code
and than as this user I will have both write and edit permission to the list.
My goal is to be able to have full premission only through the webpart code.
I am using MOSS 2007.

SPSecurity.RunWithElevatedPrivilieges() will execute your code as the system account, i.e. the account under which the application pool runs, which might or might not be what you want to do. For example, if you have a workflow attached to the list which is supposed to trigger when new items are added to the list, it will not fire if you insert a new list item under the credentials of the system account (this was a security fix introduced in SharePoint 2007 SP 1). In that case you will have to perform the insert operation under a different account that has the correct permissions on the list.
You can get the UserToken for any user using the following code:
SPUserToken userToken = null;
SPSecurity.RunWithElevatedPrivileges(() =>
{
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
{
userToken = web.AllUsers["domain\\username"].UserToken;
}
}
});
Replace the "domain\username" with the correct windows account name. Then you can pass this user token to one of the overloads of the SPSite object constructor to execute the code under this user's credentials like so:
using (SPSite site = new SPSite(SPContext.Current.Site.ID, userToken))
{
using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
{
// This code will execute under the credentials of the userToken user
}
}
Hope this helps.

You are looking for SPSecurity.RunWithElevatedPrivileges Method.

Related

Possible to Submit Sharepoint 2013 Form Data to 365 List Online?

Using data connection in SharePoint 2013, or any other method, is it possible to submit form data with each form completion to an external landing place, like a list in SharePoint 365 online? I am new to SharePoint and am needing to learn the ropes pretty quick! Thanks for any help you can provide.
Have a great 2020!
You could develop a custom WebPart or Add-in for SP 2013 and in c# code of this project You could, using SPOnline CSOM, add items to SP Online.
The main problem is the authentication model You are using in SP-OnPrem and SP-online (OF365 tenant). If You have the same kind of authorization provider (for example in both places You are using adfs) then there should not be much of a problem to (as the same user account) submit some data from OnPrem to Online with some Add-in or Webpart as the user will be authenticated in both places. Otherwise You can submit some data from OnPrem to Online with CSOM but You will need to login (in code.. like hardcoded) as some user. This is not the best option from security point of view.
Here is an example how to login to SP Online using CSOM (You could do something very similar in the webpart or Add-in).
... so this are only ideas but generally to do this kind of logic first You need to figure out how You authenticate between OnPrem and Online. If You authenticate the 'same way' You could just create the context of SPOnline and then add/delete or update items with the user permissions. Otherwise You need to authenticate to SPOnline as some user to submit data.
If you use the OOTB list form, we can create an event receivers and use CSOM C# code to add new item to SharePoint Online list. The following code for your reference.
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Security;
using Microsoft.SharePoint.Client;
namespace SharePointProjectER.CustomListER
{
/// <summary>
/// List Item Events
/// </summary>
public class CustomListER : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
if (properties.List.Title == "CL0106")
{
//add item to SharePoint Online list
string siteUrl = "https://tenant.sharepoint.com/sites/team";
string userName = "admin#tenant.onmicrosoft.com";
string password = "xxx";
var securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
var credential = new SharePointOnlineCredentials(userName, securePassword);
ClientContext clientContext = new ClientContext(siteUrl);
clientContext.Credentials = credential;
List oList = clientContext.Web.Lists.GetByTitle("CL0106");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = oList.AddItem(itemCreateInfo);
oListItem["Title"] = properties.ListItem["Title"];
oListItem.Update();
clientContext.ExecuteQuery();
}
}
}
}
Or we can create a custom web part with custom form or add-in as Adam's reply, and use the CSOM C# code to achieve it.
Reference: Complete basic operations using SharePoint client library code

Authorization problem with SharePoint ClientContext created with ADAL Access Token

I am trying to automatize the provision of a SharePoint Online Site Collection. I am doing it with SharePoint CSOM. If I create the ClientContext(Microsoft.SharePoint.Client) object
with SharePointOnlineCredentials, everthing works fine such as creating sub sites/list/libraries, upload custom master pages, setting web properties etc. (By the way we are using Publishing Site)
ClientContext ctx = new ClientContext(contextWebUrl);
SecureString sec_pass = new SecureString();
Array.ForEach(contextPassword.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();
ctx.Credentials = new SharePointOnlineCredentials(contextUserName, sec_pass);
return ctx;
But i don't have user's password on production environment because we have to use ADAL authentication and we have only Access Token. So i have to create ClientContext object by using this token. Like;
ClientContext ctx = new ClientContext(siteUrl);
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e)
{
e.WebRequestExecutor.WebRequest.Headers.Add("Authorization", "Bearer " + siteToken.AccessToken);
if (digestValue != null)
{
e.WebRequestExecutor.WebRequest.Headers.Add("X-RequestDigest", digestValue.FormDigestValue);
e.WebRequestExecutor.WebRequest.Accept = "application/json;odata=verbose";
}
};
return ctx;
by this way getting something from SharePoint works but if i try to _set_ something such as create a subsite or deploy a master page to catalogs library i am getting 401 as below.
Access denied. You do not have permission to perform this action or access this resource
I thought that it was an update issue but even though i have used X-RequestDigest nothing changed.
Some people have encountered same issue when uploading documents but all answers are about using rest api directly and this cant solve my issue.
The token which is being used in second method is related to application client Id.
So Azure application needs necessary permission as similar as user's. In Azure Portal/Azure Active Directory, i gave AllSites.FullControl permission to the application which i use to signin and get access token.
Hereby this problem has been resolved.

Why I don't need to authenticate the user before i can execute query in CSOM example

I am going thru the examples here which shows how to perform basic operations with the SharePoint 2013 .NET Framework client object model (CSOM).
https://msdn.microsoft.com/en-us/library/office/fp179912.aspx
My question is why I don't need to authenticate the user before i can execute query in CSOM
For example
// Starting with ClientContext, the constructor requires a URL to the
// server running SharePoint.
ClientContext context = new ClientContext("http://SiteUrl");
// The SharePoint web at the URL.
Web web = context.Web;
// We want to retrieve the web's properties.
context.Load(web);
// Execute the query to the server.
context.ExecuteQuery();
// Now, the web's properties are available and we could display
// web properties, such as title.
label1.Text = web.Title;
You dont need to do this cause it will use the current logged in user. Otherwise you have to impersonate the user first.
ClientContext context = new ClientContext("http://server/");
context.Credentials = new NetworkCredential("user", "password", "domain");
// Some Cording
context.ExecuteQuery();

Cannot access site groups with user with manage hierarchy permissions

I have a custom form that lists the site groups and the users in each group.
the form has twi drop down lists: one to display the site's group and the other to display the users in that group.
when I log to the form with the administrator user it works fine.
But if I log in with a user with manage hierarchy permission level, it omly displays the info of the domain groups and if I try to access a sharepoint group I get an access denied error.
I use run with elevated permissions in my code
I really don't know what to do in this
thanks.
Two common mistakes when using RunWithElevatedPrivileges is:
Using the SPContext.Current.Web (or Site etc) won't change the identity of the web object, it is already in memory.
Declaring the SPWeb outside the delegate, with similar results of mistake 1
That said, try something like:
Guid siteId = SPContext.Current.Site.Id;
SPSecurity.RunWithElevatedPrivileges(() =>
using (SPSite elevatedSite = new SPSite(siteId))
using (SPWeb elevatedWeb = elevatedSite.RootWeb)
{
//impl
});

SharePoint WebPart Permissions

Hi I am using the SharePoint namespace for a webpart and I encounter some permission errors when I try to use the System account. Is there a way I can use a defined user instead of the system account?
Right now I have:
SPUserToken sysToken = SPContext.Current.Site.SystemAccount.UserToken;
using (SPSite site = new SPSite(_SPSite, sysToken))
I want to be able to use an account on the domain instead of the System account, thanks for any advice.
You may need to use RunWithElevatedPermissions to get access to the System account to work, as per the following blog post:
http://solutionizing.net/2009/01/06/elegant-spsite-elevation/
You can use the SPUserCollection
SPContext.Current.Site.RootWeb.AllUsers
to get all of the users on the site, and get the SPUser from there. Once you have the SPUser you can get the UserToken.
What are you trying to do? If you don't use a token, the web will be opened with the same permissions as the current user
/* runs as user requesting the web part */
SPSite site = SPContext.Current.Web.site
or you can wrap it in the RunWithElevatedPrivileges delegate
/* runs with admin privileges */
SPSecurity.RunWithElevatedPrivileges(
delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Web.Site.Url))
{
//do stuff
}
}
);

Resources