SimplesamlPHP infinite redirection - php

I'd setup simplesamlphp to my localhost as a 3 different virtual host.
1. http://idp-saml.com
2. http://sp-saml.com
3. http://api-saml.com
When I tried to connect idp-saml.com using sp-saml.com then it works fine.
Now, I want to integrate it with my own application api-saml.com.
For that, I'd follow the below steps:
Create "authsouce" to sp-saml.com on 'authsources.php'.
'sp1' => array(
'saml:SP',
'privatekey' => 'sp-saml.pem',
'certificate' => 'sp-saml.crt',
'entityID' => 'http://api-saml.com',
'idp' => 'http://idp-saml.com',
)
Now, go to the Federation page and click on "SP1" metadata and copy SAML 2.0 Metadata XML
Then go to idp-saml.com and open metadata-converter.php and parse SAML 2.0 Metadata XML.
Copy both shib13-sp-remote and saml20-sp-remote to metadata\shib13-sp-remote.php and metadata\saml20-sp-remote.php on idp-saml.com virtual host and I can see api-saml.com under federation tab under SAML 2.0 SP Metadata (Trusted) section.
https://www.screencast.com/t/424rmDxRlRfV
Now, Go to api-saml.com directory and create index.php and add below code
require_once('sp-saml/lib/_autoload.php');
$saml_auth = new SimpleSAML_Auth_Simple('sp1');
if ($saml_auth->isAuthenticated()) {
$attributes = $saml_auth->getAttributes();
var_dump($attributes);
}
else {
$saml_auth->requireAuth();
}
Now, tried to access http://api-saml.com and it goes to idp-saml.com and ask me for login credentials. After adding credentials it does not redirect back me to api-saml.com and behave like infinite redirection. You can see https://www.screencast.com/t/VGhDHE1j

You app and the authsource SP metadata should be on the same domain. Your steps 1 and 2 should download the metadata from http://api-saml.com/simplesaml/... rather than from a domain that is distinct from your app.
The SP metadata contains information on authorized Assertion Consumer Service (ACS) urls - and the metadata you are generating and then loading into the IdP only lists paths under http://sp-saml.com as a legitimate return urls. When you attempt to use the authsource from a different domain then the IdP see an unauthorized return url, ignores it and instead uses the one from the metadata which isn't want you want.

Related

Service Account Domain Delegation unauthorized_client

I am trying to use service account with domain delegation so I can automate some tasks of google classroom via cron. For this I need service account with domain delegation.
I am working and struggling in it for 3 days. I have properly read documentation so many times. You can imagine the 3 days research. Now I am getting exhaust and finally come here in the hope.
I am using php library provided by google for google classroom.
https://github.com/googleapis/google-api-php-client
I am getting this error
Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.
Which means in google documentation enter image description here
I tried that several times but still getting this errror.
Here is my php code
require_once plugin_dir_path(__FILE__).'../../xf-google-classroom/vendor/autoload.php';
$this->scopes = [
Google_Service_Classroom::CLASSROOM_COURSES,
//Google_Service_Classroom::CLASSROOM_ROSTERS,
//Google_Service_Classroom::CLASSROOM_COURSES_READONLY,
//Google_Service_Classroom::CLASSROOM_COURSEWORK_ME,
//Google_Service_Classroom::CLASSROOM_COURSEWORK_ME_READONLY,
//Google_Service_Classroom::CLASSROOM_COURSEWORK_STUDENTS,
Google_Service_Classroom::CLASSROOM_COURSEWORK_STUDENTS_READONLY,
//Google_Service_Classroom::CLASSROOM_PROFILE_EMAILS,
];
$this->credentials = plugin_dir_path(__FILE__) . '/sufi-new-2.json';
//$this->redirect_uri = site_url( 'wp-admin/admin.php?page=bp-groups' );
$this->client = new Google_Client();
//$this->client->useApplicationDefaultCredentials();
$jsonKey = [
"type"=> "service_account",
"project_id"=> "edufix-upgraded",
"client_email"=> "newsufyan#edufix-upgraded.iam.gserviceaccount.com",
"client_id"=> "115746479435703189142",
"auth_uri"=> "https://accounts.google.com/o/oauth2/auth",
"token_uri"=> "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url"=> "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url"=> "https://www.googleapis.com/robot/v1/metadata/x509/newsufyan%40edufix-upgraded.iam.gserviceaccount.com"
];
$this->client->setAuthConfig( $jsonKey );
$this->client->setSubject('clases#krugerschool.edu.ec');
//$this->client->setRedirectUri( $this->redirect_uri );
$this->client->addScope( $this->scopes );
$this->client->setAccessType( 'offline' );
Let me tell you that my OAuth2 authentication with conscent screen application is working good on frontend for users. I am not able to run my cron scripts because of this domain delegation.
Also my OAuth Consent screen is in test mode and I have added test users in it. And working good with users on frontend with consent screen.
Also I always generate new key after any new changes and deploy that new credentials as well everytime. I tried to remove and add again with client id and proper scopes and domain delegation again and again but not working.
Also I have added that my administrator account in service account and grant access to owner. But not not worked.
Kindly help
I am trying to solve my problem and expecting a poper solution

