So The Direct Project strikes again. I'm no expert in LDAP, but I'm trying to set up a test environment since the standard requires any package to support getting certificates from LDAP as well as DNS CERT, regardless of which method is implemented by the package.
According to the documentation, the prescribed sequence of events (trimmed for relevance) from section "3.3.3 LDAP query":
* Discover the Base DNs
Branches in LDAP must be defined by a “Base DN”. The list of Base DNs that are
provided by a LDAP directory are found by doing a LDAP Query with a NULL (i.e.
“”) Base DN, and ObjectClass=”DN”.
* Query across the Base DN for entries where "Mail" contains the endpoint address
I'm trying to implement this process in php, using the ldap_* functions, but their way doesn't seem to work. Obviously, NULL is not the same as an empty string (the latter makes any call to ldap_search return a "No such object" error), and "DN" isn't a valid value for an ObjectClass attribute.
So, TL;DR, is there another way an anonymous remote user retrieve the (list of?) base DNs that I'm missing?
UPDATE: Reworded the title to reflect the root cause of my problem: Reading the rootDSE from PHP when the ldap_* api doesn't allow you to specify 'base' scope.
So another read through the docs answered my question for me.
Apparently, the only difference between ldap_search(), ldap_list(), and ldap_read() are the scopes (LDAP_SCOPE_SUBTREE (sub), LDAP_SCOPE_ONELEVEL (one), and LDAP_SCOPE_BASE (base), respectively). So using ldap_read() instead of the others will allow one to get the rootDSE.
In the root dse. See "namingContexts".
Update:
In java:
LDAPConnection conn = new LDAPConnection(hostname,port);
SearchRequest req = new SearchRequest("",SearchScope.BASE,"(&)","+");
SearchResult result = conn.search(req);
// If the search succeeds, the result will comprise one entry,
// and that entry is the Root DSE:
dn:
subschemaSubentry: cn=schema
namingContexts: C=us
vendorName: UnboundID Corp.
vendorVersion: UnboundID Directory Server 4.1.0.6
Related
We have an implementation of openid connect which returns an encoded id token, this works well and has been working for a while. However we are attempting to connect to it using cognito in aws and after a bit of trial and error we have found that we are missing a .well-known/openid-configuration file.
This file is meant to contain information about the calls to the openid-connect server we have including the JWK keys.
I don't understand JWK keys, this means:
1. How to generate them
2. Once generated what to do with them?
3. Does the exising code we have for the openid-connect need to change and use the JWK keys?
4. Is there any way of validating an openid-connect configuration?
I have asked something similar a while back but with no avail but revisiting.
Thanks
Kevin
What Ive already tried:
Been here: https://mkjwk.org/ and clicked on 'New Key', which returns what I assume is a web key.. however don't know what i'm meant to do with it or what the other tabs on that mean.
Expected Results:
Expecting AWS Cognito to continue and allow it to connect to our open id connect implementation. Currently just get an error with regards to a missing well known configuration file.
The openid connect server you have generates ID token that are JWS.
These tokens are signed using a private key (EC, RSA or OKP).
The well-known/openid-configuration is should contain a JSON object that indicates what algorithms are used to sign the tokens and the url to get the public keys associated to the private keys used to sign the token.
For example, the Google Account server configuration indicates the public keys can be found at https://www.googleapis.com/oauth2/v3/certs (jwks_uri parameter).
At this url, you will find a list of keys (JWKSet) formatted in JWK (JSON Web Keys). These formats (JWK and JWKSet) are the standrad representations for keys and key sets used in a JWT context (see RFC7517).
How to generate them
Normally you already have at least one private key to sign your tokens so you don’t have to generate a new one.
Once generated what to do with them?
The private key you have should be a PEM (starting with ------ PRIVATE RSA KEY ----- or similar) or DER key.
You just have to convert this key into JWK.
I created a small PHAR application (PHP) that will help to convert your keys. This app is part of the Web Token Framework but can be installed as a standalone app. Make sure you have PHP 7.1, OpenSSL and JSON extensions installed.
When the app is installed, you can execute the following command:
jose key:convert:public $(jose key:load:key PATH_TO_YOUR_KEY)
This command will convert the private key into JWK and then convert it from private to public.
The result can be shared through the jwks_uri endpoint.
Does the exising code we have for the openid-connect need to change and use the JWK keys?
No. The way you build your tokens does not means you have to change anything.
Is there any way of validating an openid-connect configuration?
As far as I know, there is no tools to validate the configuration object. You have to refer to the OpenID Connect specification.
While Florent's answer the usage of public key, I like to point you to the specification that defines the contents of JWK and specific implementation details.
OpenID Connect discovery define the discovery document. There you find jwks_uri URL as part of the metadata, which points to JSON Web Key Set
3. OpenID Provider Metadata
wks_uri
REQUIRED. URL of the OP's JSON Web Key Set [JWK] document. This
contains the signing key(s) the RP uses to validate signatures from
the OP
Now this points to RFC7517 - JSON Web Key (JWK). You can find exact details of each field of the JSON payload there. Refer its samples and appendix section to see sample contents. And your implementation must follow specification requirements defined by this.
For coding, if you are using JAVA, I suggest you to use Nimbus JOSE+JWT library. Sample can be found from this link.
For example, if you already have X509Certificate loaded, then following is the minimalistic code to generate JWK. It is embedded into a Servlet [Full source].
import Common.CertificateLoader;
import Common.Exceptions.FrameworkUncheckedException;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.JWK;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.cert.X509Certificate;
#WebServlet(urlPatterns = "/openid-configuration/jwks_uri")
public class JWKDocument extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// NOTE - LOAD YOUR CERTIFICATE HERE
final X509Certificate certificate = CertificateLoader.getCertificateLoader().getX509Certificate();
final JWK jwk;
try {
jwk = JWK.parse(certificate);
} catch (JOSEException e) {
throw new FrameworkUncheckedException("Error while loading to JWK", e);
}
resp.getOutputStream().print(jwk.toJSONString());
}
}
I am encountering precisely this problem:
Symfony Docs - How to Generate URLs and Send Emails from the Console
Our email templates are being filled with "localhost" instead of "my.real-domain.name". When constructing links to the application using twig's "url('some/path')".
However, where Symfony is usually "one installation per domain", our application is designed so a single instance can handle multiple domains. It constructs the necessary configuration through various configuration channels, with each customer being one channel.
Thus I would like to avoid configuring "router.request_context.host" and others for every single customer channel.
So I would like to grab the domain to be used from a "--domain" console parameter that we give to every console command instad.
But instead of doing it in every single command, I would need to do this in one central location that grabs the domain and configures "router.request_context" dynamically according to the console parameter.
Is there any way I can do that?
You can register a listener on the event dispatcher which listens to the ConsoleEvents::COMMAND and configure it further before the run method on the command is called.
For example, you can use a setter or change the input on the ConsoleCommandEvent instance.
https://symfony.com/doc/3.4/components/console/events.html
I'm not sure this is an ideal solution, but this is what I could think of at the moment.
You can tell to the router which domain use when generating an absolute URL, as example:
$domain = $input->getArgument('domain');
$context = $this->getContainer()->get('router')->getContext();
$context->setHost($domain);
$route = $this->getContainer()->get('router')->generate('welcome_page', $params, UrlGeneratorInterface::ABSOLUTE_URL);
$output->writeln('Use the following url to show the welcome page for the provided domain');
$output->writeln(sprintf('<info>%s</info>', $route));
Hope this help
I'm trying to make auth calls connecting from php to an Active Directory server auth looks fine but I don't know what to put as ldap_search parameters.
dump of ldap_connect:
resource(4) of type (ldap link)
dump of ldap_bind:
bool(true)
dump of ldap_search:
resource(5) of type (ldap result)
dump of ldap_get_entries:
array(1) {
["count"]=>
int(0)
}
I tried an endless number of permutation of this kind of parameters:
$ldap_dn = "CN=Users,DC=ad,DC=domain";
$ldap_filter = "(objectClass=*)";
but I'm not sure what exactly to put as DC= value in my specific case or O= or OU= or CN= or whatever, any help will be appreciated.
The base distinguished name is the base distinguished name you'd like to perform operations on. An example base DN would be DC=corp,DC=acme,DC=org.
You can learn it from your active directory server manager.
I also recommend you to use adLDAP Package
It is a PHP class that provides LDAP authentication and integration with Active Directory.
If one dc is not defined, then the package will try to find it automatically by querying your server. It's recommended to include it to limit queries executed per request. It has some custom functions that use PHP's defualt ones. Hence, using the package may make your work easier.
I've been working on a project (which I'll keep specific details out of this post with randomized data) that involves integrating our system (PHP 5.3.x+) with an API (they provided a SDK) of a major company. They provided a WSDL and claimed ours needed to match their methods and they provided examples of how output (XML generated by the Soap Server) should look.
Right now, everything has been working as expected. When I send a XML request from SoapUI (an app I'm using to test) it all processes properly and such, but the XML output isn't matching closely with their examples and we believe they said we must be close to their examples.
Basically, we created an agnostic class we initialize with a service name and it initializes into a non-agnostic class which is used via the following:
/**
* The following is used to process Soap Server based on config and any optional settings.
*
* #param string $className
* #param array $options
* #param object $config
* #return Zend_Soap_Server
*/
public static function init($className, Array $options = null, $config = null)
{
// Used to define the class and return object.
$soap_server = new Zend_Soap_Server(null, $options);
$soap_server->setClass($className, null, (isset($config) ? $config : null));
$soap_server->handle();
exit;
}
The problem itself lies within the outputted response. How would you guys suggest we build the XML output if they're very specific about everything?
1.) One of our methods is moneyTransferRequest. When I send the XML over for this, it does find the method and processes it. However, they want it to show the method name, in the response, as moneyTransferResponse but it outputs moneyTransferRequestResponse.
2.) Our output (for variables and such sent back as an object) has multiple variables, we'll say $money for example. The field for this would return as:
<money xsi:type="xsd:string">10.0</money>
They would like it to be:
<ns1:money xsi:type="xsd:string">10.0</money>
in the return.
I appreciate any help and input on the subject.
The key feature of SOAP is that it uses XML, and XML can come in a bunch of different styles but still mean the same.
I think (but I can only guess because you didn't provide details) that your two issues might be non-existing.
1.) The name of the response XML structure should align with the name mentioned in the WSDL. YOU are publishing the WSDL, so you should check if these two match. Note that the important entry point is the SOAP method - everything thereafter is defined in the WSDL itself, any consuming client should be able to figure it out as long as the names mentioned are correctly used.
2.) This is basically the same, but even easier: XML allows to use namespaces, and these can be defined in several locations, with the result being not literally the same, but every XML parser will understand that they are the same. So you should check whether the namespace that is required as "ns1" is mentioned in the XML header of your response. Every XML document has a base namespace, which does not need to be repeated on every element that belongs to it.
This is the case with the <money> element. Your style of writing uses that base namespace, their style of writing uses a namespace shortcut ns1 also introduced in the XML header, but not declared as the base namespace. So as long as there are traces of the correct XML namespace in both responses, I'd assume they are equivalent.
And the bad news would be that you cannot change how the PHP SoapServer generates the XML. You'd need to create your own implementation of a SOAP server, which I'd say is a complete waste of resources.
PHP provides a great function for copying or moving directory records within LDAP. Unfortunately this ldap_rename function doesn't seem to work on the Sun Directory. Do any alternatives exist to change an account's OU without having to create a new account?
My end goal is to have a simple method to switch between two OU's, such as:
CN=username,OU=Admin,DC=uaa,DC=alaska,DC=edu to
CN=username,OU=Student,DC=uaa,DC=alaska,DC=edu
You can do it with LDIF. On the directory point of view, the job you want to do is called a DN modification, there are two LDAP verbs for that moddn and modrdn.
It can be done in LDIF by this way in OpenLDAP:
dn: CN=username,OU=Admin,DC=uaa,DC=alaska,DC=edu
changetype: modrdn
newrdn: CN=username
deleteoldrdn: 0
newsuperior: OU=Student,DC=uaa,DC=alaska,DC=edu
I use this way accros Active Directory :
dn: CN=username,OU=Admin,DC=uaa,DC=alaska,DC=edu
Changetype: moddn
Newrdn: CN=username
Deleteoldrdn: 1
Newsuperior: OU=Student,DC=uaa,DC=alaska,DC=edu
Be careful, copy/delete is significantly different from moddn and modrdn in the first solution you create new objects (new guid or uuid in the LDAP database) and it can impact replication. In the second solution you move objects.
Perhaps you can find there verbs in PHP.