SharePoint is a platform used for business collaboration where Individuals can manage their own collaborative websites and share information across the globe. Over the last few years or a decade, SharePoint servers have had a great impact on business processes. It is mainly used for file sharing, content searching, and blog sharing. This list keeps on increasing with new SharePoint servers coming into the market.
As a SharePoint 2013 user and C sharp developer, one might need to monitor services or service applications present in SharePoint 2013 using C# applications through a system user.
The issue arises when the user needs to access these services and service applications through a system user. A system user does not have direct access over the SharePoint Farm and services. So, the issue arises when the service application is run by a system user and he needs access over SharePoint farm/services.
There are many solutions to the problem. But the best one is to impersonate the system user as another user who has all the access on SharePoint Farm (an administrator user most of the time) and is a part of the Administrators’ Group in the farm. It is quite common in C# applications if we need to run some code under the session of another user.
There are many inbuilt Windows security functions present to implement impersonation in C# applications.
This can be explained by the following flow diagram:
Figure 1: Flow Diagram of a Code Snippet
Below is a brief introduction about the steps to be followed:
- Login into the local system using the particular user details (this is the user having access to SharePoint Farm).
- Once the login is successful, the access token must be updated with the required privileges.
- These security tokens provide the security context of the impersonated user and play a very important role. These can be updated according to the application requirements to provide security to sensitive production environments.
- After the access tokens are assigned security privileges, the next step is to create a session of the impersonated user. In this step, the APIs create a virtual space of the impersonated user where the actual program/process runs, and disposes off the impersonated user session once done with the execution.
- Create a particular .exe/process under the context of the user impersonated in the previous steps. This process runs using the impersonated user. All the execution is done in this process.
Have a look at API examples for more understanding:
- Call “LogonUser” function which will check if the username and password provided is valid or not. Try to create a session token through the credentials provided.
Where ‘LogonType’ is the type of operation the user wants to perform on the machine,
‘LogonProvider’ denotes the logon provider.
This API returns a memory reference to the user's security token, which is passed to the WindowsIndentity constructor in the impersonation process.
If returnValue is returned “true”, it means that the credentials you provided are valid and can be impersonated, otherwise it is quite possible that credentials are invalid or that the session is not created with the given user.
- Create a duplicate security token from the existing security token returned by ‘LogonUser’ API. The Win32 API ‘DuplicateTokenX’ is used to convert an impersonation token to a primary token. Now what is an impersonation token and a primary token?
A primary token provides the security context of the user associated with a process. This is the default token used by the system. An impersonation token describes the security context of the client that needs to be impersonated.
As the token used to impersonate the WindowsIdentity constructor should be an impersonation token, that is why this API should be called after the primary token is accessible.
Where ‘hExistingToken’ is the token returned by ‘LogonUser’ API,
‘dwDesiredAccess’ is the access rights requested for the new impersonation token,
‘lpThreadAttributes’ denotes the security attributes (can specify if child processes of the impersonated process can inherit the token or not),
‘ImpersonationLevel’ specifies impersonation level of a new token,
‘dwTokenType’ is the token type that specifies whether it should be a primary token or an impersonation token,
‘phNewToken’ is nothing but a handle pointer for a new token.
If this function/API succeeds then it returns a non-zero value, otherwise zero is returned.
- Create an interface used to run the process under an impersonated session. It needs to be disposed off once we are done. You can create the space with the “using” construct, which will automatically dispose the interface at the end.
The sample code written here is run under the new WindowsIdentity that has been created. The Impersonate() function impersonates the user specified in the WindowsIdentity object.
- Call ‘CreateProcessAsUser’ API that will create a particular exe/process under context of the user impersonated in the previous steps.
Where ‘hToken’ is the primary token,
‘lpApplicationName’ is the name of the application,
‘lpCommandLine’ is the command-line to be executed,
‘lpProcessAttributes’ denotes the security attributes for a new process object,
‘lpThreadAttributes’ denotes the security attributes for a new thread object,
‘bInheritHandles’ specifies whether handles can be inherited by a new process or not,
’dwCreationFlags’ are the flags that define the priority classes and creation of process,
’lpEnvironment’ is a pointer to the environment block,
‘lpCurrentDirectory’ is the current directory of the process,
‘lpStartupInfo’ specifies the start-up options for the process, and
‘lpProcessInformation’ is the whole information about the new process created.
If the function succeeds, then it returns a non-zero value, otherwise zero is returned.
The new process created in the operations above will run under the security context of the client, even if the calling application runs under the system user.
In the same way, the above approach can execute any of the process or application under the impersonated user context.
Enjoy the power of Impersonation!!