Consent is required to transfer ownership of a file to another user [Google Drive API]

I have a Google Sheets file shared with 1 user - owner (Gmail account) and 2nd user - writer (google service account like #iam.gserviceaccount.com).
I use this function to copy a table from user 1 by user 2 and make the owner of copied file user 1 again:
$ownerPermission = new Google_Service_Drive_Permission([
'type' => 'user',
'role' => 'owner',
'emailAddress' => 'user1#gmail.com'
]);
$requestOwnership = $service->permissions->create($newfileId, $ownerPermission, ['fields' => 'id', 'transferOwnership' => 'true']);
And all works well until yesterday! Now Gooogle Drive API returns error: Consent is required to transfer ownership of a file to another user
How to fix it?
This seems to be a recent change to the google API. See also https://developers.google.com/drive/api/guides/manage-sharing
I haven't tried this, but it suggests that you should replace transferOwnership=true with role=writer and pendingOwner=true, and then separately update the permissions as user1#gmail.com with role=owner. I don't know how you do that second step from a gmail.com account though.
This seems to be working as expected as according to this Issue Tracker issue here:
Following up here, this is the expected behavior as currently Drive does not support the changing of the ownership for items which are owned by gmail.com accounts.

simpleSAMLphp and Azure gives me "AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application"

I am a novice for Azure SSO so I might have missed some obvious things here - please have that in mind ;-)
I need to integrate my application to Azure Active Directory. There is not much help to get in our organisation for that so I am left for myself to find the problem here :-/ My exact problem is that when I login then I get this error from Azure:
AADSTS50011: The reply URL specified in the request does not match the
reply URLs configured for the application: 'https://192.168.0.1/secure/'.
I have of course searched for how to solve this myself but I didn't find anything that could get me any closer.
I have this setup:
IIS
PHP
simpleSAMLphp
Azure AD
I have not setup nor access to the Azure part as this is setup by our IT guys but they have setup this:
Basic SAML Configuration
Identifier (Entity ID) : https://192.168.0.1/secure/
Reply URL (Assertion Consumer Service URL) : https://192.168.0.1/secure/
Sign on URL : Optional
Relay State : Optional
Logout URL : Optional
I have recived a federation XML file from Azure and have converted/populated that in to the simpleSAMLphp file \metadata\saml20-idp-remote.php
I have setup the \config\authsources.php file:
'entityID' => "https://192.168.0.1/secure/",
'idp' => "https://sts.windows.net/06dg12k9-1wl2-4mue-79gh-40ff1a8dnd4a/",
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
'simplesaml.nameidattribute' => 'eduPersonTargetedID',
Everything has been configured with this guide in mind, https://www.lewisroberts.com/2015/09/05/single-sign-on-to-azure-ad-using-simplesamlphp/
When I launch https://192.168.0.1/simpleSAMLphp/www/ and go to Authentication and Test configured authentication sources and I test with default-sp then I do get an Azure login screen. If I view the URL for that then it looks like this:
https://login.microsoftonline.com/0ad94219-6af5-474e-99d0-60f9188f3fce/saml2
?SAMLRequest=f[CUT]2Fy%2Fi%2Bjc%3D
&RelayState=https%3A%2F%2F192.168.0.1%2FsimpleSAMLphp%2Fwww%2Fmodule.php%2Fcore%2Fauthenticate.php%3Fas%3Ddefault-sp
I assume the RelayState is where the request comes from on my server. I have tried to setup the Entity ID and Reply URL in Azure to be https://192.168.0.1/simpleSAMLphp/www/module.php/core/authenticate.php?as=default-sp but with the same result.
So I have provided everything I know here but I am really blank on how to fix this problem? Do I need to configure a Reply URL in simpleSAMLphp so it is passed as an URL parameter?
Any help would really be appreciated.
### UPDATE 1 - another problem ###
After revising the logfile from simpleSAMLphp then it showed what was sent to Azure:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_25e3fb2" Version="2.0" Destination="https://login.microsoftonline.com/088f3fce/saml2" AssertionConsumerServiceURL="https://192.168.0.1/simpleSAMLphp/www/module.php/saml/sp/saml2-acs.php/default-sp" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
<saml:Issuer>https://192.168.0.1/simpleSAMLphp/www/module.php/saml/sp/metadata.php/default-sp</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" AllowCreate="true"/>
</samlp:AuthnRequest>
I then took the AssertionConsumerServiceURL from there and used that as Reply URL in Azure. Also I took the Entity ID from the simpleSAMLphp Federation page and now the simpleSAMLphp demo page works :-)
So my Azure setup now looks like this:
Basic SAML Configuration
Identifier (Entity ID) : https://192.168.0.1/simpleSAMLphp/www/module.php/saml/sp/metadata.php/default-sp
Reply URL (Assertion Consumer Service URL) : https://192.168.0.1/simpleSAMLphp/www/module.php/saml/sp/saml2-acs.php/default-sp
Sign on URL : Optional
Relay State : Optional
Logout URL : Optional
(note the difference in the URL)
However I sadly still have problems. When I have a PHP file in my web scope with this content:
<?PHP
require_once ("../../simpleSAMLphp/lib/_autoload.php");
$as = new SimpleSAML_Auth_Simple('default-sp');
$as->requireAuth();
$attributes = $as->getAttributes();
echo '<pre>';
print_r($attributes);
echo '</pre>';
// Get a logout URL
$url = $as->getLogoutURL();
echo 'Logout';
?>
Then it ends up in an infinite loop redirecting between my server and Azure!? Viewing the log provide no major insight for me. It seems that I do receive data from Azure and that I am authenticated as I can see the user attributes in the debug log but ... if I am authenticated then why am I redirected back to Azure!?
### UPDATE 2 - solution ###
After a few more hours of looking in the simpleSAMLphp logfile and cleaning out the WARNINGS (they are actually important) then I found out that my infinite redirection was caused by a mismatch between the PHP sessions and simpleSAMLphp sessions.
My solution was to align the two and have the exact same settings all places. Make sure to check the php.ini session settings and the \config\config.php session settings and make them identical.
Also I found out that the PHP source code I have used is for an older version of simpleSAMLphp though I don't think it was a problem.
Instead of this old method:
$as = new SimpleSAML_Auth_Simple('default-sp');
Then it should be this new method:
$as = new \SimpleSAML\Auth\Simple('default-sp');
RelayState is just a parameter that is echoed back to your SP as-is. It can be used to store the page url the user tried to access before authentication, for example.
If you're using SAML2, the replyURL should be your AssertionConsumerService url in your SP metadata. Azure will send the SAML Response there. If that url differs from https://192.168.0.1/secure/ you will get that error. Even a missing trailing / will cause the error.

