Add custom attributes to response with simplesaml - saml

I'm setting up simplesaml as an IdP to do some testing for my SP. I need to add one new attribute to the response which is {sp_name}Access. However, I don't know where to add them.
I've tried adding the following to saml20-idp-hosted.php
'authproc' => array(
50 => array(
'class' => 'core:AttributeAdd',
'{sp_name}Access' => '{sp_name}Access',
),
)
And in my authsources.php I have this
'test-users' => array(
'exampleauth:UserPass',
'user1:user1pass' => array(
'uid' => array('1'),
'eduPersonAffiliation' => array('group1'),
'email' => 'user1#example.com',
'givenName' => 'User',
'surname' => 'One',
'{sp_name}Access => true
),
),
However it gives me this error
Backtrace:
1 www/_include.php:45 (SimpleSAML_exception_handler)
0 [builtin] (N/A)
Caused by: Exception: Invalid attributes for user user1 in authentication source test-users: Invalid attribute value for attribute loopioAccess: "1".
Backtrace:
6 modules/exampleauth/lib/Auth/Source/UserPass.php:55 (sspmod_exampleauth_Auth_Source_UserPass::__construct)
5 lib/SimpleSAML/Auth/Source.php:302 (SimpleSAML_Auth_Source::parseAuthSource)
4 lib/SimpleSAML/Auth/Source.php:343 (SimpleSAML_Auth_Source::getById)
3 lib/SimpleSAML/Auth/Simple.php:56 (SimpleSAML\Auth\Simple::getAuthSource)
2 lib/SimpleSAML/Auth/Simple.php:160 (SimpleSAML\Auth\Simple::login)
1 modules/core/www/authenticate.php:36 (require)
0 www/module.php:135 (N/A)
Any ideas how to actually add a custom attribute? I'm very new to simplesaml so I'm not sure if there's anything else I need to do to make this work.

Well, yout authsources.php IS missing a quotation mark after the key in the following key/value pair you provided... that could be a likely culprit.
'{sp_name}Access => true

Related

OneLogin SAML2 Invalid Schema

