Azure AD – Self-Service Sign-up for Guest Users

A Self-Service user flow defines the steps an user will follow while signing-up for an application in your tenant. These applications can be the custom built or SaaS applications. This allows users to sign-up for an app and creates a guest account in the Azure AD tenant.

These user flows cannot be used for MS apps like Teams or SharePoint.

Enable self-service sign-up

Before creating and adding self-service sign-up user flow to your applications, the feature has to be enabled. Once enabled, the necessary options become available.

  1. Login to Azure AD admin portal (https://aad.portal.azure.com/)
  2. In the left menu, click External Identities and then External collaboration settings
External collaboration settings
  1. Toggle Yes to Enable guest self-service sign up via user flows
  2. Click Save

Create user flow for self-service sign-up

Now we’re ready to create user flow for self-service sign-up and add it to an application.

  1. Under the same External identities section in the above steps, click User flows in the left menu
  2. Select New user flow
  3. Enter a Name for the user flow. The name is automatically prefixed with B2X_1_
  4. Select the Identity providers
    • Azure AD is the default identity provider, which means that users are able to sign up by default with an Azure AD account
    • Google and Facebook, Microsoft Account, and Email OTP are also options
  5. Under User attributes, choose the attributes you want to collect from the user
    • For additional attributes, click on Show more
  6. Click Create
New user flow

Select the Page Layout

We can customize the order in which the attributes are displayed on the sign-up page

  1. Click on the user flow created
  2. Click on Page Layouts under Customize in the left menu
  3. For my scenario, I’ve reordered the fields and selected optional as No for the fields I consider mandatory
  4. Click Save
Page Layout

Add Application(s) to the user flow

Now, we are ready to associate an application to the user flow,

  1. In the left menu, under Use, select Applications
  2. Select Add application
    • For my scenario, I’m adding the Salesforce application to enable users to do a self-signup
  3. Search for the application and click Select
Add application

This concludes the steps in the Azure AD admin portal

Guest User experience

We can simply provide the application URL to the guest user for them to sign-up.

In my scenario, I’m using the Salesforce application in my environment,

Salesforce login page

When user tries to login with their own credentials, they will get an error ‘This account does not exist in this organization..‘ This means that the user who is part of a different Azure AD tenant doesn’t exist in the home tenant which the Salesforce application is part of.

Login error

User clicks on Create a new one or Create one!

Select Sign up with email. Enter Email address and password

Review and click Accept in the Permissions requested by: screen

Note: See in screenshot below, Permissions requested by: is the tenant where the application lives

Fill the necessary information and click Continue

Note: This next screen is a result of how we configured the page layout earlier.

And it redirects the user to the Salesforce landing page. I don’t have anything configured within Salesforce for this specific user

Salesforce landing page

So, there are few things to note here:

  • When the user goes through a self-signup process, guest account is automatically created for the user in the home tenant
  • Like in my example, as I don’t have user provisioning enabled with Salesforce, the user has to be created within Salesforce
    • I’m only know the basics on Salesforce’s inner workings but I do have the authentication part configured with Azure AD
    • If you are following this guide and also allowing guest users to login to Salesforce, have your Salesforce administrator setup this guest user with the user’s home tenant’s email account
Guest user’s profile

Hope this post helped you in setting up the Azure AD self-service sign-up user flow to an app.

Thank you for stopping by.✌

M365 – Manage Group Creation Permission

All users can create M365 groups, this is the option enabled by default. Microsoft probably took this approach so as to make sure users can collaborate without any IT assistance.

This is good but when it comes to start managing Teams and the related resources that get created, it can easily become an IT data governance nightmare. If your organization is in its initial phases of Teams rollout, IMO it is better to disable group creation ability for the masses and preferable do a phased approach.

When we disable M365 group creation, it affects all services that rely on groups for access, including:

  • Outlook
  • SharePoint
  • Microsoft Teams
  • Microsoft Stream
  • Yammer
  • Planner
  • Power BI (classic)
  • Project for the web

To have a solution that is sort of a best of both worlds scenario, we can designate an Azure AD group with specific users who have the permissions to create M365 groups.

Create an Azure AD Group

To create a new Azure AD group, the New-AzureADGroup cmdlet can be used or can also be created from the Azure AD admin portal. I’m naming the group ‘M365 – Group Creators’

New-AzureADGroup -DisplayName "M365 - Group Creators" -Description "Group that allows users to create M365 groups" -MailEnabled $false -SecurityEnabled $true -MailNickName "NotSet"
New Azure AD group

Keep in mind this doesn’t prevent users with Azure AD admin roles which has group creation capabilities from creating new groups.

Set Group Creators

The following needs to be run from PowerShell. Make sure AzureADPreview is installed and connected.

Install-module AzureADPreview
Import-Module AzureADPreview
Connect-AzureAD

Run the following commands,

$Template = Get-AzureADDirectorySettingTemplate | where {$_.DisplayName -eq 'Group.Unified'}
$Setting = $Template.CreateDirectorySetting()
New-AzureADDirectorySetting -DirectorySetting $Setting
‘..already exists’ error

If you get an ‘..already exists’ error, that means your tenant already this setting defined. Proceed with the next steps below,

$Setting = Get-AzureADDirectorySetting -Id (Get-AzureADDirectorySetting | where -Property DisplayName -Value "Group.Unified" -EQ).id
$Setting["EnableGroupCreation"] = $False
$Setting["GroupCreationAllowedGroupId"] = (Get-AzureADGroup -SearchString "<Name of your security group>").objectid
EnableGroupCreation and GroupCreationAllowedGroupId

Use the Set-AzureADDirectorySetting below to set the value in the $Setting variable which has the object ID of the Azure AD group.

Set-AzureADDirectorySetting -Id (Get-AzureADDirectorySetting | where -Property DisplayName -Value "Group.Unified" -EQ).id -DirectorySetting $Setting

To determine if the group is allowed to create to groups,

(Get-AzureADDirectorySetting).Values
verify settings

Only one group can be used to control the ability to create Microsoft 365 Groups. But, other groups can be nested as members of this group.

In case your organization wants to revert back this setting in the future, you can do so by changing $AllowGroupCreation to “True” and the group value to “”

$Setting = Get-AzureADDirectorySetting -Id (Get-AzureADDirectorySetting | where -Property DisplayName -Value "Group.Unified" -EQ).id
$Setting["EnableGroupCreation"] = $true
$Setting["GroupCreationAllowedGroupId"] = ""
Set-AzureADDirectorySetting -Id (Get-AzureADDirectorySetting | where -Property DisplayName -Value "Group.Unified" -EQ).id -DirectorySetting $Setting
(Get-AzureADDirectorySetting).Values
Enable group creation

Usually the settings takes 30ish minutes to take effect. You can verify this by trying to create a group with a user who is a non-member of the allowed Azure AD group.

If a user who is part of the group creators can’t create a M365 group, it’s worth checking the OWA policy. The Get-OwaMailboxPolicy can be used to check this,

Get-OwaMailboxPolicy | Select GroupCreationEnabled

If the above output shows ‘False’, you can enable this by using the Set-OwaMailboxPolicy cmdlet,

Set-OwaMailboxPolicy -Identity "Name of your OWA Policy" -GroupCreationEnabled $true

Hope this helped you in setting up the policies to disable M365 group creation.

Thank you for stopping by.✌

Azure AD – Create Security Groups and Add Members using PowerShell

Azure AD security groups can be used to manage member and computer access to shared resources for a group of users. A security group can have users, devices, groups and SPNs as its members. In this post, I’ll go over steps on how to create a Azure AD security group, add users to one group and also bulk import users to one group and multiple groups.

Make sure you are connected to Azure AD,

$credential = Get-Credential
Connect-AzureAD -credential $credential

To create an Azure AD security group:

$GroupName = Read-Host "Enter name for Azure AD group"
New-AzureADGroup -DisplayName $GroupName -MailEnabled $false -SecurityEnabled $true -MailNickName "NotSet"

To create multiple Azure AD security groups:

Note: csv file has name,description as column headers

$groups = import-csv "C:\tmp\AzureAD Groups\groups.csv"

Foreach($group in $groups) {
New-AzureADGroup -DisplayName $group.name -Description $group.description -MailEnabled $false -SecurityEnabled $true -MailNickName "NotSet"
}

To add an user and an owner to an existing group:

$Group = Read-Host "Enter name of Azure AD group"
$User = Read-Host "Enter username of user to be added"
$Owner = Read-Host "Enter username of group owner"

$GroupObj = Get-AzureADGroup -SearchString $Group
$UserObj = Get-AzureADUser -SearchString $User
$OwnerObj = Get-AzureADUser -SearchString $Owner

Add-AzureADGroupMember -ObjectId $GroupObj.ObjectId -RefObjectId $UserObj.ObjectId
Add-AzureADGroupOwner -ObjectId $GroupObj.ObjectId -RefObjectId $OwnerObj.ObjectId

To display members of a security group:

$Group = Read-Host "Enter name of Azure AD group to display members"
$GroupObj = Get-AzureADGroup -SearchString $Group
Get-AzureADGroupMember -ObjectId $GroupObj.ObjectId

To display owners of a security group:

$Group = Read-Host "Enter name of Azure AD group to display owner(s)"
$GroupObj = Get-AzureADGroup -SearchString $Group
Get-AzureADGroupOwner -ObjectId $GroupObj.ObjectId

To bulk add multiple users to a specific group:

Note: csv file has UserPrincipalName as column header

$Group = Read-Host "Enter name of Azure AD group to add users"
$GroupObj = Get-AzureADGroup -SearchString $Group
$Members = Import-csv "C:\tmp\GroupMembers.csv"
Foreach($Member in $Members) {

$User = $Member.UserPrincipalName
Write-Progress -Activity "Adding user.." -Status $User

Try {
$UserObj = Get-AzureADUser -SearchString $User
Add-AzureADGroupMember -ObjectId $GroupObj.ObjectId -RefObjectId $UserObj.ObjectId
}
catch {
Write-Host "Error occured while adding $User" -ForegroundColor Red
}
}

To bulk add multiple users to multiple groups. This below script checks to see if the user is already part of the Azure AD group and returns an error.

Note: csv file has UserPrincipalName,Group as column headers

$list = Import-csv "C:\tmp\UsersGroups.csv"
Foreach($entry in $list) {

$User = $entry.UserPrincipalName
$Group = $entry.Group
$UserObj = Get-AzureADUser -SearchString $User
$GroupObj = Get-AzureADGroup -SearchString $Group
$GroupMembers = (Get-AzureADGroupMember -ObjectId $GroupObj.ObjectId).UserPrincipalName

If ($User -notin $GroupMembers) {
    Add-AzureADGroupMember -ObjectId $GroupObj.ObjectId -RefObjectId $UserObj.ObjectId
    Write-Host "$User added to $Group" -ForegroundColor Green
    }
    else {
    Write-Host "$User already in $Group" -ForegroundColor Red
    }
}

Hope this was helpful for you in exploring Azure AD security groups.

Thank you for stopping by. ✌

Azure AD – Bulk Add Guest users using PowerShell

With Azure AD B2B collaboration, we can invite guest users into our tenant to allow them to access M365 apps and other Azure AD SSO integrated apps. There are multiple ways to invite external users into our Azure AD tenant. In this post, I’ll go through what I worked on recently to invite a bunch of external users in to one of the tenants I manage.

Make sure you are connected to Azure AD,

$credential = Get-Credential
Connect-AzureAD -credential $credential

To send an invite to an external user:

$GuestName = Read-Host "Enter name of user being invited"
$GuestEmail = Read-Host "Enter email address of user being invited"
New-AzureADMSInvitation -InvitedUserDisplayName $GuestName -InvitedUserEmailAddress $GuestEmail -SendInvitationMessage $True -InviteRedirectUrl "http://myapps.microsoft.com"

To bulk invite users from a csv file, this below script will work. This script checks to make sure if the user is already invited and also includes a custom message you can include in the invite.

How the csv file looks like,

$GuestUsers = Import-csv "C:\tmp\InviteGuestUsers\GuestUsers.csv"

$invitationBody = @"
Hi,

Please accept this invitation to join our organization.
If you have any questions, please contact our helpdesk at
support@internaldomain.com

"@

$invitemessage = @{customizedmessagebody = $invitationBody}

ForEach($GuestUser in $GuestUsers) {

$GuestUserEmail = $GuestUser.GuestEmail
$GuestUserName = $GuestUser.GuestName

    if ((Get-AzureADUser -SearchString $GuestUserEmail).Length -le 0) {

        $Invite = New-AzureADMSInvitation -InvitedUserDisplayName $GuestUserName -InvitedUserEmailAddress $GuestUserEmail -SendInvitationMessage $True -InvitedUserMessageInfo $invitemessage -InviteRedirectUrl "http://myapps.microsoft.com"
        Write-Host "Guest user $GuestUserName invited" -ForegroundColor Green
        } else {
        $status = Get-AzureADUser -filter "Mail eq '$GuestUserEmail'" | Select -Expandproperty UserState
        Write-Host "Guest user $GuestUserName already invited - Guest account exists in tenant and invite status is $status" -ForegroundColor Red
        }
}

To list all guest users in the tenant and their invitation acceptance status:

Get-AzureADUser -filter "UserType eq 'Guest'" | Select DisplayName,UserPrincipalName,UserState

or a filter can be applied to determine a specific user,

$guestuser = Read-Host "Enter the guest user email address to check invite status"
Get-AzureADUser -filter "Mail eq '$guestuser'" | Select DisplayName,UserPrincipalName,UserState

Hope this post helped you in external user invites.

Thank you for stopping by. ✌

Enable Federation with Azure AD SSO and Amazon AppStream 2.0

We can enable users to sign in to AppStream 2.0 by using their existing Azure AD credentials, and start streaming applications. To accomplish this, we use an IAM role and a relay state URL to configure Azure AD and enable AWS to permit users to access an AppStream 2.0 stack. The IAM role grants users the permissions to access the stack. The relay state is the stack portal to which users are forwarded after successful authentication by AWS.

In this post, I’ll go over steps on how to configure federated user access for Amazon AppStream 2.0 using Azure AD SSO for Enterprise Apps.

The below diagram illustrates the authentication flow between AppStream 2.0 and Azure AD as identity provider (IdP).

Authentication Workflow

From a user’s perspective, this above process happens seamlessly. The user starts at myapps.microsoft.com and is automatically redirected to an AppStream 2.0 application portal without being required to enter AWS credentials.

The setup process goes like in this diagram below,

Create an Azure AD SSO application

  1. Login to Azure AD Admin Center (https://aad.portal.azure.com/)
  2. Click on the Enterprise applications tab
  3. To add new application, Click New application
Enterprise applications
  1. Click Create your own application
Azure AD – New Application
  1. Provide a name for your application
    • I’ve named my application AppStream-DesignUsers
  2. Select Integrate any other application you don’t find in the gallery (Non-gallery) and click Create
Create your own application
  1. Once the application is added, from the left navigation menu, Click on Single sign-on, and choose SAML
SSO method – SAML
  1. Click Edit in the Basic SAML Configuration
Basic SAML Configuration
  1. Provide the Identifier (Entity ID) and Reply URL (Assertion Consumer Service URL), then click Save
    • Identifier (Entity ID) = URN:AMAZON:WEBSERVICES
    • Reply URL (Assertion Consumer Service URL) = https://signin.aws.amazon.com/saml
    • Sign on URL (Optional) = <leave it blank>
    • Relay State (Optional) = <leave it blank>, We will revisit this later in this post
      • The entity ID is passed during the SAML exchange
      • Azure AD requires this value to be unique for each application
      • When we add more AppStream 2.0 stacks, we can append a number to the string; for example, URN:AMAZON:WEBSERVICES1,URN:AMAZON:WEBSERVICES2
Basic SAML Configuration – Continued
  1. In the SAML Signing Certificate section, click Download next to the Federation Metadata XML and save the .xml file to your computer
Download Federation Metadata XML

Create the SAML identity provider

Now, we need to create the SAML provider in AWS IAM console.

  1. In AWS console, search and open IAM
  2. In the left navigation window, click Identity providers, and the Add provider
AWS IAM – Add provider
  1. On the Configure Provider page, for the Provider Type, select SAML
  2. For Provider name, I’ve named it AzureAD-SSO
  3. Click Choose File to upload the metadata document that previously downloaded from Azure AD, and click Add provider
Configure identity provider
  1. Click on the identity provider we just created
Identity provider added
  1. Copy the value for the Provider ARN
    • The ARN is in the following format: arn:aws:iam::AccountID:saml-provider/Provider Name
Copy Identity provider ARN

Configure an IAM policy

We need to create a policy with permissions to the AppStream 2.0 stack. This way we can ensure that users have only the permission to stream applications from a specific stack.

  1. In the IAM console, choose Policies, click Create Policy
  2. In Create policy page, choose the JSON tab
  3. Copy and paste the following JSON policy into the JSON window
    • Modify the resource by entering your AWS Region Code, account ID, and stack name
      • AWS Region Code = Determine AWS region code here
      • account ID = In AWS console, click on your user name in the top right of the window and your account ID is there
      • Stack name = AppStream stack name which we want to grant access to users to
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "appstream:Stream",
      "Resource": "arn:aws:appstream:REGION-CODE:ACCOUNT-ID-WITHOUT-HYPHENS:stack/STACK-NAME",
      "Condition": {
          "StringEquals": {
              "appstream:userId": "${saml:sub}"           
          }
        }
    }
  ]
}
AWS IAM – Policy
  1. In the Review policy page, provide Name, Description and click Create policy
