Blog Post

Project Support Blog
3 MIN READ

App + User authentication and Project Online development

Brian-Smith's avatar
Brian-Smith
Former Employee
Nov 23, 2020

With the most recent updates to the SharePoint client object model (CSOM) libraries it is now possible to authenticate to SharePoint and Project Online with the MSAL libraries rather than ADAL - and this opens up the use of .NET Standard rather than needing the .NET Framework.  This DOES NOT however mean that Project Online supports App ID only authentication.  SharePoint Online does support app only - but the additional authorisation level in Project to understand who the user is and what they can do requires app + user.  See more information here - https://docs.microsoft.com/en-us/sharepoint/dev/sp-add-ins/using-csom-for-dotnet-standard and the API permissions you can choose are shown here. Im my example I've just selecting the Project.Write which allows me to create and update a project.

 

API Permission Options for Project Online

You application would need to reference the Application (Client) ID associated with these permissions when requesting token - but would also need to pass in the credentials of a user with permissions and license to Project Online.  This could be an interactive login - or using a securely stored username and password (not recommended) or using a stored token that is refreshed periodically.  Attempting to connect by with the application ID will fail with an "unauthorized" response.

 

As an example, the following code would get the token and set for project context to make further CSOM calls: 

 

 

            string domainName = "brismith.onmicrosoft.com";
            string PJOAccount = "brismith@brismith.onmicrosoft.com";
            string scope = "https://brismith.sharepoint.com/Project.Write";
            string redirectUri = "http://localhost";
            string pwaInstanceUrl = "https://brismith.sharepoint.com/sites/pwa/";         // your pwa url
            int DEFAULTTIMEOUTSECONDS = 300;
            

            HttpClient Client = new HttpClient();
            var TenantId = ((dynamic)JsonConvert.DeserializeObject(Client.GetAsync("https://login.microsoftonline.com/" + domainName + "/v2.0/.well-known/openid-configuration")
                .Result.Content.ReadAsStringAsync().Result))
                .authorization_endpoint.ToString().Split('/')[3];

            // This client ID just has project.write
            PublicClientApplicationBuilder pcaConfig = PublicClientApplicationBuilder.Create("87edf46a-466d-4241-8afc-b9650d7fb0d7")
            .WithTenantId(TenantId);

            pcaConfig.WithRedirectUri(redirectUri);

            // This section uses the interactive flow for auth
            var TokenResult = pcaConfig.Build().AcquireTokenInteractive(new[] { scope })
                .WithPrompt(Prompt.NoPrompt)
                .WithLoginHint(PJOAccount).ExecuteAsync().Result;


            //The following section uses the username and password - this would be best pulled from Azure Key Vault or use another auth flow
            //This also requires the app registration to be set as a public client
            //SampleConfiguration config = SampleConfiguration.ReadFromJsonFile("appsettings.json");
            //string text1 = config.Text1;
            //var sc = new SecureString();
            //foreach (char c in text1) sc.AppendChar(c);

            //var TokenResult = pcaConfig.Build().AcquireTokenByUsernamePassword(new[] { scope }, PJOAccount, sc).ExecuteAsync().Result;

            // Load ps context
            csom.ProjectContext psCtx = new csom.ProjectContext(pwaInstanceUrl);
            psCtx.ExecutingWebRequest += (s, e) =>
            {
                e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + TokenResult.AccessToken;
            };

 

- using the latest MSAL (Microsoft.Identity.Client v4.22) and Microsoft.ProjectServer.Client from Microsoft.SharePointOnline.CSOM 16.1.20616.12000 at the time of writing.  These will also work with legacy auth disabled which is a setting that may break some existing custom applications.

 

To check if legacy auth is disabled you can open the SharePoint Online Management shell, connect to your admin Url and run Get-SPOTenent.  Look in the returned properties for:

 

LegacyAuthProtocolsEnabled : False

 

which in my case shows that legacy auth is disabled.

 

Hopefully we will get the sample on Github updated with this latest information.

 

 

Published Nov 23, 2020
Version 1.0

20 Comments

  • Ravi_BS it looks like you aren't passing in the right credentials - are you just getting that response in a browser without authenticating?  Best open a support case if the standard samples with the latest authentication libraries isn't working.

  • Ravi_BS's avatar
    Ravi_BS
    Copper Contributor

    Hi Brian-Smith,

     

    I am getting below error while accessing Projects Data, Please help me out.

     

    Thanks

     

  • Huddos's avatar
    Huddos
    Copper Contributor

    Hi There,

     

    The last bit of code, how can I do this in powershell. I have managed to get an access token with Powershell commands.

    csom.ProjectContext psCtx = new csom.ProjectContext(pwaInstanceUrl);
                psCtx.ExecutingWebRequest += (s, e) =>
                {
                    e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + TokenResult.AccessToken;
                };

    I now need to connect to the project context using similar code to below but use the token instead of user/password. Microsoft.SharePoint.Client.SharePointOnlineCredentials does not provide the authentication in an Azure function as it does when run from desktop?


    $ProjCtx = New-Object Microsoft.ProjectServer.Client.ProjectContext($siteURL)

    [Microsoft.SharePoint.Client.SharePointOnlineCredentials]$spocreds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName, $Cred.Password);
    $ProjCtx.Credentials = $spocreds

     

  • parthrawal's avatar
    parthrawal
    Copper Contributor

    Is above screenshot "Request API Permission" from the azure App registration section ? 

  • parthrawal's avatar
    parthrawal
    Copper Contributor

    Any idea on, how to achieve authentication in case of SSIS Package ? 

  • I've seen that Hepster but don't recall what I'd done wrong when that appeared  - possibly you haven't set the API with the public client option?

  • Hepster's avatar
    Hepster
    Copper Contributor

    Hi, I'm getting...

     

    The request body must contain the following parameter: 'client_assertion' or 'client_secret'.

     

    Any ideas?

  • No changes to CSOM Trutz_Stephani - there was a recent REST change to allow task level custom fields to be edited - but nothing new likely for CSOM.  Likewise the samples will hopefully get updated at GitHub - OfficeDev/Project-Samples: - but the 2013 documentation is still pretty much accurate.  I'll check with the product group - as it would be useful to at least update the document with this new .NET Standard capability.

    Best regards,

    Brian

  • Hi Brian-Smith,

    Do you know if there has been also new API functionality added to Project CSOM, e.g. set a baseline?

    Will there be an updated API documentation in the future? The current one is still for Project Server 2013.