I am in the process of integrating OneLogin for SAML2 authentication. I have this working just fine in our QA servers but my production environment is throwing an error.
Warning: DOMDocument::schemaValidate(): Invalid Schema in
\Classes\OneLogin\src\Saml2\Utils.php on line 133
invalid_response
OneLogin\Saml2\Auth Object
(
[_settings:OneLogin\Saml2\Auth:private] => OneLogin\Saml2\Settings Object
(
[_paths:OneLogin\Saml2\Settings:private] => Array
(
[base] => \\Classes\OneLogin/
[config] => \\Classes\OneLogin/
[cert] => \\Classes\OneLogin/certs/
[lib] => \\Classes\OneLogin/src/
)
[_baseurl:OneLogin\Saml2\Settings:private] =>
[_strict:OneLogin\Saml2\Settings:private] => 1
[_debug:OneLogin\Saml2\Settings:private] =>
[_sp:OneLogin\Saml2\Settings:private] => Array
(
[entityId] => tools
[assertionConsumerService] => Array
(
[url] => https://example.com/login/saml2.php
[binding] => urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
)
[NameIDFormat] => urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
[x509cert] => -----BEGIN CERTIFICATE-----
From what it sounds like, the invalid schema is due to the response coming back? It must not be in the expected format that matches the .xsd?
If thats the case, this this usually be an indication of an invalid certificate?
$settingsInfo = array(
'strict' => true,
'sp' => array(
'entityId' => 'tools',
'assertionConsumerService' => array(
'url' => "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
),
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
'x509cert' => file_get_contents('lb-sso.pem', FILE_USE_INCLUDE_PATH),
'privateKey' => file_get_contents('lb-sso.key', FILE_USE_INCLUDE_PATH),
),
'idp' => array(
'entityId' => 'https://sso.example.com',
'singleSignOnService' => array(
'url' => 'https://sso.example.com/idp/SSO.saml2',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
),
'singleLogoutService' => array(
'url' => 'https://sso.example.com/idp/SSO.saml2',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
),
'x509cert' => file_get_contents('sso.pem', FILE_USE_INCLUDE_PATH)
),
'compress' => array(
'requests' => true,
'responses' => true
),
'security' => array(
'authnRequestsSigned' => true,
'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
)
);
$auth = new OneLogin\Saml2\Auth($settingsInfo);
Update:
I was able to print out some additional errors for this.
Warning: DOMDocument::schemaValidate(): Invalid Schema in \\Classes\OneLogin\src\Saml2\Utils.php on line 134
failed to load external entity "/Classes/OneLogin/src/Saml2/schemas/xmldsig-core-schema.xsd"
Element '{http://www.w3.org/2001/XMLSchema}import': Failed to locate a schema at location '/Classes/OneLogin/src/Saml2/schemas/xmldsig-core-schema.xsd'. Skipping the import.
failed to load external entity "/Classes/OneLogin/src/Saml2/schemas/xenc-schema.xsd"
Element '{http://www.w3.org/2001/XMLSchema}import': Failed to locate a schema at location '/Classes/OneLogin/src/Saml2/schemas/xenc-schema.xsd'. Skipping the import.
Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'ref': The QName value '{http://www.w3.org/2001/04/xmlenc#}EncryptedData' does not resolve to a(n) element declaration.
Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'ref': The QName value '{http://www.w3.org/2001/04/xmlenc#}EncryptedKey' does not resolve to a(n) element declaration.
The files xsd files do exist however the path appears to be possibly missing another / in front of it. //Classes/OneLogin/...
Update 2:
It appears there could be a difference of how idp is sending back the response to our production server verses our QA server.
The OneLogin files are identical on both sites but I had to toggle one setting in the security side of things wantXMLValidation = false.
This leads me to believe that the XML format they are sending back for the response doesn't match the same xsd format that is expected.
It shows that the authentication and certificates are all valid and the connection is being established, just no longer validating the format of the XML.
What security implications can this have if any or is it more of a housekeeping check to make sure it is including all of the expected nodes?
The SAMLResponse proccesed by the php-saml toolkit does not follows the xsd schema, that why you see that error.
You can try record the SAMLResponse with SAMLTracer and later use https://www.samltool.com/validate_xml.php to get the cause of the XML invalidation

Creating an Advanced Search field capable of searching multiple module fields

I am currently encountering issues trying to build a custom search field (itself bound to an unused field on a Module) to search two Phone Number fields. The documentation covering modifications of a search field are really poor, but I have the following in place in the module's SearchFields.php
'phone' =>
array (
'query_type' => 'default',
'operator' => '=',
'db_field' =>
array (
0 => 'home_phone_c',
1 => 'work_phone_c',
),
),
The field itself returns no results, so am I missing something that would prevent this from working?
why not you use "sub-query" operator for this? See SearchFields.php inside metadata folder of Account module. You will see entry like following:
'email' =>
array (
'query_type' => 'default',
'operator' => 'subquery',
'subquery' => 'SELECT eabr.bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (ea.id = eabr.email_address_id) WHERE eabr.deleted=0 AND ea.email_address LIKE',
'db_field' =>
array (
0 => 'id',
),
'vname' => 'LBL_ANY_EMAIL',
),
this will help you to understand the sugar logic of doing it.
You need to designate the correct tables. Try the below code (or use the tables that you're searching):
'phone' =>
array (
'query_type' => 'default',
'operator' => '=',
'db_field' =>
array (
0 => 'accounts_cstm.home_phone_c',
1 => 'accounts_cstm.work_phone_c',
),
),

zf2 doctrine form int required not working

$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
In my Doctrine Entity, I have a getInputFilter method which I use for form validation. The above is code snippet for one of the input elements. My problem is the required => true is not working even if I submit an empty form.
After researching I found out, that the Int filter converts the empty input to 0 and submits it and that is why the required validator is not working. I just need reasons why it may not be working.
For reference where I searched
Zend Framework 2 - Integer Form Validation
where he suggests to use Between validator
$inputFilter->add($factory->createInput(array(
'name' => 'zip',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'Between',
'options' => array(
'min' => 1,
'max' => 1000,
)
)
)
)
));
I want to know why I should use Between and why required is failing.
You should only use the Between validator to validate if the given value is Between a min and max value. It has nothing to do with solving your empty value to 0 issue.
You should ask yourself 2 questions:
Is 0 a valid value?
Do I want to automatically cast null empty string ('') and other empty values to this 0 or not?
If you actually want to prevent that the Int filter sets an empty value to 0, maybe then you should not use this filter at all then?
You can instead add an IsInt validator to check if the given value is an integer. Your required => true setting will work as expected and validation will fail on any other (not integer) input so also on null, empty strings etc.
Thank you for your time, energy & effort.
Actually I solved the problem.
I had copy-pasted the code, which I should have been careful while doing so.
What I found out is there is no such filter named 'Int' and actually it's 'Digits'
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
shows me error because the filter name should have been 'Digits'.
Only doing so solved my problem and works as per my requirement.
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Digits'),
),
));
This is the right way to do and I would advice you to be careful while referring code from your sources because it's an illogical mistake I did.
Happy coding

