SimpleSamlPhp, Multiple Idps (Identity Providers), Multiple Sps (Service Providers) - saml-2.0

I have been given a task at work to implement SAML 2.0. I have successfully set it up based on the docs.
However, I need to know if SimpleSAMLPhp can be configured as multiple idps per instance of SimpleSAMLPhp as an Idp and Multiple Sp's per instance as an Sp.

You can configure multiple SPs per installation in authsources.php
If you want mulitple Service Providers in the same site and installation, you can add more entries in the authsources.php configuration. If so remember to set the EntityID explicitly. Here is an example:
'sp1' => array(
'saml:SP',
'entityID' => 'https://sp1.example.org/',
),
'sp2' => array(
'saml:SP',
'entityID' => 'https://sp2.example.org/',
),
You can configure multiple IdPs per installation as well however they need to be on different hostnames.
<?php
/* The index of the array is the entity ID of this IdP. */
$metadata['entity-id-1'] = array(
'host' => 'idp.example.org',
/* Configuration options for the first IdP. */
);
$metadata['entity-id-2'] = array(
'host' => '__DEFAULT__',
/* Configuration options for the default IdP. */
);

Related

How to set up HyperDB for WordPress website?

I have a large database which I want to split into several databases but connected to my WordPress site. I searched through internet and came to a solution of using HyperDB class which is provided by WordPress Codex. I downloaded the files and I tried like below
$wpdb->add_database(array(
'host' => 'localhost', // If port is other than 3306, use host:port.
'user' => 'root',
'password' => '',
'name' => 'partitioning',
));
/**
* This adds the same server again, only this time it is configured as a slave.
* The last three parameters are set to the defaults but are shown for clarity.
*/
$wpdb->add_database(array(
'host' => 'localhost', // If port is other than 3306, use host:port.
'user' => 'root',
'password' => '',
'name' => 'slave',
'write' => 0,
'read' => 1,
'dataset' => 'global',
'timeout' => 0.2,
));
I am using xampp for the development version. After WordPress site installation I put the db-config.php along with wp-config.php file directory and db.php in wp-content folder. Doing this I get the blank page.
Can any one elaborate the process step by step how to set up the database and HyperDB scripts? I mean how to make the slave database or HyperDB will automatically make the slave database? How can I split any table to slave database? The whole process I mean.
If you're building a high-volume Wordpress site, and the database is the bottleneck (as it often is), HyperDB is absolutely the correct Wordpress solution. HyperDB is authored by Automattic, is used on Wordpress.com, and is designed as a proper Wordpress drop-in.
HyperDB supports MySQL read-replicas and partitioning, and which you use depends on your use-case.
These configuration options are actually reasonably well documented in the HyperDB Config file, which looks like this:
https://plugins.trac.wordpress.org/browser/hyperdb/trunk/db-config.php
This won't precisely work for your situation; you'll have to adjust this to fit your setup.
// This is the default database configuration
//
$wpdb->add_database(array(
'host' => 'localhost',
'user' => 'root',
'password' => '',
'name' => 'regular_db',
));
// This is your secondary database.
//
$wpdb->add_database(array(
'host' => 'localhost',
'user' => 'root',
'password' => '',
'name' => 'product_db',
'dataset' => 'products',
));
// This magic detects which database table is being read from/written to, and switches
// hyperdb connection based on that.
$wpdb->add_callback('my_db_product_detector');
function my_db_product_detector($query, $wpdb) {
// This makes the assumption that you've only got one relevant table, wp_products.
// Update this to whatever your table name(s) are.
if ( preg_match('^wp_products$', $wpdb->table) ) {
return 'products';
}
}
To begin with, to test that this works on your existing database, you should change product_db to regular_db, and go from there.
At this point, you have architectural decisions to make. If you simply want to reduce the size of your DB, then this now writes your products to a second DB. Alternatively, you might have a second database server entirely to share the load across different databases.
Creating a read replica is also worth considering, but that depends on what ecosystem you're working with. If you're using AWS, then RDS will create read replicas quite simply.

Laravel 5 How to configure the Queue database driver to connect to a non-default database?

