Sharepoint Rest API Permissions to create a Site

Radu Nour 20 Reputation points
2023-04-28T09:00:02.8466667+00:00

Hello,

I'm trying to create a Sharepoint (Modern Site) using Rest Api with an access token, however I get in the end the 401 Unauthorized error. I have granted the Azure Enterprise App all the Sharepoint API permissions, however still nothing (at the same time with the same access token I can run Graph API commands and I get response). Can anybody advise what else should I do be able to use Sharepoint API?

User's image

Thanks in advance!

Import-Module MSAL.PS

#Variables
$ClientID = "XXX"
$ClientSecret = "XXX"
$ClientCertificate = Get-Item "Cert:\CurrentUser\My\XXX"
$tenantID = "XXX"
$scope = "https://XXX.sharepoint.com/.default"
$authority = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token"

$Body = @{
  "grant_type"    = "client_credentials";
  "client_id"     = "$ClientID";
  "tenant_id" = "$tenantID";
  "ClientCertificate" = "$ClientCertificate";
  "scope"      = "$scope";
}

#Get AccessToken
#$result = Invoke-RestMethod -Method POST -uri $authority -Body $body
#$AccessToken = $result.access_token

#Get AccessToken with MSAL
$AccessToken = Get-MsalToken -ClientId $ClientID -TenantId $tenantID -ClientCertificate $ClientCertificate -Scope $scope
# Inspect the Access Token using JWTDetails PowerShell Module
$AccessToken.AccessToken | Get-JWTDetails

#Create Event
$headers = @{
# "Authorization" = "Bearer "+ $AccessToken;
# "Authorization" = $AccessToken.CreateAuthorizationHeader();
# "Authorization" = "Bearer "+ $AccessToken.CreateAuthorizationHeader();
 "Authorization" = "Bearer $($AccessToken.access_token)"
 "Accept" = "application/json;odata.metadata=none"
}

#Create JSON Object
$json = @"
{
    "Title": "Communication Site 1",
    "Url":"https://XXX.sharepoint.com/sites/commsite1",
    "Lcid": 1033,
    "ShareByEmailEnabled":false,
    "Classification":"Low Business Impact",
    "SensitivityLabel": "None",
    "Description":"Description",
    "WebTemplate":"SITEPAGEPUBLISHING#0",
    "SiteDesignId":"6142d2a0-63a5-4ba0-aede-d9fefca2c767",
    "Owner":"******@XXX.com",
    "WebTemplateExtensionId":"00000000-0000-0000-0000-000000000000"
}
"@

$uri = "https://XXX.sharepoint.com/_api/SPSiteManager/create"
Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $json 

The remote server returned an error: (401) Unauthorized. Same with the command below

$uri = "https://XXX.sharepoint.com/_api/SPSiteManager/status?url='https%3A%2F%2F<tenantXXX>.sharepoint.com%2Fsites%2FAcademy'"
Invoke-RestMethod -Method GET -Uri $uri -Headers $headers
Microsoft 365 and Office SharePoint For business Windows
Microsoft Security Microsoft Graph
0 comments No comments
{count} votes

Accepted answer
  1. RaytheonXie_MSFT 40,471 Reputation points Microsoft External Staff
    2023-05-03T01:22:15.12+00:00

    Hi @Radu Nour

    I'm glad to hear you solve the problem ,if you have any issue about SharePoint, you are welcome to raise a ticket in this forum.

    By the way, since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others." and according to the scenario introduced here: Answering your own questions on Microsoft Q&A, I would make a brief summary of this thread:

    [Sharepoint Rest API Permissions to create a Site]

    Issue Symptom:

    Get 401 Unauthorized error when create a Sharepoint site using Rest Api with access token

    Solution:

    The error caused by missing request headers and wrong json format, fixed by following powershell script

    Import-Module MSAL.PS
    
    #Variables
    $ClientID = "XXX"
    $ClientSecret = "XXX"
    $ClientCertificate = Get-Item "Cert:\CurrentUser\My\XXX"
    $tenantID = "XXX"
    $scope = "https://XXX.sharepoint.com/.default"
    $authority = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token"
    
    $Body = @{
      "grant_type"    = "client_credentials";
      "client_id"     = "$ClientID";
      "client_secret" = "$ClientSecret";
      "scope"      = "$scope";
    }
    
    #Get AccessToken
    #$result = Invoke-RestMethod -Method POST -uri $authority -Body $body
    #$AccessToken = $result.access_token
    
    #Get AccessToken with MSAL
    $AccessToken = Get-MsalToken -ClientId $ClientID -TenantId $tenantID -ClientCertificate $ClientCertificate -Scope $scope
    # Inspect the Access Token using JWTDetails PowerShell Module
    $AccessToken.AccessToken | Get-JWTDetails
    
    #Create Event
    $headers = @{
    # "Authorization" = "Bearer "+ $AccessToken;
    # "Authorization" = $AccessToken.CreateAuthorizationHeader();
    # "Authorization" = "Bearer "+ $AccessToken.CreateAuthorizationHeader();
     "Authorization" = "Bearer $($AccessToken.AccessToken)";
     "Accept" = "application/json;odata.metadata=none";
     "Content-Type" = "application/json;odata=verbose";
     "odata-version" = "4.0"
    }
    
    #Create JSON Object
    $json = @"
    {
      "request": {
        "Title": "Communication Site 1",
        "Url":"https://XXX.sharepoint.com/sites/commsite1",
        "Lcid": 1033,
        "ShareByEmailEnabled":false,
        "Classification":"Low Business Impact",
        "Description":"Description",
        "WebTemplate":"SITEPAGEPUBLISHING#0",
        "SiteDesignId":"6142d2a0-63a5-4ba0-aede-d9fefca2c767",
        "Owner":"******@XXX.com",
        "WebTemplateExtensionId":"00000000-0000-0000-0000-000000000000"
      }
    }
    "@
    
    $uri = "https://XXX.sharepoint.com/_api/SPSiteManager/create"
    Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $json
    

    You could click the "Accept Answer" button for this summary to close this thread, and this can make it easier for other community member's to see the useful information when reading this thread. Thanks for your understanding!

    2 people found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. RaytheonXie_MSFT 40,471 Reputation points Microsoft External Staff
    2023-05-01T02:50:17.93+00:00

    Hi @Radu Nour

    Granting access via Azure AD App-Only covers how to register an app with app-only permissions in Azure AD and how to use that app to interact with SharePoint using PnP PowerShell and the SharePoint PnP Sites Core library. Unfortunately, this resource doesn't cover how to use the app with the "plain" REST API. The basic steps to do this would be to use the Microsoft Authentication Library (MSAL) library to get an access token and then make REST API calls with that token included in the headers of the request.

    One important thing to note, you cannot use Client ID and Client Secret for authentication when authenticating with the REST API or CSOM using an app registered in Azure AD. You have to use Client ID and a certificate. How to register the app to use Client ID and a certificate is shown in the article I linked.

    Here is a nice article similar with your requirement, please make a reference

    Testing client certificate authentication to Azure API Management with Postman

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.