wordpress WP Query and Custom Field filtering

I've encoutered problem with filtering pages to display in WP query.
I use Codex WP query reference for custom fields with ACF (Advanced Custom Fields plugin - but it doesn't matter, couse it works same as WP custom field) parameters to filter pages.
In "Multiple Custom Field Handling" paragraph, Codex got an example with 2 conditions. We can use OR or AND relation. I works for both until you have 3rd condition (array).
They use example:
'relation' => 'OR',
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE'
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
It has only 2 arrays. When I put 3rd, nothing shows. In debug mode I can see an error:
WordPress database error: [Lost connection to MySQL server during query]
When I use AND it works, but I got to use OR. Unfortunately it makes MySQL disconnect.
I've tryed asking phpMySQL for same query WP does. It couses problem - phpMyAdmin says same:
Lost connection
Any Idea?
Maybe I should try different aproach for filtering? (maybe I should use taxonomy?)
Here is code I use:
$query_array = array('relation' => 'OR');
array_push($query_array,
array(
'key' => 'filter1',
'value' => 'value1',
'compare' => 'LIKE'
),
array(
'key' => 'filter1',
'value' => 'value2',
'compare' => 'LIKE'
),
array(
'key' => 'filter1',
'value' => 'value3',
'compare' => 'LIKE'
)
);
$args = array(
'order' => $order_array,
'meta_key' => $meta_key,
'orderby' => $orderby,
'post_type' => 'page',
'paged' => $paged,
'post__in' => $postIDs,
'posts_per_page' => 12,
'paged' => get_query_var('paged'),
'meta_query' => $query_array
);
query_posts($args);
?>
(variables for $args are set of course)
I don't know why I can't use
'compare' => '='
but probably it is why I can't use:
$query_array = array('relation' => 'OR');
array_push($query_array,
array(
'key' => 'filter1',
'value' => array('value1', 'value2', 'value3'),
'compare' => 'IN'
)
);
Just wanted to say that your comment helped me; I'd been butting my head against a very similar problem for a while. I'm using ACF too, and using it to attach items of one post type to another custom post type was easy - for instance, to Attach Person_1 and Person_3 to "Project_A".
This made it easy to list out which users were attached to specific projects. But when it came to do the same in reverse - to show which projects were attached to which users - it became a massive headache.
I finally figured it out, in part thanks to your comment - I'll post my solution here in case someone else comes along with the same problem:
$args = array(
'numberposts' => -1,
'post_type' => 'project',
'meta_query' => array(
'relation' => 'IN',
array(
'key' => 'people',
'value' => ';s:1:"' . $person->ID . '";',
'compare' => 'LIKE'
)
)
);
In short: because the ACF values in repeater fields et cetera are serialized, the compare keyword has to be "LIKE", and I added some context to the value to eliminate false returns - just searching for an ID like "1" would match a lot of the (wrong) posts, but the ";s1;" part ensures that the given value is at index 1, which in my case is the correct index.
So it would need tweaking from case to case. Inspecting what you're trying to match up with var_dumping "get_post_meta($post->ID, 'people')" is helpful for getting the value correct.

Zf2 + Doctrine 2 Authentication Adapter with Multiple or Alternate Columns

I am working on a site in which user can enter two email address(primary and secondary) along with password.
If user enters his primary email and password, he gets logged in successfully.
But, what I am trying to provide is if user enters his secondary email instead of primary, even then he gets logged in. And the problem I am getting is how to create an alternate Doctrine Auth Adapter or something like that.
this is what I have done in my module.config.php:
'doctrine' => array(
'driver' => array(
__NAMESPACE__ . '_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
)
)
),
'authentication' => array(
'orm_default' => array(
'object_manager' => 'Doctrine\ORM\EntityManager',
'identity_class' => 'User\Entity\LoginDetails',
'identity_property' => 'primary_email',
'credential_property' => 'password',
),
),
)
Is there any option to add an identity property which will be alternative ?
I am using Zend framework 2 and Doctrine 2
Is there any option to add an identity property which will be alternative ?
No, there is no such option built-in to DoctrineModule.
Consider extending DoctrineModule\Authentication\Adapter\ObjectRepository to override the authenticate() method.
Then, at minimum, you'll want to replace the default adapter with your new more different one. If you look at the various factories in DoctrineModule, you should be off to a good start.
Basically, one of your modules will want to override the doctrine.authenticationadapter.[orm|odm]_default configuration key in the ServiceManager. That will cause DoctrineModule to inject your extended ObjectRepository into the AuthenticationService in place of you the default one.