Configure ADFS to work externally without having a WAP Server (configure Azure app proxy to publish ADFS externally)

Overview:

Screenshot 2022-05-27 141620

Azure Application proxy provides single sign-on (SSO) and secure remote access for web applications hosted on-premises environments without complexities. This makes your life easier as you won’t need those complicated reverse proxies or Web Application proxies (WAP) that are usually sit in the DMZ.

Objective:

In this scenario, the idea is to guide you through on how to publish ADFS service externally so that users can access your applications outside of the internal network. This will also be beneficial for public user scenario such as Azure AD users and Azure B2B. The known approach to publish ADFS externally is “to have a Web Application Proxy” server configured in DMZ but that’s very time consuming and over complicated for basic requirements (unless you have specific needs to depend on WAP or Reverse proxy).

This post assumes that you have an ADFS server/s configured and in the running conditions as we won’t be going through that part of the configuration on this one.

Prerequisites:

  • Active directory domain and DNS configured in your on-premise environment
  • ADFS Server installed, configured and running
  • Verifiable public domain name (i.e. mscloudjournal.com)
  • Public SSL certificate binding is done in the ADFS server
  • Azure tenancy with Azure AD Premium P1 or P2 license

Step1: Download and install proxy connector in the desired server

First thing is first, let’s download the proxy connector tool from Azure. Simply login to your Azure tenancy and navigate to Azure Active Directory –> Application Proxy –> Hit that nice little button to download the latest version of the tool.

Copy across this to your ADFS server (or any desired server that you’re planning to run this connector. You do not need a dedicated server for this as it’s a very lightweight service).

image

Once copied across to the desired server (ADFS server itself in this case), run the tool to begin the process.

image

Next, you’ll be prompted to sign in to Azure AD. Make sure you have appropriate privileges to run this operation in Azure AD.

image

It won’t take more than a couple of minutes.

image

And there we have the greenlight. Simply close this wizard now and switch back to Azure AD.

image

Hit refresh and you’ll notice our brand new connector is now up and running in Azure. And we also have a public IP assigned to it by Azure.

image

Step2: Configure an App in Azure

Now to configure an app using the option given in the top ribbon. Hit “Configure an app” to begin.

image

image

Input the details below to suit your environment’s naming. Choose “Passthrough” for Pre-authentication method and the rest can be defaults unless you have a specific need.

image

And that’s it! our new on-premises application is created successfully.

image

Step3: Adding the DNS CNAME record

Now we need a DNS record to point the traffic to Azure App Proxy service endpoint. This is done in the DNS repository so you’ll need the access to your domain’s hosting provider (i.e. Godaddy) to add a DNS pointing record.

image

The record will look something like this. Point to needs to be the address we saw in Azure ending with “msappproxy.net” (this is the proxy service endpoint for Azure). Add a new CNAME record as shown below and amend the naming to suit your record.

image

Step4: Binding the exported certificate

Now lets head over to “Enterprise Applications” –> All applications –> select the app one we created in the previous step (ADFS External Publishing Proxy) –> Application Proxy.

image

Here you get the certificate upload option. This certificate is taken from the ADFS server. Follow the next step to obtain this from the server.

image

Export the certificate from the ADFS server

Login to your relevant on-premises server (ADFS server in my case) and open mmc (type “mmc” in the run command and enter) and add the certificate snap-in to the mmc console.

image

Chose the right certificate that binds to the ADFS service URL and right click –> All tasks –> Export

image

image

You need both certificate + the private key so export it from the certificate export wizard in the server itself.

image

image

image

Choose “AES256-SHA256” for encryption and check the password option to enter a password.

image

Give the cert a name and save it in a secure space. We will upload this to the app we created in Azure, next.

image

Now lets switch back to Azure AD –> Enterprise Applications –> All applications –> select the app one we created in the previous step (ADFS External Publishing Proxy) –> Application Proxy.

Scroll down and click on the option that allows you to upload the certificate.

image

Chose the file we exported (.pfx) and input the same password specified when exporting it –> hit upload.

image

It should like below if everything went well.

image

image

And, that’s it ! we should now be able to test it out.

Step5: Testing the external accessibility

To test it, simply try to access the ADFS signon URL from a external network and if you can see the following screen with a validated certificate, you’re all done !

https://adfs.yourdomain.com/adfs/ls/idpinitiatedsignon

image

Azure AD Error: AADSTS700016 Application with identifier was not found in the directory

I recently had the chance to work on Azure B2B access integration with ADFS (SAML consumed by SaaS applications) and this post is inspired by the quick fix applied to an issue I encountered in the middle of the process. Although this may look obvious in technical point of view, I’m quite certain that someone will find this handy and could save hours of troubleshooting.

Mac-102-error-1200x900