Google API - allow connections only with Google Apps Domain

Is it possible to allow a client to connect to the API ONLY with a google apps domain email address? Users often have their own gmail session active and we need to ensure that they can only connect to the api using our Google Apps Domain email.
For now the only solution has been that we disconnect them when they return from the auth steps if their email address doesnt contain our domain, with an error message telling them they need to follow the steps again using their [domain].com email address, which is far less than ideal. Can the domain be specified somewhere in the scopes or api console for example?
[Google API PHP Client]
I found a hacky solution, describing briefly for those who may need smth similiar:
If you add the login_hint parameter with the email address (in this case with Google Apps account, with our own domain) it bypasses the initial login page and if any other google sessions are available bypasses them as well. I didn't find this behavior described in the documentation, nor did I find the ability to add this parameter in the google-api-php-client. I added a method in the Google_Client.php file to allow the ability to add the login_hint parameter:
public function setLoginHint($loginHint) {
global $apiConfig;
$apiConfig['login_hint'] = $loginHint;
self::$auth->login_hint = $loginHint;
}
And the parameter to the authenticate method in Google_Oauth2.php:
$request = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->redirectUri,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'login_hint' => $this->loginHint
)));
Then I can call the method using the user's Google Apps email address during authentication:
$client->setLoginHint("user#mydomain.com")
If there was something built in that I didnt find in the docs or searches please let me know. By the way, I thought Google API guys were keeping an eye on SO for questions such as these, echo echo...

