{"id":27100,"date":"2016-12-11T04:26:33","date_gmt":"2016-12-11T02:26:33","guid":{"rendered":"https:\/\/mamchenkov.net\/wordpress\/?p=27100"},"modified":"2016-12-12T11:34:08","modified_gmt":"2016-12-12T09:34:08","slug":"php-microsoft-office-365-and-active-directory","status":"publish","type":"post","link":"https:\/\/mamchenkov.net\/wordpress\/2016\/12\/11\/php-microsoft-office-365-and-active-directory\/","title":{"rendered":"PHP : Microsoft Office 365 and Active Directory"},"content":{"rendered":"<!-- google_ad_section_start -->\n<p><strong>Disclaimer<\/strong>: I am not the biggest fan of Microsoft. \u00a0On the contrary. \u00a0I keep running into situations, where Microsoft technologies are a constant source of pain. \u00a0If that annoys you, please stop reading this post now and go away. \u00a0I don&#8217;t care. \u00a0You&#8217;ve been warned.<\/p>\n<p>A few recent projects that I&#8217;ve been working on <a href=\"https:\/\/www.qobo.biz\/\">in the office<\/a> required integration with <a href=\"https:\/\/products.office.com\/en\/business\/explore-office-365-for-business\">Microsoft Office 365<\/a>. \u00a0Office 365 is a new kid on the block as far as I am concerned, so I had no experience of integrating with these services.<\/p>\n<p>The first look at what needs to be done resulted in a heavy drinking session and a mild depression. \u00a0Here are a few links to get you started on that path, if you are interested:<\/p>\n<ul>\n<li><a href=\"http:\/\/haishibai.blogspot.com.cy\/2012\/07\/guided-tour-of-windows-azure-active.html\">Get Started with Windows Azure Active Directory (Developer Preview)<\/a><\/li>\n<li><a href=\"https:\/\/dev.office.com\/code-samples-detail\/2138\">PHP Calendar API Sample<\/a><\/li>\n<li><a href=\"https:\/\/dev.office.com\/code-samples-detail\/5984\">PHP Connect sample using Microsoft Graph<\/a><\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/22262616\/logging-into-office365-email-using-php\">Logging into Office365 email using PHP<\/a><\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/11551181\/using-php-and-ldap-to-connect-to-microsoft-office-365\">Using PHP and LDAP to connect to Microsoft Office 365<\/a><\/li>\n<\/ul>\n<p>We&#8217;ve discussed the options with the client and decided to go a different route &#8211; limit the integration to the single sign-on (SSO) only, and use their Active Directory server (I&#8217;m not sure about the exact setup on the client side, but I think they use <a href=\"https:\/\/technet.microsoft.com\/en-us\/windowsserver\/dd448613.aspx\">Active Directory Federation Services<\/a> to have a local server in the office synchronized with the Office 365 directory).<\/p>\n<p>Exposing the Active Directory server to the entire Internet is not the smartest idea, so we had to wrap this all into a virtual private network (VPN). \u00a0You can read my blog post on how to <a href=\"https:\/\/mamchenkov.net\/wordpress\/2016\/11\/20\/automate-openvpn-client-on-centos-7\/\">setup the CentOS 7 server as an automated VPN client<\/a>.<\/p>\n<p>Once the Active Directory was established, <a href=\"http:\/\/php.net\/manual\/en\/book.ldap.php\">PHP LDAP module<\/a> was very useful for avoiding any low-level programming (sockets and such). \u00a0With a bit of Google searching and StackOverflow reading, we managed to figure out the magic combination of parameters for <em><a href=\"http:\/\/php.net\/manual\/en\/function.ldap-connect.php\">ldap_connect()<\/a><\/em>, <em><a href=\"http:\/\/php.net\/manual\/en\/function.ldap-set-option.php\">ldap_set_option()<\/a><\/em>, and <em><a href=\"http:\/\/php.net\/manual\/en\/function.ldap-search.php\">ldap_search()<\/a><\/em>.<\/p>\n<p>It took longer than expected, but some of it was due to the non-standard configuration and permissions on the client side. \u00a0Anyways, it worked, which were the good news.<\/p>\n<p>The client accepted the implementation and we could just close the chapter, have another drink, and forget about this nightmare. \u00a0But something was bothering me about it, so I was thinking the heavy thoughts at the back of my mind.<\/p>\n<p>The things that bother me about this implementation are the following:<\/p>\n<ul>\n<li>Although it works, it&#8217;s a rather raw implementation, with very limited flexibility (filters, multiple servers, etc).<\/li>\n<li>The code is difficult to test, due to the specifics of the AD setup and the network access limitations.<\/li>\n<li>There is a lack of elegance to the solution. \u00a0Working code is good, but I like things to be beautiful too. \u00a0As much as possible at least.<\/li>\n<\/ul>\n<p>So, I was keeping an eye open\u00a0and I think today I came across a couple of links\u00a0that can help make things better:<\/p>\n<ol>\n<li><a href=\"https:\/\/github.com\/adldap\/adLDAP\">adLDAP<\/a> PHP library, which provides LDAP authentication and integration with Active Directory. \u00a0I don&#8217;t know how I missed it so far, but I think now things will be much easier and cleaner.<\/li>\n<li><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa746475(v=vs.85).aspx\">Search Filter Syntax<\/a> documentation on MSDN.<\/li>\n<li><a href=\"https:\/\/www.reddit.com\/r\/PHP\/comments\/ly2mf\/trying_to_check_a_username_against_an_ad_group\/\">This Reddit thread<\/a>. \u00a0Yes, a lot of the things I&#8217;ve learned today are linked from it. \u00a0But it&#8217;ll be much easier for me to find all this information in my own blog, next time I&#8217;ll have to deal with Microsoft again.<\/li>\n<li><a href=\"https:\/\/drupal.gatech.edu\/handbook\/whitepages-gt-directory-server\">Public-facing LDAP server<\/a>\u00a0thanks to\u00a0<a href=\"http:\/\/www.gatech.edu\/\">Georgia Institute of Technology<\/a>, for testing connection and simple queries.<\/li>\n<\/ol>\n<p>Armed with this new knowledge, I&#8217;m sure the current working solution can be improved a lot &#8211; simplified with fewer lines of code, based on the much more robust and tested code base, and given a basic test script to make sure the code works somewhere else, outside of a particular client&#8217;s setup.<\/p>\n<p>I wish I came across that all much earlier.<\/p>\n<p>&nbsp;<\/p>\n<!-- google_ad_section_end -->\n","protected":false},"excerpt":{"rendered":"<!-- google_ad_section_start -->\n<p>Disclaimer: I am not the biggest fan of Microsoft. \u00a0On the contrary. \u00a0I keep running into situations, where Microsoft technologies are a constant source of pain. \u00a0If that annoys you, please stop reading this post now and go away. \u00a0I don&#8217;t care. \u00a0You&#8217;ve been warned. A few recent projects that I&#8217;ve been working on in &hellip; <a href=\"https:\/\/mamchenkov.net\/wordpress\/2016\/12\/11\/php-microsoft-office-365-and-active-directory\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">PHP : Microsoft Office 365 and Active Directory<\/span><\/a><\/p>\n<!-- google_ad_section_end -->\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"PHP : Microsoft Office 365 and Active Directory #PHP #WebDev #Microsoft #Office365 #AD #ActiveDirectory #SSO #security #auth","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_links_to":"","_links_to_target":""},"categories":[1,18,62,1334],"tags":[3469,1264,10,3381,38,200,3474,1330],"keyring_services":[],"class_list":["post-27100","post","type-post","status-publish","format-standard","hentry","category-general","category-programming","category-technology","category-web-work","tag-active-directory","tag-integration","tag-ldap","tag-microsoft-office-365","tag-php","tag-security","tag-single-sign-on","tag-web-development"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":24834,"url":"https:\/\/mamchenkov.net\/wordpress\/2015\/10\/12\/office-365-lync-online-srv-dns-records-on-amazon-route-53\/","url_meta":{"origin":27100,"position":0},"title":"Office 365 Lync Online SRV DNS records on Amazon Route 53","author":"Leonid Mamchenkov","date":"October 12, 2015","format":false,"excerpt":"One of the very few things we still rely on from Microsoft at work is Office 365. \u00a0Not because it is so great, but because I simply didn't have the time to move away yet (quiet Christmas season is coming soon). \u00a0Most people don't get exposed much to it anyway,\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":162,"url":"https:\/\/mamchenkov.net\/wordpress\/2003\/03\/16\/microsoft-weekend\/","url_meta":{"origin":27100,"position":1},"title":"Microsoft weekend","author":"Leonid Mamchenkov","date":"March 16, 2003","format":false,"excerpt":"Heh, one of those office Sundays. Our MS Exchange admin screwed up Active Directory a bit, so few of us spent a day in the office trying to fix it. No luck, until another expert came from Nicosia. Even he agreed afterwards that simplicity in Unix design is attractive and\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":28522,"url":"https:\/\/mamchenkov.net\/wordpress\/2018\/04\/25\/understanding-ad-access-control-entries\/","url_meta":{"origin":27100,"position":2},"title":"Understanding AD Access Control Entries","author":"Leonid Mamchenkov","date":"April 25, 2018","format":false,"excerpt":"\"Understanding AD Access Control Entries\" is a quick and simple article describing some of the madness of the Active Directory access control entities.\u00a0 This is particularly useful for those of us who had to deal with Active Directory, without having much experience with MS Windows.\u00a0 I'm sure this will come\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6,"url":"https:\/\/mamchenkov.net\/wordpress\/2001\/11\/09\/microsoft-ldap\/","url_meta":{"origin":27100,"position":3},"title":"Microsoft LDAP","author":"Leonid Mamchenkov","date":"November 9, 2001","format":false,"excerpt":"LDAP saga continues... Finally I have found something that Microsoft did actually good. I have found out that ldifde.exe -f myfile.ldf will export the whole Active Directory structure into myfile.ldf file in LDIF file format (human readable). That is extremely usefull when migrating I have also found Exchange-HOWTO an interesting\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":37373,"url":"https:\/\/mamchenkov.net\/wordpress\/2019\/03\/07\/cloud-irregular-iam-is-the-real-cloud-lock-in\/","url_meta":{"origin":27100,"position":4},"title":"Cloud Irregular: IAM Is The Real Cloud Lock-In","author":"Leonid Mamchenkov","date":"March 7, 2019","format":false,"excerpt":"Vendor lock-in is an old and well discussed issue. Some people don't care about it all, jump right in. Others avoid it like a plague. And then there are those who allow it, with some very careful considerations. I have always been on the side of avoiding vendor lock-in by\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":24831,"url":"https:\/\/mamchenkov.net\/wordpress\/2015\/10\/12\/continuous-integration-servers\/","url_meta":{"origin":27100,"position":5},"title":"Continuous Integration Servers","author":"Leonid Mamchenkov","date":"October 12, 2015","format":false,"excerpt":"Here's a list of Continuous Integration (CI) servers \/ solutions for those who is still trying to choose: Travis CI CircleCI Jenkins CI Atlassian Bamboo JetBrains TeamCity Microsoft Team Foundation Server Microsoft Visual Studio Online CI GitLab CI Codeship Drone.io Buildkite Via volkswagen.","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"build results","src":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2015\/10\/build-results-500x308.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts\/27100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/comments?post=27100"}],"version-history":[{"count":0,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts\/27100\/revisions"}],"wp:attachment":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/media?parent=27100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/categories?post=27100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/tags?post=27100"},{"taxonomy":"keyring_services","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/keyring_services?post=27100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}