Security & Identity

Automate Accounts for Azure AD

Azure AD’s B2B capability is a really powerful way to leverage identities from outside of an organization, but is it the right solution for seasonal, temporary, or white listed employees?  Maybe, maybe not, and if not then the creation of cloud only accounts may require a time consuming (possibly manual) request > approval > provision process.

Recently I had a customer that asked how we could automate an account provisioning processes that allow for a request, an approval workflow, automated account provisioning, association of the account with a ‘manager’, an automated actions if the ‘manager’ departed, and time boxing of the account.  In order to minimize development and utilize as much Out of the Box as I could I turned to Flow.

Start with SharePoint

So this is the benefit of experience: I actually started with Flow and discovered the template for Flow, SharePoint, and Azure AD.  Because I started with Flow I didn’t think about what data I wanted to capture first, I just wanted to get accounts creating and would add fields as I needed them.  This lead to some issues, probably because I’m impatient, between adding field and having those available in Flow.  Therefore, I recommend YOU think about the information you need to capture from a user, build your SharePoint list and then proceed.

I decided that I would create a new site for tracking requests and host my request list in this location.  In a real world environment this would allow an organization to have a single account request location which I viewed as valuable.

I created a list as shown below (Title will be used as the last name)

SP List

All fields are Single Line of Text except for Review Status which is a Choice field with Pending, Approved, Rejected as the options with Pending as the Default value.

Create your workflow with Flow

I am by no means a Flow expert, thanks to this demo I learned a little bit, but I really needed a simple place to start.  Fortunately, if you go to Flow select Templates and Search for Azure AD the second template is Create Azure AD User from SharePoint List.

Flow Templates

Once the flow is generated you need to update the first action with your SharePoint site Url and list name.

Flow Item Created

You can skip the second action as this will generate a random password for the account.

Next, you need to update the Create User step based on the fields you created in your list.  You can also use Expressions to customize the values you want to use when creating the user.  For example I use the following to create a username:

concat(triggerbody()['FirstName'], '.', triggerbody()['Title'], '')

Flow Create User You will also notice that I’ve clicked on the Show advanced options and updated the Business Phone, Department, Job Title, Mobile Phone, Office Location, and Preferred Language.

Account creation will fail if Preferred Language does not meet the specific format.  Business Phone can be an empty array, but cannot accept a null value.
eg. [] – ok
[null] – failure

Next, update the Update item action to set the current item’s ReviewStatus value to Approved.  You will also notice the IsComplete field with a value of true, this field needs to be added to your SharePoint list or else the Update item action will fail.

Flow Update Item.png

Finally, update the Send an email action to utilize the values captured from the list.

Flow Send Email.png

Now you should be able to test you Flow by creating an item in the SharePoint list and observe the execution of your flow, and if there are errors then you can perform troubleshooting and resubmit.

Flow Runs

Add the Review

Now that the creation process is working update the flow to include the actual review phase and condition handling. Add the Start and wait for an approval (v2) action to your flow AFTER the Initialize variable step and configure it as shown.

The Initialize Variable cannot happen within the Condition portion of the workflow, so you may as well initialize this immediately after the flow starts.

Flow Wait for Approval

Next, add a Condition action to your flow.  Update the Condition to use the Outcome of the Start and wait for an approval outcome to be equal to ‘Approve’.

Flow Condition

Finally, move (yes drag and drop does work) the Create User, Update Item, and Send an email actions into the If yes segment of the workflow. You should also add a Send an email to the If no segment of the workflow and send the user a notification that their request has been rejected.

Flow Condition Branches

I recommend testing again to make sure your approval process works as expected, and be sure to test both the Approve and Reject.

Collect Requests with Forms

Now that our flow works we need to set up a way for people to submit requests to be reviewed and approved/rejected.  Microsoft Forms is a simple way to create the request form you need and allow it to be shared outside of your organization.