Invalid OAuth Signature returned while using Yammer Api

I am trying to write a small webapp that pulls data from Yammer. I have to go through Yammer's OAuth bridge to access their data. I tried using the Oauth php library and do the 3 way handshake. But at the last step, I get an error stating I have an invalid OAuth Signature.
Here are the series of steps:
The first part involves getting the request Token URL and these are the query parameters that I pass.
[oauth_version] => 1.0
[oauth_nonce] => 4e495b6a5864f5a0a51fecbca9bf3c4b
[oauth_timestamp] => 1256105827
[oauth_consumer_key] => my_consumer_key
[oauth_signature_method] => HMAC-SHA1
[oauth_signature] => FML2eacPNH6HIGxJXnhwQUHPeOY=
Once this step is complete, I get the request Token as follows:
[oauth_token] => 6aMcbRK5wMqHgZQsdfsd
[oauth_token_secret] => ro8AJxZ67sUDoiOTk8sl4V3js0uyof1uPJVB14asdfs
[oauth_callback_confirmed] => true
I then try to authorize the given token and token secret by passing the parameters to the authorize url.It takes me to Yammer's authentication page where I have allow my app to talk to Yammer.
Yammer then gives me a 4 digit code that I have to put back into my application which then tries to acquire the permanent access token. I pass the following information to the access token URL:
[oauth_version] => 1.0
[oauth_nonce] => 52b22495ecd9eba277c1ce6b97b00fdc
[oauth_timestamp] => 1256106815
[oauth_consumer_key] => myconsumerkey
[callback_token] => 61A7
[oauth_token] => 6aMcbRK5wMqHgZQsdfsd
[oauth_token_secret] => ro8AJxZ67sUDoiOTk8sl4V3js0uyof1uPJVB14asdfs
[oauth_callback_confirmed] => true
[oauth_signature_method] => HMAC-SHA1
[oauth_signature] => V9YcMDq2rP7OiZTK1k5kb/otMzA=
Here I am supposed to receive the Oauth Permanent access token, but instead I get a Invalid Oauth signature. I dont know what I am doing wrong. I use the same signaures to sign the request. Should I sign the request using the new token and secret? I tried that as well but to no avail. I even tried implementing this in java using signpost library and got stuck at the exact same place. Help Help!!
The callback_token was something Yammer introduced in response to an OAuth security advisory earlier this year. When OAuth 1.0a was released, it was instead named oauth_verifier. However, it's not unlikely that Yammer still supports their workaround but rename it and try again to be sure.
Also, the below is information from the Yammer Development Network yesterday:
Tomorrow we will be releasing some
changes to the Yammer API to
facilitate user network switching on
API clients. Most of the change is in
the OAuth Access Tokens call which
allows you to generate pre-authorized
OAuth access tokens for a given user.
One token will be generated for each
network they are in and your clients
switch networks by sending an API
request signed with the appropriate
token for that network.
I'm assuming that Yammer OAuth libraries might need to be updated per this change. I haven't taken a look at it yet.
Edit: My python-yammer-oauth library still works despite Yammer having changed things on their side.
Edit2: Could you try using signature method PLAINTEXT instead of HMAC-SHA1? I've had problems with Yammer and HMAC-SHA1.
I tried by using PLAINTEXT.. but for this method its giving me the same "Invalid OAuth signature" error even for requesting the token.
So is it possible to generate the access token we use HMAC-SHA1 and for accessing the actual API method i.e. for posting the message.. we use PLAINTEXT?
just found the problem!
I had forgotten to add an ampersand ("&") at the end of CONSUMER_SECRET. Perhaps this is your issue as well?

Categories