Permissions for Project Online to access via REST api

New Contributor

Hi. I'm having a lot of trouble trying to access Project Online data through the REST interface. 

 

I understand Oauth2 and I'm successfully getting an authorization token using a client id and secret that I obtained via the https://<<tenant>>.sharepoint.com/sites/pwa/_layouts/15/appregnew.aspx page. 

 

I can use the bearer token to do a GET on https://<<tenant>>.sharepoint.com/sites/pwa/_api/web/lists without a problem. However when I try to access https://<<tenant>>.sharepoint.com/sites/pwa/_api/ProjectData/Projects I get an authorization error, code 20010, "Access Denied".

 

The user I'm logging in with is the company administrator, and has also been added as a site admin for the Project site explicitly by name. Also when I'm logged in as that user, I can navigate to the above link and get the data inside the browser. That's using login cookies I guess, not oauth.

 

It seems obvious that I've not added the correct permissions, but I've given every permission I can find to my user through the admin website, not only to the project site but to the root site. 

 

I'm pretty stumped, I'd be grateful for a trailhead.

 

Thanks,

Rod

5 Replies

@rodfrey  Did you ever solve this?

Guess not, I haven't found an answer for this after lots of hours searching and trying.. any help?

@dlafer Yes, we solved it after weeks of trying. We did this...

 

                ProjectContext myProjectContext = _projectOnlineUtils.GetProjectContext
                    (_configuration["ProjectOnline:SiteUrl"],
                    _configuration["AzureAd:ClientId"],
                    _configuration["ProjectOnline:PJOAccount"],
                    _configuration["ProjectOnline:PJOPassword"],
                    _configuration["AzureAd:TenantId"],
                    _configuration["ProjectOnline:Scope"]);

                ProjectCollection projects = myProjectContext.Projects;
                myProjectContext.Load(projects);
                await myProjectContext.ExecuteQueryAsync();

 and this

 public ProjectContext GetProjectContext(string siteUrl, string clientId, string userName, string password, string tenantId, string scope)
 {
     try
     {
         PublicClientApplicationBuilder pcaConfig = PublicClientApplicationBuilder.Create(clientId)
             .WithTenantId(tenantId);

         string redirectUri = "http://localhost";
         pcaConfig.WithRedirectUri(redirectUri);
         SecureString sc = new();
         foreach (char c in password) sc.AppendChar(c);

         AuthenticationResult tokenResult = pcaConfig.Build()
             .AcquireTokenByUsernamePassword
                 (new[] {scope},
                 userName,
                 sc)
             .ExecuteAsync()
             .Result;

         ProjectContext projectContext = new(siteUrl);
         projectContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs) { webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + tokenResult.AccessToken; };
         return projectContext;
     }
     catch (Exception e)
     {
         _logger.LogError($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: Error - {e.Message}");
         return null;
     }
 }

 

It need a bit of a clean, but it works.

Thanks!
Any idea if there is a parallel version for python? I tried office365 library but it didn't work.
That code should port straight over to python.