Creating a Form is really easy so I won’t provide the full details, but create a new Form that captures the same information that the SharePoint list stores.  Don’t include the workflow type fields like Approval status and IsComplete field of course.  Here is an example of the Form I created.

Form Example

As you can see I provided friendly names for each of the user input fields and marked everything as required.

Now you need to allow this Form to be accessed by anyone with the link.  To do this click on the Share button in the upper right of the browser window and select the Anyone with the link can respond.  This will allow you to copy the URL and send it to any external participants.

Form Share

Tie this all together

The final part is to pull our Form submission into our SharePoint list, and again we go back to Flow for this and use an existing Template.

Form Flow

After creating the new Flow from the Template you need to customize the When a new response is submitted Action and select the form you just created.

Form Flow New Response

In the Apply to each action update the Get response details and select the form you created.

Form Get response details.png

Finally, update the Create item by selecting the Site Address and List Name, then expand the Advanced Options so that all the fields from your list display.

Form Create Item

Save your flow, and go test your solution from Flow to Account Creation.

Wrapping Up

You should now be able to share your Form with people outside of your organization, have them submit the form, record the entry in SharePoint and have the Approval process kick off and the account creation be performed.

There are lots of Flow templates and clearly the Approval process doesn’t specifically require SharePoint to store the item, so there are probably hundreds of ways to approach this problem.  However, I like this method because I can see the data move from Forms to SharePoint to Azure AD and creating tracking and report solutions are easy.

Incorporate Azure AD with your Angular App

I began my career as a software developer and I still love the opportunity to tinker with code from time to time.  Since I usually deal with authentication and identity I have a need from time to time to demonstrate how customers can add their own custom applications to Azure AD and how the protections can be applied.  So, I spent a few days recently building and testing my own, single page, custom application based on the latest version of Angular (Typescript).

While I could detail what I did to get the project working, it is probably easier to provide the various links I used to learn Angular as well as the libraries I used and added to get the project working.

Getting Going

Since I had ZERO experience with Typescript and the latest TS Angular I started with the Tour of Heroes tutorial.

Second, I was able to find the Angular-MSAL library available here on Github.  I recommend going here so you can read the friendly documentation, but use ‘npm install @azure/msal-angular’ to add this to your development project.

Third, I followed these directions to register my application in Azure AD.

Finally, I used the sample application found here to make my application.  This is where I found the most trouble so below I’ll focus on some of the issues I had.

Issues I Had

The first issue I ran into was that every time I logged in I would get an error about lacking some api permissions.  Searching for the error didn’t provide really relevant information so I started to eliminate as much as I could.  What I discovered was that during the  LoginPopup call the Sample code I copied and pased into my app include ‘api://a88bb933-319c-41b5-9f04-eff36d985612/access_as_user’ which is unnecessary for Login and user queries so I removed it.

The second issue I ran into was that the MsalService.getAllUsers() only returned my local user’s information, which is actually documented, but I wanted that ability.  Instead I had to call directly against the Graph services to get that information which you can find my solution here.

My App

If you are interested here is the app I created.  Yes there are still some issues which I’m working on, but it may be an easier starting point for others.


The Identity stupid!

James Carville’s campaign strategy for Bill Clinton’s ’92 campaign was “The economy, stupid!” These 3 words left no doubt to what was important, what to focus on, and the fact that getting the Economy right would make everything else possible.  Today, as we look at changes to the corporate IT network and infrastructure we should adopt a similar slogan:

The Identity, stupid!

Identity is a core enabler of modern solutions be they Collaboration, Security, from IaaS to PaaS.  Companies in the past could rely on physical controls to secure information, but today Cloud and the interconnectedness of businesses has destroyed those controls. So where does this leave us in a world where we don’t control where information is accessed from, by what devices, or where the information is stored? We are left with one truth, unique to everyone and applicable to devices and data: Identity.

