Forum Discussion

rodfrey's avatar
rodfrey
Copper Contributor
May 29, 2019

Permissions for Project Online to access via REST api

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

    • dlafer's avatar
      dlafer
      Copper Contributor
      Guess not, I haven't found an answer for this after lots of hours searching and trying.. any help?
      • Hepster's avatar
        Hepster
        Copper Contributor

        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.

Resources