We have our PHP application that requires authentication, and for our clients that run SharePoint we'd like to offer some kind of SSO service, so that the users can use their SharePoint credentials (we did something similar with Google Apps, CAS, ...)
Note: Obviously, our app is not hosted on the same domain/premices as SharePoint
I can't find the litterature about it, so any pointer would be welcome !
NB: we'd like to implement a proper tier authentification mechanism, so that the user can log into our app directly by typing the URL, and choose to login using SharePoint, exactly like you'd do with OAuth and the like...
Thanks in advance !
SharePoint Online (SPO) supports claims based authentication.
The below picture demonstrates how authentication is performed in SPO:
According to this post the authentication process consists of the following steps:
Steps:
Send SAML Request to STS
Receive SAML Response
Send the Security Token to SharePoint Online
Receive the authentication cookies
Send requests including authentication cookies
phpSPO - SharePoint client for PHP supports SPO authentication.
The library provides a SharePoint Online (SPO) client for PHP
applications. It allows you to performs CRUD operations on SharePoint
data using an SharePoint 2013 REST/OData based API.
Examples
How to perform authentication in SharePoint Online (SPO):
try {
$client = new SPOClient($url);
$client->signIn($username,$password);
echo 'You have authenticated successfully\n';
}
catch (Exception $e) {
echo 'Authentication failed: ', $e->getMessage(), "\n";
}
The following examples demonstrates how to perform CRUD operations on SharePoint list data:
<?php
require_once 'SPOClient.php';
$username = 'username#tenant.onmicrosoft.com';
$password = 'password';
$url = "https://tenant.sharepoint.com/";
$client = new SPOClient($url);
$client->signIn($username,$password);
//Get Tasks list
$listTitle = 'Tasks';
$list = $client->getList($listTitle);
//Create a Task item
$itemProperties = array('Title' => 'Order Approval', 'Body' => 'Order approval task');
$taskItem = $list->addItem($itemProperties);
print "Task '{$taskItem->Title}' has been created succesfully.\r\n";
$itemId = $taskItem->Id;
//Update a Task item
$itemProperties = array('PercentComplete' => 1);
$list->updateItem($itemId,$itemProperties);
//Delete a Task item
$list->deleteItem($itemId);
?>
References
SharePoint Online client for PHP
Not sure if you still need help on this - Sharepoint is usually set to sync up with Active directory (AD/LDAP). So really if you have users that use sharepoint AND are being internally authenticated in their company via their Active directory login, then what you may want to look at is authenticating your app against LDAP (and use the email address or domain id as the username)
Here is some more info on that:
Authenticating in PHP using LDAP through Active Directory
Related
I can't get the Locations list from my business under my code (PHP using the "Google APIs Client Library for PHP" together with "Google_Service_MyBusiness" Classes) when I use the "Service Account" authentication, the API returns an empty Location List.
I already have the Prerequisites and did the Basic setup, by the way, I got the information with success on OAuth Playground, under a specific AccountId, Eg: 1111111111, provided by another response there on the "OAuth Playground".
(PS: I tested with my "PERSONAL" and "LOCATION_GROUP" accounts and got success with both).
But when I try to do it over my code via Server Account authentication, I can't get all the information, just the Account data that return another AccoundId, Eg: 2222222222, different of the Accounts that I got on OAuth Playground.
I did the Authentication process on OAuth Playground, using the same project where I created the "Service Account", by the way, the Permission of this "Service Account" is OWNER.
Previously, my role in my company on the Google My Business was "SITE_MANAGER", so I saw a forum answer where just "MANAGER" level/role can list the Locations, so I requested to change my permission, but continues as not the success on Locations listing.
So, I saw another Google My Business support article recommending create a "Location Group" and put my current "Location" into this group to make easy handle it, I did it and no success again.
My code is simple, based on Google guide, OAuth 2.0 for Server to Server Applications, and some Forum Questions (BTW the author's question have the same issue than me):
<?php
putenv('GOOGLE_APPLICATION_CREDENTIALS=service-account-credentials.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope("https://www.googleapis.com/auth/plus.business.manage");
require_once('Google_Service_MyBusiness.php');
$mybusinessService = new Google_Service_MyBusiness($client);
$accounts = $mybusinessService->accounts;
$accountsList = $accounts->listAccounts()->getAccounts();
foreach ($accountsList as $accKey => $account) {
var_dump('$account->name', $account->name);
$locations = $mybusinessService->accounts_locations;
$locationsList = $locations->listAccountsLocations($account->name)->getLocations();
var_dump('$locationsList', $locationsList);
// Final Goal of my Code
if (empty($locationsList)===false) {
foreach ($locationsList as $locKey => $location) {
$reviews = $mybusinessService->accounts_locations_reviews;
$listReviewsResponse = $reviews->listAccountsLocationsReviews($location->name);
$reviewsList = $listReviewsResponse->getReviews();
var_dump('$reviewsList', $reviewsList);
}
}
}
I expected the Location of my business (also the reviews, but it a next step), but I just got the empty Location list.
Finally, I got success using the ClientId/ClientSecret keys together with Refresh Token previously received on Google OAuth 2 Playground on the first time that I give permission to (my) App, instead "Service Account" authentication way :)
$client = new Google_Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->addScope("https://www.googleapis.com/auth/plus.business.manage");
$client->setSubject('my email user on GMB');
$client->refreshToken(' ###### ')
Now I got all the needed data for my application.
I am quite new to wordpress and OAuth. I have two sites. One hosted on the web,and the second one hosted on my local machine. I want to use OAuth in order to login to my local machine site if i am logged in to the other site.
What i managed to do:
I had installed WP OAuth Server on web hosted site and created new client;
On my local machine i wrote the following code using https://github.com/adoy/PHP-OAuth2;
require('vendor/autoload.php');
const CLIENT_ID = 'my client id';
const CLIENT_SECRET = 'my client secret';
const REDIRECT_URI = '';
const AUTHORIZATION_ENDPOINT = '';
const TOKEN_ENDPOINT = '';
$client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);
if (!isset($_GET['code']))
{
$auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI);
header('Location: ' . $auth_url);
die('Redirect');
}
else
{
$params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
$response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params);
$response = (object) $response;
$result = (object) $response->result;
//echo json_encode($result->access_token);
echo "<pre>";
print_r($response);
}
When i run this script i got the following response:
stdClass Object
(
[result] => Array
(
[access_token] => rhfnpz6ifgnjufoq0rby0utphtzpxhrmsytnjh5z
[expires_in] => 86400
[token_type] => Bearer
[scope] => basic
[refresh_token] => lgrklt5kwiv29ch3nmdhhieedjbudg8liv48l6c7
)
[code] => 200
[content_type] => application/json
)
How can i use this access token in order to login to my local hosted site? What i am missing? Thank you!
After you have a response with the access_token you can log the user in without having to accept and process the normal WP email+password flow. Do this by
session the access_token and refresh_token (for future calls to the API Resource endpoint, if any)
call wp_set_auth_cookie() to create a WP session for the user.
You'll want to include in your code a hook for the WP logout where you'll clear the tokens from the session.
OAuth2 Server
Your web-hosted WordPress website needs an OAuth2 server plugin. This is our premium product: https://lana.codes/product/lana-passport/
The OAuth2 server plugin provides the authentication server that is connected to the WordPress user system. It also provides the /authorize, /token and /resource endpoints, to which the client can connect and generate a token, and then use the token to access user data.
Basically, the Authorization Code grant type should be used for this purpose, because it also provides the WordPress login interface if you are not logged in and need to identify yourself. This is the most user-friendly and most popular grant type.
OAuth2 Client
And your local machine-hosted WordPress website needs an OAuth2 client. This is our free product: https://wordpress.org/plugins/lana-sso/
This creates a Single Sign On button for the WordPress login interface, which is connected to the configured OAuth2 server.
How does it work:
If the client went through the authentication process and received the access_token, it requests the user data from the OAuth server at the /resource endpoint.
If the user can be found on the client website based on the user data, the user is logged in using the wp_set_current_user() and wp_set_auth_cookie() functions. If the user is not found and registration is enabled, a new user is created using the wp_insert_user() function on the client website and logged in.
If you want to know more about the OAuth2 process, we have a case study that specifically discusses the single sign on solution for two WordPress websites: https://lana.codes/case-study/oauth2-server-and-client-wordpress-plugin/
I need to access CRM odata REST API for Integration. I have a php cron job for syncing data from CRM. When I hit the endpoint of CRM WEB API https://internal.crm.org.com:5443/appname/api/data/v8.0/ from browser I redirect to the following link :
https://adfs.crm.org.com/adfs/ls/?wa=wsignin1.0&wtrealm=https://internal.crm.org.com:5443/&wctx=rm=1&id=4d65271b-682e-44bb-80ce-ed44b5370ed7&ru=%2forgTechnicalTraining%2fdefault.aspx&wct=2016-11-02T07:15:47Z&wauth=urn:federation:authentication:windows
and a window is shown to authenticate using username, and password.
So my question is how to authenticate with the resources server?
Microsoft point me to this page
https://msdn.microsoft.com/library/mt622431.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
and this guy explain how to authenticate using oauth2
http://www.powerobjects.com/2016/01/22/start-your-engines-getting-started-with-the-crm-2016-web-api/#collapse2
Microsoft said dynamics 365 is using three different security models (claims, active dirctory, and auth2 authentications)
I have successfully integrated with CRM web api 2016 using the ws-trust protocol.
This lib are do the heavy work for you and implment the ws-trust protocol messages.
Steps To authenticate with CRM that is protoected by ADFS 3.0
1- Get the samel security token (the endpoint for ws-trust for active authenticate need to be configured on adfs server)
2- Include that token per http request within the header as earer token
Code:
<?php
include_once dirname(dirname(__FILE__)) . '/http.php';
include_once dirname(dirname(__FILE__)) . '/wstrust.php';
// username/password of a user in the LDAP directory
// LDAP as configured in the PingFederate Username Token WS-Trust connection settings for Salesforce
$username = 'username';
$password = 'password';
// RST appliesTo
$appliesTo = 'crmservice/api/data/v8.0/';
//STS service
$IPSTS = 'org/adfs/services/trust/13/UsernameMixed';
// special token type (needs to be enabled in run.properties)
$tokenType = WSTRUST::TOKENTYPE_SAML20;
// call to IP-STS, authenticate with uname/pwd, retrieve RSTR with generated token
//get security token
$result = HTTP::doSOAP(
$IPSTS,
WSTRUST::getRSTHeader(
WSTRUST::getUserNameToken($username, $password),
WSTRUST::getTimestampHeader(), $IPSTS),
WSTRUST::getRST($tokenType, $appliesTo)
);
// parse the RSTR that is returned
list($dom, $xpath, $token, $proofKey) = WSTRUST::parseRSTR($result);
$xpath->registerNamespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$token = $xpath->query('saml:EncryptedAssertion', $token);
$token = $token->item(0);
// now pass the encrypted assertion to the RP
$ts = WSTRUST::getTimestampHeader('_0');
$token = $dom->saveXML($token);
//include the token with the http header per request like this Authorization: Bearer $token
I am trying to read a feed from a Google Sites account (Google apps).
I don't need my app to require every user to login so i created my ClientID as a "Service Account" in the "Google API console".
I have added this Client ID and the scope (https://sites.google.com/feeds/) to the "Mange API client access" page in my google apps control panel.
I connect using the code below, all constants are defined in my code with the right values.
// api dependencies
require_once(GOOGLE_API_PATH);
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName(GOOGLE_API_NAME);
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
GOOGLE_API_EMAIL,
array(GOOGLE_API_SCOPE),
file_get_contents(GOOGLE_API_PK)
));
$client->setClientId(GOOGLE_API_CLIENTID);
// create service
$req = new Google_HttpRequest("https://sites.google.com/feeds/content/<herismydomainname.com>/intranet");
$val = $client->getIo()->authenticatedRequest($req);
// The contacts api only returns XML responses.
$response = json_encode($val->getResponseBody());
print "<pre>" . print_r(json_decode($response, true), true) . "</pre>";
The response i get is "Not authorized to access this feed "
When i try to get this feed in the OAuth2.0 playground logging in using my google apps account i get the expected response.
What am i overlooking here?
Service accounts and Google Sites can't be used together currently. Google Apps provides a consumer secret that can be used to access data across your domain as Two-Legged OAuth within OAuth 1.0a.
Check out http://support.google.com/a/bin/answer.py?hl=en&answer=162105 for how to configure your Apps account, and the sample code at https://developers.google.com/gdata/docs/auth/oauth#2LeggedOAuth.
I've been implementing an OAuth login via the Google Identity toolkit in php. I've got as far as getting an authenticated session, the userdata, id, photo etc, which seems to be working more or less ok.
However, I'd like to be able to login using methods that don't rely on redirection on the user's browser (thinking of remote APIs for an application), but bit lost on how to achieve this.
Imagine a request which is something like:
$details = new stdClass();
$details->secret = $config->secret;
$details->client_id = $config->client_id;
$details->app_name = 'my awesome oauth app';
$details->login = array();
$details->login['email'] = 'some google account email # example.com';
$details->login['password'] = '1234';
$token = $this->do_auth($details);
if($token) {
// do stuff, setup cookies, insert token in session table etc
}
I'm using CodeIgniter. Are there any libraries that can do this..? I've seen android apps doing similar things, using custom login forms, so I'm guessing it's achievable in php.
You HAVE to redirect, it's a core essential of the way OAuth works, there is no way around this. That's why there is a redirect_uri parameter.
You only have to do this once though: when the user is logging in and you are requesting an access token. After that, you simply use curl for example to request your data.