-
-
Notifications
You must be signed in to change notification settings - Fork 58
Using the FedAuth Cookie
By using this cookie, the Sharepoint will recognize the user.
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…
- First when we try to access to Sharepoint, it returns an error 403 Unauthorized:
- We then go to the
/_trust/
section, which will return a status code 302 (redirection):
- 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:
- We post the values to
GetCredentialType
which returns a JSON string that contains a page underFederationRedirectUrL
that needs to be called:
POST https://login.microsoftonline.com/common/GetCredentialType?mkt=en-US
- The federation URL will return a 302 redirection:
GET https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/prp.wsf?some_params
- The redirected page will return an
www-authenticate
header withNegociate
:
GET https://pf.my-company.com/idp/RANDOM-UNIQUE-ID/resume/idp/prp.ping
- 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
- 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
- The previous page contained another form that we post:
- One additional form to post:
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.
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!
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();