Question

I'm having a little problem with creating a list item with the "created by" user being the correct one. The scenario I have is I've deployed a Provider-Host app via Visual Studio (while logged in as user1) and all is working well. However, if I log into the computer as a different user (user2) and then create a new list item through the app the "created by" user is set to user1? Note: I am using the Rest API for this... I have pasted my code below:

public void AddDocumentToLibrary(string documentName, string libraryName, string data, string sharePointUrl)
    {
        string newFormDigest = GetFormDigest(sharePointUrl);

        string digestRequest = sharePointUrl + "/_api/web/GetFolderByServerRelativeUrl('/" + libraryName + "')/Files/add(url='" + documentName + "', overwrite=true)";

        HttpWebRequest spNewRequest = (HttpWebRequest)HttpWebRequest.Create(digestRequest);
        CredentialCache credNewCache = new CredentialCache();
        credNewCache.Add(new Uri(digestRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);
        spNewRequest.Credentials = credNewCache;
        spNewRequest.Method = "POST";
        spNewRequest.Accept = "application/json;odata=verbose";
        spNewRequest.ContentType = "application/json;odata=verbose";
        spNewRequest.Headers.Add("X-RequestDigest", newFormDigest);

        // For Content Length
        byte[] postByte = Encoding.UTF8.GetBytes(data);
        spNewRequest.ContentLength = postByte.Length;
        Stream postStreamBody = spNewRequest.GetRequestStream();
        postStreamBody.Write(postByte, 0, postByte.Length);
        postStreamBody.Close();

        HttpWebResponse webResponse = (HttpWebResponse)spNewRequest.GetResponse();
        GetHTTPResponse(webResponse);
    }

    private string GetContextInformation(string sharePointUrl)
    {
        // 1st request to get the context information
        string formdigestRequest = sharePointUrl + "/_api/contextinfo";
        HttpWebRequest spRequest = (HttpWebRequest)HttpWebRequest.Create(formdigestRequest);
        CredentialCache credNewCache = new CredentialCache();
        credNewCache.Add(new Uri(formdigestRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);
        spRequest.Credentials = credNewCache;
        spRequest.Method = "POST";
        spRequest.Accept = "application/json;odata=verbose";
        spRequest.ContentLength = 0;
        HttpWebResponse endpointResponse = (HttpWebResponse)spRequest.GetResponse();
        string contextInformation = GetHTTPResponse(endpointResponse);

        return contextInformation;
    }

    private string GetFormDigest(string sharePointUrl)
    {
        string contextInformation = GetContextInformation(sharePointUrl);

        // Get the FormDigest Value
        var startTag = "FormDigestValue";
        var endTag = "LibraryVersion";
        var startTagIndex = contextInformation.IndexOf(startTag) + 1;
        var endTagIndex = contextInformation.IndexOf(endTag, startTagIndex);
        string newFormDigest = null;
        if ((startTagIndex >= 0) && (endTagIndex > startTagIndex))
        {
            newFormDigest = contextInformation.Substring(startTagIndex + startTag.Length + 2, endTagIndex - startTagIndex - startTag.Length - 5);
        }

        return newFormDigest;
    }

    private string GetHTTPResponse(HttpWebResponse endpointResponse)
    {
        Stream postStream = endpointResponse.GetResponseStream();
        StreamReader postReader = new StreamReader(postStream);

        string results = postReader.ReadToEnd();

        return results;
    }

Any insight to this will be great. If I've been a bit vague I can try and explain this a bit more too.

Thanks in advance, David

Was it helpful?

Solution

I've worked it out. From some reason, what the code above seems to do is it will use the user account of whoever installed the app in the first place... At least that what it seems like it's doing for me.

I've altered the code slight so I'm passing in the "UserAccessTokenForSPHost" value that you can get from the SharePointContext [SharePointContextProvider.Current.GetSharePointContext(HttpContext)], this will retrieve the user access token of the currently logged in user.

We can then use this token while creating our request object to communicate with SharePoint as the logged in user. Mainly, I updated the AddDocumentToLibrary function from

public void AddDocumentToLibrary(string documentName, string libraryName, string data, string sharePointUrl)
{
    string newFormDigest = GetFormDigest(sharePointUrl);

    string digestRequest = sharePointUrl + "/_api/web/GetFolderByServerRelativeUrl('/" + libraryName + "')/Files/add(url='" + documentName + "', overwrite=true)";

    HttpWebRequest spNewRequest = (HttpWebRequest)HttpWebRequest.Create(digestRequest);
    CredentialCache credNewCache = new CredentialCache();
    credNewCache.Add(new Uri(digestRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);
    spNewRequest.Credentials = credNewCache;
    spNewRequest.Method = "POST";
    spNewRequest.Accept = "application/json;odata=verbose";
    spNewRequest.ContentType = "application/json;odata=verbose";
    spNewRequest.Headers.Add("X-RequestDigest", newFormDigest);

    // For Content Length
    byte[] postByte = Encoding.UTF8.GetBytes(data);
    spNewRequest.ContentLength = postByte.Length;
    Stream postStreamBody = spNewRequest.GetRequestStream();
    postStreamBody.Write(postByte, 0, postByte.Length);
    postStreamBody.Close();

    HttpWebResponse webResponse = (HttpWebResponse)spNewRequest.GetResponse();
    GetHTTPResponse(webResponse);
}

to be:

public void AddDocumentToLibrary(string documentName, string libraryName, string data, string sharePointUrl, string userAccessToken)
{
    string newFormDigest = GetFormDigest(sharePointUrl);

    string digestRequest = sharePointUrl + "/_api/web/GetFolderByServerRelativeUrl('/" + libraryName + "')/Files/add(url='" + documentName + "', overwrite=true)";

    HttpWebRequest spNewRequest = (HttpWebRequest)HttpWebRequest.Create(digestRequest);
    spNewRequest.Headers.Add("Authorization", "Bearer " + userAccessToken);            
    spNewRequest.Method = "POST";
    spNewRequest.Accept = "application/json;odata=verbose";
    spNewRequest.ContentType = "application/json;odata=verbose";
    spNewRequest.Headers.Add("X-RequestDigest", newFormDigest);

    // For Content Length
    byte[] postByte = Encoding.UTF8.GetBytes(data);
    spNewRequest.ContentLength = postByte.Length;
    Stream postStreamBody = spNewRequest.GetRequestStream();
    postStreamBody.Write(postByte, 0, postByte.Length);
    postStreamBody.Close();

    HttpWebResponse webResponse = (HttpWebResponse)spNewRequest.GetResponse();
    GetHTTPResponse(webResponse);
}

Thank heavens this works now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top