Review and create policy
  1. You should see the following notification once the policy is created,

Create an IAM Role

In this step, we will create a role that our Azure AD users will assume when federating to AppStream 2.0

  1. In the IAM console, choose Roles, click Create role
  2. For the Trusted entity type, select SAML 2.0 federation
  3. Under SAML 2.0-based provider, choose the SAML IdP that we created earlier
  4. For the Attribute, pick SAML:aud and type https://signin.aws.amazon.com/saml
  5. Do not add any conditions and click Next
AWS IAM – Role
  1. In Add permissions, select the IAM policy we created earlier and click Next
Add permissions
  1. Provide a Role Name and Description that identifies the role, and click Create Role
  2. Once created, locate and click on the role we just created
  3. Copy the Role ARN
    • The ARN is required to configure claims rules later
    • The ARN is in the following format: arn:aws:iam::AccountID:role/Role Name
Copy role ARN

Configure the Azure AD SSO Application

Now we are ready to finish configuring the Azure AD application we started working on earlier

  1. Login to Azure AD Admin Center (https://aad.portal.azure.com/)
  2. Click on the Enterprise applications tab
  3. Choose the application we created earlier, from the left navigation menu, Click on Single sign-on
  4. Click Edit in the Basic SAML Configuration, Provide Relay State URL and click Save
    • Relay State = The Relay State is unique to the account, AWS Region, and AppStream 2.0 stack
    • Format is,
      • https://relay-state-region-endpoint?stack=stackname&accountId=aws-account-id-without-hyphens
    • Below table has a list of AppStream 2.0 Relay State Region Endpoints
Region Relay state endpoint
US East (N. Virginia)https://appstream2.us-east-1.aws.amazon.com/saml
(FIPS) https://appstream2-fips.us-east-1.aws.amazon.com/saml
US West (Oregon)https://appstream2.us-west-2.aws.amazon.com/saml
(FIPS) https://appstream2-fips.us-west-2.aws.amazon.com/saml
Asia Pacific (Mumbai)https://appstream2.ap-south-1.aws.amazon.com/saml
Asia Pacific (Seoul)https://appstream2.ap-northeast-2.aws.amazon.com/saml
Asia Pacific (Singapore)https://appstream2.ap-southeast-1.aws.amazon.com/saml
Asia Pacific (Sydney)https://appstream2.ap-southeast-2.aws.amazon.com/saml
Asia Pacific (Tokyo)https://appstream2.ap-northeast-1.aws.amazon.com/saml
Canada (Central)https://appstream2.ca-central-1.aws.amazon.com/saml
Europe (Frankfurt)https://appstream2.eu-central-1.aws.amazon.com/saml
Europe (Ireland)https://appstream2.eu-west-1.aws.amazon.com/saml
Europe (London)https://appstream2.eu-west-2.aws.amazon.com/saml
AWS GovCloud (US-West)https://appstream2.us-gov-west-1.amazonaws-us-gov.com/saml
(FIPS) https://appstream2-fips.us-gov-west-1.amazonaws-us-gov.com/saml
AppStream 2.0 Relay State Region Endpoints
Azure AD – Add Relay State
  1. Click Edit in the Attributes & Claims section
Azure AD – Attributes & Claims
  1. In Required claim,
    • Unique User Identifier (Name ID) = Key used to identify users in the SAML assertion
    • I generally stick with user.userprincipalname
    • Usually user.mail or user.userprincipalname works
  2. Click + Add new claim and add the below claims
    • By default, Azure AD populates several SAML attributes for all new applications
    • These attributes are not needed for the federation to AppStream 2.0
    • We can remove them by choosing the three dots next to each, and choosing Delete
      • If you decide to leave them as is, it doesn’t do any harm

Name = Role
Namespace = https://aws.amazon.com/SAML/Attributes
Source = Attribute
Source Attribute = This is the Role ARN from earlier in this post, followed by a comma and then the Provider ARN

Role attribute

Name = RoleSessionName
Namespace = https://aws.amazon.com/SAML/Attributes
Source = Attribute
Source Attribute = We can provide any string value. I’m going with user.mail

RoleSessionName attribute

Name = SAML_SUBJECT
Namespace = https://aws.amazon.com/SAML/Attributes
Source = Attribute
Source Attribute = We can provide any string value. I’m going with user.displayname

SAML_SUBJECT attribute

If the user intend to use the AppStream 2.0 client, sessions will default to a 60 minute timeout. This setting will determine the duration.

Name = SessionDuration
Namespace = https://aws.amazon.com/SAML/Attributes
Source = Attribute
Source Attribute = Value in seconds between 900 (15 minutes) and 43200 (12 Hours). I’m going with 28800 (8 Hours)

SessionDuration attribute

Assign Azure AD groups in Application

  1. In the left navigation menu, click Users and groups, click + Add user/group
  2. In Add Assignment, click Users and groups
  3. In the Users and groups dialog box, select the Azure AD group to provide access the AppStream 2.0 stack
  4. Click Assign
Assign Group

Also click on the Properties tab in the left navigation menu to check the following,

  • Enabled for users to sign-in? = Yes
  • Assignment required? = Yes
  • Visible to users? = Yes

I also uploaded an icon file for the app to look nicer.😉

Test Application

With a Azure AD security group assigned to the application and the other setting configured, we’re ready to test this with a user account. I’ve already added the user account to the assigned Azure AD group. To test this,

  1. User logs into myapps portal (https://myapps.microsoft.com/) with their Azure AD credentials
  2. User is presented with the AppStream stack,
User’s myapps portal view
User redirected to AppStream 2.0 app catalog

I also created a second fleet and stack, associated the fleet to the stack to demonstrate how we can assign different users to stacks. IMO, the myapps portal is a really cool feature and we can it to present AppStream to our users.

As I mentioned earlier in this post, adding more stack will require adding additional Azure AD applications and assigning AD group(s) to it.

All Stacks
All Fleets

This below is a different user logging into the myapps portal (https://myapps.microsoft.com/) with their Azure AD credentials and I’ve assigned the ‘DeveloperUsers-Stack-0323’ stack to them.

User’s myapps portal view

The user gets redirected to the AppStream 2.0 portal

User redirected to AppStream 2.0 app catalog

Issues you may encounter and How to fix it

Error: RoleSessionName is required in AuthnResponse (service: AWSSecurityTokenService; status code: 400; error code: InvalidIdentityToken)

Fix: I encountered this error with the second stack I had created. When is saw this error, my obvious first step is to make sure I didn’t miss the RoleSessionName attribute in the Azure AD app I created. And it was there with the expected value.

I then decided to go back over the AWS IAM role and policy I created and realized that in the I had picked the wrong identity provider and once I picked the correct one, this issue was resolved.

RoleSessionName is required in AuthnResponse (service: AWSSecurityTokenService; status code: 400; error code: InvalidIdentityToken)

Error: Unable to authorize the session. (Error Code: INVALID_AUTH_POLICY);Status Code:401

Fix: This error message occurs when the IAM policy does not permit access to the AppStream 2.0 stack or when the stack name is not entered into the policy. Similar mess up on my part.

I had mistyped the stack’s name while creating/typing in the JSON window during the policy creation step.

Unable to authorize the session. (Error Code: INVALID_AUTH_POLICY);Status Code:401

In my experience, the SAML-tracer for Chrome and Firefox comes in handy to help identify SAML related issues. It has certainly helped me in several instances.

Hope this post helped you to setup Azure AD SSO for your AppStream 2.0 stacks.

Thank you for stopping by.✌