When a B2B user (AAD registered guest) tries to access the ADFS signon URL (https://adfs.yourdomain.com/adfs/ls/idpinitiatedsignon), the following error received. I had the Azure AD App registered and configured to work with ADFS but, the error makes perfect sense here. It clearly says that “the application ID did not match the URN that was generated by ADFS.


“AADSTS700016: Application with identifier ‘<URN>’ was not found in the directory ‘<Tenant Id>’. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant”

Screenshot 2022-05-28 235054

The Uniform Resource Name (URN) is a unique identifier assigned to our Enterprise SAML connection. This value is labelled as ‘”Federation service Identifier” in the ADFS server Federation service properties which is easy to find. The URN value apparently needs to be assigned to the App Registration.

ADFS Server –> Edit Federation Service Properties

Screenshot 2022-05-29 003839

To access the APP ID, select the Add an Application ID URI option in the Azure App.

Screenshot 2022-05-29 004046

Screenshot 2022-05-29 002752

Set the URN copied from the ADFS service properties. This is usually “HTTP”, not HTTPS.

Screenshot 2022-05-29 004110

No changes to the “Redirect URIs. Leave it with the IDPInitiatedSignOn page and hit save to apply the change.

Screenshot 2022-05-29 004130

And that’s it ! Azure App is now linked correctly with the ADFS service endpoint.

Windows unquoted service path enumeration vulnerability-Is this still a concern?

A bit of background:

‘Windows Unquoted Path Enumeration vulnerability’ was identified few years ago and most applications have released multiple versions after identifying this issue however, this is still worth verifying regularly which apparently where this article comes from.

vuln-scanning

In simple terms, when a service is created whose executable path contains spaces and isn’t enclosed within quotes, leads to a potential vulnerability called ‘Unquoted Service Path’ which allows a general user to gain SYSTEM privileges (only if the vulnerable service is running with SYSTEM privilege level which most of the time is the case). In Microsoft Windows, if the service is not enclosed within quotes (“”) and is having spaces, it would handle the space as a break and pass the rest of the service path as an argument. Apparently, this vulnerability allows an attacker to escalate the privilege for NT AUTHORITY/SYSTEM for a low-level privilege user account which is extremely dangerous.

How to replicate/test this vulnerability:

<

p align=”justify”>You can easily recognize this by running a script that I have pointed out below but additionally, if you’re keen to try this in a test environment, you can download one of the applications listed in the CWE ID 428.

https://www.cvedetails.com/vulnerability-list/cweid-428/vulnerabilities.html

image

One of the sample app we can use to test this in a test (isolated) environment is, ‘BitComet’. BitComet Service for Windows before version 1.8.6 contains an unquoted service path vulnerability which allows attackers to escalate privileges to the system level.

After Installing BitComet v.1.7 for test in my test lab:

As you can see below, the ImagePath in the registry (run “regedit” from the run command) is clearly unquoted and it means this app makes the device/environment vulnerable to a potential hacker.

clip_image002Actions/Recommendations: As there is no simple patch/fix from Microsoft to fix these kind of vulnerabilities, the best way is to regularly analyse the devices (or asses every 3rd party application before onboard them in to the corporate environment) to ensure they’re not compromised. A group of Github contributors have done a fantastic job putting together a PowerShell script that analyse, detect and fix these paths in your Windows devices if there’s any.

https://github.com/VectorBCO/windows-path-enumerate/

After applying the fix: I simply ran the script above and voila ! the path got fixed and is now appears quoted.

clip_image004

Enabling Teams Meeting report download capability

Meetings in Teams is one of the most popular functionality that being used by millions across the world. The ability to download reports for meeting attendance would be very useful for meeting organizers to view the attendance of the meeting/s. In the recent Teams update, Microsoft added this functionality to Teams, but it is disabled by default, and you will not be able to use it out-of-the-box unless you enable it (for everyone or a specific target group). This post will guide you to get this done.

meetingatt

Note: There’s a still a limitation to this where you can’t download the report after the meeting ended. You will have to download it while participants are still in the meeting.

Steps:

  1. Log in to Teams admin centre meeting policies blade and create a new policy using the ‘+’ sign – https://admin.teams.microsoft.com/policies/meetings

Policy Title – MeetingPolicy_ReportsEnabled

Description – Meeting policy with reports download feature enabled

General

Allow Meet now in channels – On

Allow the Outlook add-in – On

Allow channel meeting scheduling – On

Allow scheduling private meetings – On

Audio Video

Allow transcription – On

Allow cloud recording – On

Mode for IP audio – Outgoing and incoming audio enabled

Mode for IP video – Outgoing and incoming video enabled

Allow IP video – On

Allow NDI streaming – Off

Media bit rate (Kbs) – 50000

Content sharing

Screen sharing mode – Entire Screen

Allow a participant to give or request control – On

Allow an external participant to give or request control – On

Allow PowerPoint sharing – On

Allow whiteboard – On

Allow shared notes – On

Participants and Guests

Let anonymous people start a meeting – off

Roles that have presenter rights in meetings – Everyone, but user can override

Automatically admit people – Everyone

Allow dial-in users to bypass the lobby – On

Allow Meet now in private meetings – On

Enable live captions – Disabled but the user can override

Allow chat in meetings – Enabled

Hit save to apply the changes

  1. Then enable the Meeting reports feature, run the following commands in PowerShell (this requires admin access)

$sfbSession = New-CsOnlineSession

Import-PSSession $sfbSession

Set-CsTeamsMeetingPolicy -Identity “MeetingPolicy_ReportsEnabled” -AllowEngagementReport Enabled

Use this command to verify the settings. Ensure the AllowEngagementReport parameter value is “Enabled”

Get-CsTeamsMeetingPolicy -Identity “MeetingPolicy_ReportsEnabled”

  1. Finally set this policy to the intended users manually by going to each users Teams profile –> Edit the Meeting Policy for the user –> Change the policy asignment to the new Policy just created (MeetingPolicy_ReportsEnabled) and hit “Save”

Edit user policies 
Meeting policy 
Meeting Policy_ReportsEnabled

During the meeting, you’ll see the following option to download under the “People” section.

image

Provisioning bulk distribution lists

Its ideal to avoid distribution lists wherever possible and adopt Microsoft 365 groups instead however, we can’t apply it for every scenario as DLs are still very useful and in some cases the only option you have. This post will showcase the steps to provision DLs in bulk (in Exchange Online)

Steps:

1. Create a 3 column simple CSV file as shown below and save it locally in your PC as “DL_Pilot.csv”

Name 
Incidents 
Incidents 
Incidents 
Incidents 
AU_Group1 
AU_Group2 
AU_Group3 
AU 
Group4 
Type 
Distribution 
Distribution 
Distribution 
Distribution 
Email 
Incidents 
Incidents 
Incidents 
Incidents 
AU 
AU 
AU 
AU 
Groupl@mantasa.live 
Graup2@mantasa.live 
Graupa@mantasa.live 
Graup4@mantasa.live

2. Login to Exchange online PowerShell module

Connect-ExchangeOnline

3. Run the following command (set the location to match yours) and point the path to your previously created CSV file.

Import-CSV “C:\Official\Mantoso\DL_Pilot.csv” | foreach {New-DistributionGroup -Name $.name -Type $.Type -PrimarySmtpAddress $_.email}

That’s it. It’ll simply provision the DLs defined in the the CSV (sample below)

DL-Result

Fixed: Outlook desktop unable to render SharePoint hosted images embedded in to mail body through PowerAutomate send email action

This post comes out from a recent support experience to one of my clients. He was trying to use Microsoft PowerAutomate flow to embed a SharePoint library hosted image in to an email notification which sent regularly across the organization for all users. Usual way for doing this is using the <img src tag in the send email action but interestingly, these behaviors was a showstopper until I figured out the solution after several hours (described at the end of the article).

111

Behaviors:

  1. Embedded images from a SharePoint URL did not render in Outlook desktop App
  2. Same image renders in OWA (Outlook Web App) however, there was a slight delay in loading the image.
  3. Same image hosted in public hosting locations rendered nicely as well (e.g – https://www.w3schools.com/, Google etc..)

SharePoint hosted image in Outlook Desktop App: Strange enough !

3

External hosted image in Outlook Desktop App:

4

Tried and did not work for my case:

  • Change the text format to HTMLOutlook client application (File -> Options -> Mail -> Compose message in HTML format). This was already in place for my scenario.
  • Add the domain to safe/trusted sites in the browser settings
  • Plethora of other solutions from Microsoft articles and forums

clip_image002[6]

The real solution:

To overcome this issue, you simply have to use these additional lines in your email step. Add a compose action and point it to ‘Get file content using path’ SharePoint action (or you can directly add this line to the mail body HTML)

Add a new Compose action in to the PowerAutomate flow 

Set the Expression as below (you can copy and paste this)

dataUri(outputs('Get_file_content_using_path')?['body'])

67

Amend the Mailbody to reflect the following or add the above mentioned expression directly to the HTML body. Either way should work.

<p><br>
File content using path<br> 

<img src="@{outputs('Compose_2')}"></img>
</p>

8

Full flow: Tested and working perfectly across web client and desktop client of Outlook

9

Result: SharePoint hosted image is now rendered perfectly in Outlook desktop App.

10

Root cause analysis:

The key point is the use of dataUri() to convert the file content to the right format that HTML can understand. An image or a file in general from a SharePoint link is not public link. Only authenticated users can view the image which is the root cause of this issue.

If a user logs in into Outlook on the web from  a browser, their Microsoft identification data are stored locally within the browser context as cookies. As a result, when opening an email that contains a SharePoint link in HTML image tags, a request will be sent to SharePoint servers with the same identification and the image can be downloaded if the user has enough privilege.

It’s the same way that if you have already logged in into one of the google services, you won’t have to login again when accessing other Google services in deferent tabs.

On the other hand, Outlook client is simply an email application which does not share the same architecture as a browser. Outlook account credentials are stored differently and Outlook does not have mechanism to detect and pass credentials to other Microsoft services. Hence, when it sees a SharePoint link in HTML image tags, a request without any authorization data will be sent to the SharePoint servers and of course, it will be refused. If a hyperlink added to the email, clicking on the link will open a browser and you will need to sign in.  In the end, the main purpose of Outlook client is for email-related tasks and it will not handle authentication for other services.