Skip to content

Using the FedAuth Cookie

Aymeric edited this page May 5, 2021 · 4 revisions

What is FedAuth Cookie?

By using this cookie, the Sharepoint will recognize the user.

How to find the FedAuth Cookie

In my company, we have a Sharepoint 2019 OnPremise that uses Azure AD for authentication.

I'm a site collection admin for my Sharepoint website, without any farm/server access. Let's say the URL to Sharepoint is https://aymeric.sp.my-company.com

After multiple tries with traditional authentication solutions, I came to the conclusion that I'd have to figure out a new way to connect to my environment with Node JS.

I first used Chrome dev toolbar to track the steps that my browser does when the authentication is required by Sharepoint. Based on it, I've replicated the behavior with Node and using HTTP Toolkit.

Here are the different steps to authenticate…

  1. First when we try to access to Sharepoint, it returns an error 403 Unauthorized:

GET https://aymeric.sp.my-company.com/SitePages/Home.aspx

  1. We then go to the /_trust/ section, which will return a status code 302 (redirection):

GET https://aymeric.sp.my-company.com/_trust/default.aspx?trust=AureAD&ReturnUrl%2f_layouts%2f15%2fAuthenticate.aspx%3fSource%3d%2fhttps%253A%252F%252Faymeric.sp.my-company.com%252FSitePages%252FHome.aspx

  1. We are redirected to MicrosoftOnline Login page with the TENANT-ID and some parameters; using the HTML code we get some values from JavaScript and post them:

GET https://login.microsoftonline.com/TENANT-ID/wsfed?wa=wsignin1.0&wtrealm=urn%3aSharepoint%3afederation&wctx=https%3a%2f%2faymeric.sp.my-company.com%2f_layouts%2f15%2fAuthenticate.aspx%3fSource%3d%2fhttps%253A%252F%252Faymeric.sp.my-company.com%252FSitePages%252FHome.aspx&wreply=https%3a%2f%2faymeric.sp.my-company.com%2f_trust%2fdefault.aspx

  1. We post the values to GetCredentialType which returns a JSON string that contains a page under FederationRedirectUrL that needs to be called:

POST https://login.microsoftonline.com/common/GetCredentialType?mkt=en-US

  1. The federation URL will return a 302 redirection:

GET https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/prp.wsf?some_params

  1. The redirected page will return an www-authenticate header with Negociate:

GET https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/resume/idp/prp.ping

  1. It appears we use Kerboros, so using node-expose-sspi we can authenticate to the same page using the correct header – the page will return a form with username and password fields:

GET https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/resume/idp/prp.ping

  1. We post the form from previous response, with correct fields to the provided location:

POST https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/resume/idp/prp.ping

  1. The previous page contained another form that we post:

POST https://login.microsoftonline.com/login.srf

  1. One additional form to post:

POST https://aymeric.sp.my-company.com/_trust/default.aspx

And finally, the last page returns the FedAuth cookie and the response's headers!

Note: during all these steps, it's necessary to get/pass all the cookies provided by each page – without them it will fail.

JavaScript code

I wrote a script that handles all these steps. You'll need to install some npm packages:

npm install cheerio extend node-expose-sspi node-fetch

You also need a JSON file that will contain your credentials:

{
  "username":"aymeric",
  "password":"My@SuPeR§P33swOrD",
  "email":"[email protected]"
}

And the file fedauth.js that will do all the hard work for us!

How to use it with SharepointPlus

Starting from SharepointPlus v6.1.0, there is an additional option in method $SP().auth(). Below is how to use everything together:

const $SP = require('sharepointplus/dist/');
const credentials = require('./credentials.json');
const fedAuth = require('./fedauth.js');
const uri = "https://aymeric.sp.my-company.com";

async function run() {
  try {
    // we use `{method:'cookie'}` and provide the `FedAuth=cookie`
    const sp = $SP().auth({method:'cookie'}, async () => {
      let cookie = await fedAuth({uri:uri, credentials:credentials, debug:true});
      return cookie;
    });

    let data = await sp.list('Temp', uri).get({
      fields:'Title',
      json:true
    });
    console.log(data);
  } catch(err) {
    console.log("[ERROR] ",err);
  }
}

run();