The funny think is, we’ve known identity has been important for a long time. If you ever took a class on journalism the first thing they taught was the mantra “Who, What, When, Where, Why.” When you log into your computer today the first thing it asks you is: Who are you? When you go to buy a car, boat, or house you have to tell them is who you are.  You even have to tell the barista at Starbucks who you are!

Identity is important, so protect it!

Identity is the control mechanism today for enabling technology, if you secure the identity you’ve gone a long way to securing your systems and your data.  Here are some methods to improve your organization’s identity strength without hampering their ability to do work.

Update your password policy

Recently even NIST updated their password policy (Section to reduce the artificial complexity rules, changes passwords only when suspected of compromise, and perform checks against ‘dirty words’ and previously compromised passwords. At Microsoft the use of ‘Seattle’, and ‘Seahawks’ are rumored to be banned (I wouldn’t know because I don’t live in Seattle and I’m not a Seahawks fan).

Beyond these recommendations think Passphrase not Password.  The longer the password the more difficult it is to guess so brute force and dictionary attacks are less likely to be successful.

All of these policies are easy to implement, prohibited words/phrases, detection of compromised passwords, and password length controls, and even self service password resets are built into Azure Active Directory.  Azure Active Directory can become the central hub for password management with the ability to synchronization changes to your on-premise systems.

Enable MFA

I wrote about this in another post, but seriously if you have any admin accounts that don’t have MFA enabled stop reading this and go GO TURN IT ON NOW!

MFA is one of the simplest solutions to interrupt account compromises, and it has become more common for users because it is used in Banking Apps, Commercial Email, and even Facebook recommends your account be protected with MFA.  At Microsoft we see a decrease in account compromises by over 99%.  Clearly, this is the first step in enhancing the security of your identities.  This is already included in O365 E3 or Azure Premium licenses and enabling it is just a few checkboxes, so there really is NO EXCUSE!

Use data

Monitoring accounts is critical, but there is a lot of information about what is happening in the world, like Dark Web sale of Credentials, that may not show up in your organization’s monitoring of accounts. However, a service like Azure Active Directory which is used by millions of user accounts daily gets lots of insight not only about your accounts but from all accounts, so when an attack is detected everywhere everyone can benefit from awareness and steps taken to block this type of attack.

Use AI and ML

Along with information about what is happening globally around authentications, it is also important to understand what is ‘normal’ and what is ‘abnormal’ for your users.  If users sign in Monday-Friday between 9am and 5pm for 15 years then your identity system should recognize that a sign in on Saturday at 2:30am is abnormal.  In this scenario the system may require extra identity validation (MFA), block the login attempt, or alert your other security monitoring tools and personnel.  This capability is part of the Azure Active Directory Conditional Access which natively learns user behavior patters and can dynamically adapt the authentication experience based on user behavior patterns.

Change Written Policy to Automated Action

If you want to protect identities, really if you want to protect anything these days, then you need to take written policies and automate them in your identity system.  A written policy like “If a password is compromised require a user to change it” requires a user to be notified and then for them to take action.  Instead, your Identity tools should be able to detect the credential compromise and require a password reset (with MFA validation) on the next login attempt.  In Azure Active Directory this can be done with Identity Protection policies, so if a user’s authentication event appears risky then flag the account for a password reset.

Loose the Password

I mention this one last because a Zero Password World isn’t quite there for everyone, but we are close.  With Windows Hello and the Microsoft Azure Authenticator app we are moving closer and closer.  Personally I don’t have a password for any of my Microsoft consumer accounts (Hotmail, OneDrive, etc.) and I very seldom use a password when accessing my Microsoft corporate resources.  Actually, one the rare occasion I am prompted for a password I usually have to perform a Self Service Password reset, because I honestly don’t remember it.

Azure Active Directory has added this ability, but it is currently in Preview (maybe even Private Preview) so customers have to opt it to enabling the capability, but this is coming and I predict by the end of 2019 this capability will be readily and easily available to customers.

The Identity, Stupid!

It is time for us to focus on what is most important to the success of modern IT, both for usability and security, and it is all about Who!  Like the 90’s campaign use this motto/mantra/whatever you want to call it to help you focus on The Identity, Stupid!  If you get Identity right you can make everything else happen.

Azure AD MFA managed by User Account Administrator Role

Many organizations want to delegate enabling and disabling MFA for a user to their helpdesk, but the only RBAC role that allows MFA management is the Global Administrator and no one wants to grant helpdesk technicians Global Admin access to their tenant.  However, there is a way around this RBAC limitation if your organization has Azure AD Premium.

General Concept

At a high level enabling and disabling MFA will be managed by adding and removing users from a security group.  The security group will be included in a Conditional Access policy which defines the MFA requirements.



  1. Admin with Conditional Access administrator role
  2. Helpdesk user(s) with User Administrator role assigned


Have a Helpdesk user create a security group in Azure Active Directory and assign the users your organization wants to require MFA when accessing applications.  Make sure to include a descriptive name like MFA Required Users.


Next, have the Conditional Access Admin create a new Conditional Access rule with Assignments target set to the group created by the Helpdesk user.


Next, select the Cloud apps you want to require MFA before allowing access, or select All Cloud Apps.


Next, choose the option to Grant Access and check Require multi-factor authentication.


Finally, Enable the policy and choose Create.



Now, when the Helpdesk (someone with User Administrator Role) needs to enable or disable MFA for a user all they need to do is add (Enable MFA) or remove (Disable MFA) the user from your MFA Security Group.

O365 MFA vs Azure AD MFA

As a Technical Solutions Professional at Microsoft who covers Identity and Security I get a lot of questions about Office 365 MFA vs. Azure Active Directory MFA around the differences, benefits, and what I suggest.  Customers always assume because I concentrate on the EMS stack Microsoft offers (Intune, Azure AD, Azure Information Protection) I recommend Azure AD MFA over Office 365 MFA, but the reality is when customers really compare the experiences they will almost always go with Azure AD MFA.

Before we talk about Office 365 vs Azure AD MFA let me make this position perfectly clear.

Use MFA! If you are not using, or haven’t implemented, MFA stop reading and GO TURN IT ON especially for your Administrator accounts.

Why?  We, Microsoft, find that by enabling MFA on your accounts the your organization will reduce account compromise by OVER 99%!

Office 365 MFA

Office 365 E3, and up, subscriptions entitle an organization to enable Multi Factor Authentication for their users who will be accessing O365 resources (SharePoint, OneDrive, Office Pro Plus, etc.).  When a user is entitled and enabled to use MFA they have three (3) options:

  1. Azure Authenticator App
  2. Text Message
  3. Phone Call + PIN

To enable Office 365 MFA you must turn the feature on for each user individually (user-by-user), and once MFA is required for the user, it is always required for the user.  Therefore, when a user is authenticating to O365 resources from their work computer or home computer using Office or browser, they will be prompted for MFA verification.

Azure AD MFA

Azure AD MFA is available for organizations that purchase Azure AD Premium P1, or P2, licenses for their users and this Multi Factor Authentication solution can be use with Office 365, Azure, On-Premise applications, third party applications (SaaS), and custom built Line of Business applications.  Like the O365 MFA offering Azure AD MFA provides three (3) ‘native’ options:

  1. Azure Authenticator App
  2. Text Message
  3. Phone Call + PIN

Azure AD also offers customers the ability to use 3rd party MFA providers including the following:

  1. RSA
  2. DUO
  3. Trusona
  4. (More to come)

This additional integration with 3rd party MFA providers means that any existing investment in MFA can continue to be leveraged and we can provide MFA support even in locations where mobile or office phone access is limited or prohibited.

The way an organization applies MFA with Azure AD is also different than Office 365.  When applying MFA with Azure AD an organization does so by creating Conditional Access (CA) rules.  CA rules for MFA can be very simple:

All Users + All App + MFA = Grant Access

Basically this is what the Office 365 MFA solution provides, but limited to O365 apps that is.  However, CA can do much better, it can actually allow you to address questions and policies intelligently:

  • Why prompt for MFA when a user is connecting from a corporate network and is using a corporate device?
  • Why prompt for MFA when a user is connecting to their time card the same way you would if they were connecting to the corporate account line of business application?
  • Why MFA everyone all the time, can we target specific users when they are accessing accessing sensitive information?

Using CA to drive MFA also allows your organization to integrate MFA easily with Windows Always-On VPN solutions.  Now not only do you protect a user when their app connects to a service, but you protect your corporate network when an endpoint device connects and its all managed with the same CA, MFA, and identities.

What drive Azure AD MFA over Office 365 MFA

I find most organizations choose Azure AD MFA over Office 365 MFA for one of these two reasons:

  1. They already invested in an MFA solution, maybe RSA, so the users know it, IT trusts it, and they can continue to use it.
  2. They don’t have to use an All-Or-Nothing approach, they can apply a Who-What-When-Where approach to their MFA policy and only require MFA when necessary.

To me, the greatest benefit of Azure AD MFA is the ability to target MFA scenarios.  I’ve seen many customers push MFA for everyone all the time, and within a short period of time they turn it off because “there was too much prompting”

ECTS Extension Released

I am happy to announce the release of our ECTS Extensions to CodePlex. This extension provides a bit of a performance boost especially to the User Management capability in ECTS.
ECTS provides a forms based authentication schema for SharePoint that leverages ADAM so you can allow external people access to your SharePoint to enable collaboration. With these extensions you can now allow external users to request accounts as well as manage the accounts in a more friendly UI.

How many users can ECTS Handle?

How many users can ECTS Handle?


This has become a common question for a couple of my clients, to which I really don’t have a good answer. However, with my clients we have found significant issues when attempting to use the User Manager web part in ECTS when we have 100+ users. In fact, recently the client has had to go to using the ECTS login so they can manage the users because the Active Directory times out before the page loads.


Therefore my best answer right now is: Not many.


While that is my current answer, that is not the final answer. I have recently been working on a series of web parts to replace the default ECTS web parts. The goal is to make fast loading and easy to use web parts, which means sacrificing some of the custom call backs in favor of just displaying the hidden capabilities when the page is loaded.


If interested here are a couple of screen shot on how this looks.


ECTS User Manager


    ECTS External User Manager

This web part actually shows all of the users in ADAM. When you click on the Take Action button on the far right this is what you get.

    ECTS External User Take Action


My ECTS Enhanced User Manager


    MY User Manager

This is actually two web parts, the a | b | c |… is a connection provider which controls what CNs are searched for. This could be adapted to have a more, or less, capable filtering mechanism. Notice that the Reset Password, Toggle Enabled State and Delete are all exposed immediately. This prevents us from having to recreate the list of ADAM users every time the web part is loaded, and with the filter web part we now are able to reduce our search result set to a more manageable size. I have dropped the Modify capability in the current version, in the future I will add another connectable web part that will allow for editing of the selected user.


One difference in my version is that when a password is reset the user’s who’s password was reset receives an e-mail with the new password. I’m not sure if ECTS is supposed to do this as well, but from my experience, I have never received an e-mail when the password was reset other than that sent manually by the help desk personnel.


My ECTS Enhanced User Approval

    My User Approval Part


Here you will notice that the Requestor has been dropped from the default ECTS User Approval Web Part (not pictured).


One of the key changes I have made is to use the SPUtility.SendEmail(…) rather than the crazy database settings that ECTS has used. This provides several advantages, but most of all we can see if the send succeeded or failed. If it fails we can prompt the user to manually send information like passwords to the user proactively rather than waiting for the user to again request a password reset or, worse, leave and never come back. One of the biggest issues I have seen is that once an account gets approved the approval e-mail does not get sent to the user and they never receive a password. This then requires the site support team to use the User Manger, which can time out easily, to reset the password and e-mail it to the user.


The other major advantage is you don’t have to manage three different locations where the SMTP settings are kept, currently ECTS stores these in the web.config, the ECTS database, and they are stored in SharePoint’s SMTP settings.

ECTS Post Installation Issue

So I have had the opportunity to go back and work on the ECTS enabled system I worked on earlier this year for DoD. Sadly in my preparation for creating a new site I began working in my ECTS Virtual Machine, but in my haste one day I removed the external USB HD the VM is located on and corrupted the entire VM. As it turns out this has been a nice refresher in installing ECTS and I have found some new issues to write about.


Ok, so after installing ECTS on the system, which had a fresh installations of SQL Server Dev 2005, MOSS EE 2007, Visual Studio 2008, .NET Framework 3.5 I was able to install ECTS successfully without issue. Using my certificate authority installed on the VM I created the Cert for the ECTS ADAM communication and checked to ensure it was working. Finally, I extended my "internal" site so I would have an "external" forms authentication site. Next step was to check the "external" site to ensure it was configured correctly, and I was immediately redirected to the login page where I got the standard "Unknown Error" MOSS page.


Since I had the generic error, I updated the web.config to allow the callstack to display and turned off the custom errors. I then accessed the login page again and had the following error:


The resource object with key ‘loginPageTitleInTitleArea’ was not found. at System.Web.Compilation.ResourceExpressionBuilder.ParseExpression(String expression, Type propertyType, ExpressionBuilderContext context)

at System.Web.UI.BoundPropertyEntry.ParseExpression(ExpressionBuilderContext context)

at System.Web.UI.ControlBuilder.FillUpBoundPropertyEntry(BoundPropertyEntry entry, String name)

at System.Web.UI.ControlBuilder.AddBoundProperty(String filter, String name, String expressionPrefix, String expression, ExpressionBuilder expressionBuilder, Object parsedExpressionData, Boolean generated, String fieldName, String formatString, Boolean twoWayBound)

at System.Web.UI.ControlBuilder.PreprocessAttribute(String filter, String attribname, String attribvalue, Boolean mainDirectiveMode)

at System.Web.UI.ControlBuilder.PreprocessAttributes(ParsedAttributeCollection attribs)

at System.Web.UI.ControlBuilder.Init(TemplateParser parser, ControlBuilder parentBuilder, Type type, String tagName, String id, IDictionary attribs)

at System.Web.UI.ControlBuilder.CreateBuilderFromType(TemplateParser parser, ControlBuilder parentBuilder, Type type, String tagName, String id, IDictionary attribs, Int32 line, String sourceFileName)

at System.Web.UI.ControlBuilder.CreateChildBuilder(String filter, String tagName, IDictionary attribs, TemplateParser parser, ControlBuilder parentBuilder, String id, Int32 line, VirtualPath virtualPath, Type& childType, Boolean defaultProperty)

at System.Web.UI.TemplateParser.ProcessBeginTag(Match match, String inputText)

at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding)


Ok, so the first thing I noticed was the statement about a "resource object" which is a tell tail sign some .resx file did not get deployed.


RESX File’s in your Solution

RESX files (.resx) usually get deployed to your site’s app_globalresources folder, so if a resource object is missing then it’s a good idea to look there to ensure your resx file was deployed.


Next step was to determine what resx file was missing, so I went to the folder, typically you’re My Documents folder, that has the ECTS installer (ECTSSetupWizard.hta). In that folder is also the ECTSSolution.wsp file, which is really just a renamed .cab file. So I copied the ECTSSolution.wsp to and then opened the cab, inside there are 3 resx files. I initially copied all three to the "internal" and "external" site app_globalresources folders, however you should only have to copy the ExternalCollaboration.resx file to resolve the problem above.


After copying the files to the app_globalresource I refreshed the login page, and happly ever after it has worked.