In Laravel 5.1, we can set the Queue connection configurations in config/queue.php.
QUEUE_DRIVER=database
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'expire' => 60,
],
However, it will only use the default database connection in config/database.php.
If I have 2 database, 1 default database mysql1 in localhost, and 1 database mysql2 in a remote server, and the Queue jobs table is in the remote database mysql2, how can I configure the Queue database driver to use the remote mysql2 database? Please note that the main App is using the default database in localhost.
You can use the 'connection' parameter in queue.php to set the correct database connection ( from the ones you've defined in database.php ).
'database' => [
'connection' => 'mysql2',
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'expire' => 60,
],
I was looking for the same thing and found it in the source code.
NOTE: This will not only read the jobs from this connection ( when running the queue ), but also write them to this connection ( when dispatching a new Job ) .
The best answer here did not work for me, not to say it isn't the best answer for a different issue than mine. My issue was that Laravel did not cache my config settings.
After going into file \config\queue.php and changing the default driver...
'default' => env('QUEUE_DRIVER', 'database'),
The queue was still running on the sync driver.
I then checked the file...
\bootstrap\cache\config.php
Around line 30 I saw this...
'queue' =>
array (
'default' => 'sync',
...but to connect to the database, it should be...
'queue' =>
array (
'default' => 'database',
This resolved the issue...
php artisan config:cache
Running the config:cache commmand rewrites the config.php file to the current driver settings.
You can set the $connection variable in the model. Note that this will only affect Eloquent queries and will not work for the Fluid Query Builder.
class Jobs extends Eloquent {
protected $connection = "database2"
}
This would of course require you to have a 2nd named connection in your config/database.php file that is 'database2' => [...].

how use Acl to limit user access

I have same login for 3 different type of users, admin/client/user, everyone has different layout and privileges but the issue is after login every one is able to access all pages. after a lot of search on Google and stack overflow i decided to use Acl. I created tables in database via right procedure recommended by Acl given here AccessControlList. I set permission in following way. But still all type of user are accessing all pages.
$this->Acl->allow(
array('model' => 'User', 'foreign_key' => 1),
'admins'
);
$this->Acl->allow(
array('model' => 'User', 'foreign_key' => 2),
'clients'
);
any help will be appreciated.

Multiple sessions for different instances of Cakephp in the same domain

Did you know that if you run multiple instances of the same application in Cakephp in the same domain, they will share the same Session? For example, suppose you have instances running at:
www.example.com/instance1 and www.example.com/instance2
If you login in the first instance and access instance2, you’ll see that you will already be logged in. This happens because Cakephp, per default, uses the PHP Session storage mechanism.
If this is not the behaviour you expect, Cakephp allows you to choose from three options for the Session handling method: php (default), cake and database. The current method is stored in the Session.save variable in app/config/core.php.
Changing the method from php to cake will make Cakephp store the Session variables in the app/tmp/sessions directory. If you do it, remember to create and give the appropriate permissions to this directory.
Voilá, that’s all you need to do have separate Sessions for each of your Cakephp instances.
Please open the core.php & change the application cookie path then session will be store according to application cookie path
For www.example.com/instance1
Configure::write('Session', array(
'defaults' => 'database',
'ini' => array(
'session.cookie_path' => '/instance1',
),
'cookie' => 'instance1',
'cookieTimeout' => 0,
'checkAgent' => false
));
For www.example.com/instance2
Configure::write('Session', array(
'defaults' => 'database',
'ini' => array(
'session.cookie_path' => '/instance2',
),
'cookie' => 'instance2',
'cookieTimeout' => 0,
'checkAgent' => false
));

What's the most elegant way to handle users custom domains?

On my site, users have public profiles that can be accessed via http://mysite.com/vanity_url. I want to allow users to point their own domains to their profile page on my site. Just like Bandcamp does.
My Profile model has these two fields to deal with this: vanity_url, which is the normal username type of field; and a new custom_domain which is their own domains' name, eg, example.com.
This is what I have done so far, but I'm afraid it might not be the most elegant, safe, and efficient way to do it.
First, I made sure Apache's DocumentRoot is set to my app's webroot directory, so I can tell users to point their DNS to my site's IP.
Now, this is how the routing rules on my routes.php look like:
if (preg_match('/mysite\.com\.?$/', $_SERVER['SERVER_NAME'])){
// Normal routes when visitors go to my domain
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/pages/**', array('controller' => 'pages', 'action' => 'display'));
// Move all other actions to a separate '/app/' area
Router::connect('/app/:controller/:action/**');
Router::connect('/app/:controller/**');
// Handle profile URLs
Router::connect('/:profile/**',
array('controller' => 'profiles', 'action' => 'view'),
array('pass' => array('profile'), 'profile' => '[0-9a-zA-Z\-\_]+')
);
}
else{
// If visitors come via a URL different to mysite.com, I let
// the ProfilesController deal with it passing the current SERVER_NAME
// as a param to the 'view' action
Router::connect('/', array(
'controller' => 'profiles',
'action' => 'view',
$_SERVER['SERVER_NAME'], // 'url' param
true // 'customDomain' param
));
Router::redirect('/*', 'http://mysite.com');
}
And this is how the view action on the ProfilesController looks like:
public function view($url = null, $customDomain = false) {
if ($url){
// Find the profile by its vanity_url or its custom_domain
$findOptions = array(
'conditions' => $customDomain?
array('custom_domain' => $url) :
array('vanity_url' => $url)
);
if ($profile = $this->Profile->find('first', $findOptions)) {
$this->set('profile', $profile);
}
}
else throw new NotFoundException(__('Invalid profile'));
}
What problems could I face with this approach?
Also, does anyone know why Bandcamp asks users to create a CNAME instead of an A record to set up a subdomain? Am I missing something I should consider here?
Edit Somebody helped me figure that last bit out: It seems you can't easily use an CNAME record to point a naked domain to another. The main question is still open.
I did something similar using cake 1.3 a year ago
There are 4 major steps in this solution:
Have a Domain model and domains datatable that records all the possible custom domains and Views for your users to enter their custom domains
create domain checking code in beforeFilter in AppController and save User data to Session
the Controller action that is responsible for viewing the public profile needs to reference the same User data that is saved to Session
your users need to setup CNAME and A records correctly with their domain registrars
Step 1 Domain model and datatable
What I did was I had a table called domains
Each Domain contains the web address which I assumed to be just a http://....
Domain belongsTo User
User hasMany Domain
domains
==========
id web_address user_id main
the main is a tinyint which indicates whether this is the main url to be used since User hasMany Domain.
so what happens is the user needs to create a new record or more for Domain.
Step 2 Code in beforeFilter of AppController to figure out which public profile to display
Next, your code needs to be able to retrieve the User id based on the url submitted upon each http request.
The User from this point onwards refer to the User whose public profile is viewed. Do NOT confuse this with the loggedIn User, should you have one.
I suggest that you do this in your beforeFilter of AppController.
Something like this
$currentUser = $this->User->getByDomain(FULL_BASE_URL);
$this->Session->write('CurrentUser', $currentUser);
The code for getByDomain for User model is also an exercise for you. Should be easy enough given that I have explained the schema for Domains
You may need to check against the currentUser inside your Session data before writing the currentUser because you do not wish to write the Session data all the time especially when the visitor is visiting the same webpage again and again.
You may need to change the above code snippet to something like this:
$currentUser = $this->Session->read('CurrentUser');
if(empty($currentUser) OR (!$this->checkUrlAgainstDomain(FULL_BASE_URL, $currentUser['Domain']['domain']))) {
$currentUser = $this->User->getByDomain(FULL_BASE_URL);
$this->Session->write('CurrentUser', $currentUser);
}
Again the function checkUrlAgainstDomain is an exercise for you.
Step 3 Code in beforeFilter of AppController to figure out which public profile to display
You will use the CurrentUser data saved in your Session to determine which User's public page you want to display.
I leave this as an exercise for you to figure out in your UsersController under action view
Step 4 your users need to enter the following in their domain registrars
Then your users need to go to their domain registrars and do a similar thing as BandCamp users in the faq you have linked to.
User's "www" subdomain should point using CNAME to example.Lucho.com
User's root domain (without the www) should have an A Record pointing to IP Address of your server ie where your Lucho.com is residing in
User must add both both of these Domains management page as explained earlier on the top. It can take up to 48 hours for the domain to completely update.
I guess there's no better way :P

Resources