pnp / PnP-PowerShell

SharePoint PnP PowerShell CmdLets
https://pnp.github.io/powershell
Other
987 stars 662 forks source link

Connect-PnPOnline giving 403 Forbidden when trying to connect to a site collection with multiple authentication enabled #808

Open abelunibo opened 7 years ago

abelunibo commented 7 years ago

Reporting an Issue or Missing Feature

Executing something like (against a site with multiple authentication methods enabled): Connect-PnPOnline -Url http://somesite.com.local will give you something like:

Connect-PnPOnline : The remote server returned an error: (403) Forbidden.

This is actually a known issue, and I think this is a valid solution.

To overcome this I came up with the following script:

### GetPnPClientContext - returns a PnP client context from a web site with multiple authentication configured

Function HandleMixedModeWebApplication()
{
    param([Parameter(Mandatory=$true)][object]$clientContext)  
    Add-Type -TypeDefinition @"
    using System;
    using Microsoft.SharePoint.Client;

    namespace Toth.SPOHelpers
    {
        public static class ClientContextHelper
        {
            public static void AddRequestHandler(ClientContext context)
            {
                context.ExecutingWebRequest += new EventHandler<WebRequestEventArgs>(RequestHandler);
            }

            private static void RequestHandler(object sender, WebRequestEventArgs e)
            {
                //Add the header that tells SharePoint to use Windows authentication.
                e.WebRequestExecutor.RequestHeaders.Remove("X-FORMS_BASED_AUTH_ACCEPTED");
                e.WebRequestExecutor.RequestHeaders.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
            }
        }
    }
"@ -ReferencedAssemblies "C:\Users\myself\AppData\Local\Apps\SharePointPnPPowerShell2013\Modules\SharePointPnPPowerShell2013\Microsoft.SharePoint.Client.dll", 
                         "C:\Users\myself\AppData\Local\Apps\SharePointPnPPowerShell2013\Modules\SharePointPnPPowerShell2013\Microsoft.SharePoint.Client.Runtime.dll";

    [Toth.SPOHelpers.ClientContextHelper]::AddRequestHandler($clientContext);
}

Function GetPnPClientContextFromMultiAuthSite($credentials, $url)
{

    if($credentials -eq $null){
        Write-Host "Input your credentials:"
        $credentials = Get-Credential
    }

    if($url -eq $null)
    {
        $url = Read-Host "Enter the URL of the site collection"    
    }

    Add-Type -Path "C:\Users\myself\AppData\Local\Apps\SharePointPnPPowerShell2013\Modules\SharePointPnPPowerShell2013\Microsoft.SharePoint.Client.dll"
    Add-Type -Path "C:\Users\myself\AppData\Local\Apps\SharePointPnPPowerShell2013\Modules\SharePointPnPPowerShell2013\Microsoft.SharePoint.Client.Runtime.dll"

    $clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url);
    $clientContext.Credentials = $credentials.GetNetworkCredential();
    $clientContext.AuthenticationMode = [Microsoft.SharePoint.Client.ClientAuthenticationMode]::Default

    # Mixed-mode web app handling
    HandleMixedModeWebApplication $clientContext;

    if (!$clientContext.ServerObjectIsNull.Value)
    {
        Write-Host "Connected to site collection..."

        $web = $clientContext.Web
        $clientContext.Load($web)
        $clientContext.ExecuteQuery()

        Write-Host "The site Title is" $web.Title
    }
    else
    {
        Write-Host "Could not create a client context. Check your site url or internet connection."
    }

    $clientContext.FormDigestHandlingEnabled 

    return  [OfficeDevPnP.Core.PnPClientContext]::ConvertFrom($clientContext)
}

$ctx = GetPnPClientContextFromMultiAuthSite

Set-PnPContext  $ctx

However this gives the following error:

Set-PnPContext : Object reference not set to an instance of an object.

Expected behavior

I think that there should be a way to include some extra info in the header of the http request created by the Connect-PnPOnline command, or a switch argument that inserts "X-FORMS_BASED_AUTH_ACCEPTED : f" in the header as necessary for the connections to site collections with multiple authentication enabled (see above link)

Actual behavior

Currently PnP won't allow you to connect to onpremises multi auth enabled site collections

Which version of the PnP-PowerShell Cmdlets are you using?

What is the version of the Cmdlet module you are running?

2.13.1703.0

How did you install the PnP-PowerShell Cmdlets?

iainwyatt commented 6 years ago

Hi

I am trying to connect likewise to a SharePoint 2013 web application with multiple authentication. I was able to use the script provided to demonstrate that CSOM can talk to the site. Connecting with the connect-pnponline cmdlet gives me a 403 error.

Did you manage to progress this any further?

Thanks,

Iain

garrytrinder commented 6 years ago

@iainwyatt @abelunibo I've just come across this same issue, any luck in finding a solution?

Setting -AuthenticationMode does not seem to have an effect on the connection either.

I guess the only option here is to extend the web application and use a different URL rather than mixed authentication on a single web application.

iainwyatt commented 6 years ago

Hi, for me I was fortunate enough to discover that there is an alternate access mapping in place on the web application with only windows authentication enabled which connects without issue - looks like it has been put there to support reporting services. It looks like a solution to accessing via a mixed mode url is technically possible, but I think it's beyond my skills and available time to look into it further.

sgovaerts commented 6 years ago

@garrytrinder @iainwyatt I've downloaded the source and built the DLL again (otherwise it has a problem with the strong name in the dll reference). And then referenced the OfficeDevPnP.Core in the SharePoint.PowerShell.Commands and then modified the SPOnlineConnectionHelper.cs.

Added this:

private static void Context_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
    e.WebRequestExecutor.RequestHeaders.Remove("X-FORMS_BASED_AUTH_ACCEPTED");
    e.WebRequestExecutor.RequestHeaders.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
}

And then in the 2nd InstantiateSPOnlineConnection call:

context.ExecutingWebRequest += Context_ExecutingWebRequest;

Then I replaced the OfficeDevPnP.Core.dll and SharePointPnP.PowerShell.2013.Commands.dll in the module folder, for me it was C:\Users\%username%\AppData\Local\Apps\SharePointPnPPowerShell2013\Modules\SharePointPnPPowerShell2013 and now it authenticates without the 403, even when switching between mixed mode and only ntlm.

CombineLabs commented 5 years ago

I was able to use the PowerShell CSOM example and modify it to use the tenant library. Thanks! My team wants to use PnP on prem so I hope there is a fix in the not too distant future. Thanks for the CSOM workaround!

CombineLabs commented 4 years ago

Has anyone tested this recently? Still bugged?