ADFS 4.0 Deployment and SSO with AWS AppStream 2.0 Service in my Lab

This is another lab that I just recently setup while working on a customer case to reproduce the issue. In this lab I will walk you through setting up Active Directory Federation Service (ADFS) along with ADFS Web Application Proxy (WAP). Then we will further configure Single-Sign-On (SSO) for AWS AppStream 2.0 service with our ADFS running in internal Active Directory domain. This will enable our AD users to seamlessly login to AWS AppStream 2.0 console using their domain credentials.

Lab Environment Details:
The complete environment is running Windows Server 2016 OS, I have two domain controllers (DC1 and DC2) and two other servers (ADFS01 and ADFS02) that will be acting as ADFS Federation Server and Web Application Proxy Server respectively.

Domain Controllers:
DC1.CloudMegh.in
DC2.CloudMegh.in

ADFS Servers;
ADFS01.CloudMegh.in – Federation Server
ADFS02 – ADFS Web Application Proxy Server

High Level Steps:
1. Hosting public facing domain name for external Single-Sign-On (SSO)URL.
2. Install and Configure ADFS Role on “ADFS01.CloudMegh.in” Server.
3. Add Relying Party Trust in ADFS.
4. Configure Claim Rules for Relying Party Trust.
5. Download ADFS Metadata file.
6. Create SAML Identity Provider (IdP) in AWS IAM.
7. Create AWS IAM Policy to allow access to AWS AppStream 2.0 Stack.
8. Create SAML 2.0 Federated IAM Role in AWS IAM.
9. Create RelayState URL for AWS AppStream 2.0 Stack.
10. Test AWS AppStream 2.0 Single-Sign-On with RelayState URL.
11. Install and Configure ADFS Web Application Proxy (WAP) Server on “ADFS02” Server.
12. Publish Web Application to ADFS WAP.
13. ADFS URL binding in IIS.
14. Configure the URL Rewrite and Application Request Routing in IIS for SSO URL.
15. Test AWS AppStream 2.0 SSO from outside (public) network.

High Level Architecture Diagram:


Step by Step Configuration:
Now let’s go ahead and start implementing the above high level steps to complete this lab deployment.

1. Hosting public facing domain name for external Single-Sign-On (SSO) URL
>I already have my public domain (cloudmegh.in) registered and hosted with Godaddy, I simply added a subdomain to my existing public domain and pointed to fixed public IP address. So I have my domain (sts.cloudmegh.in) which will be forming my external URL for Single-Sign-On (SSO). This public IP address where this subdomain is pointing to is actually assigned to my ADFS Web Application Proxy that I will be installing/configuring in the later part of this lab.



>Now if you perform NSLOOKUP if you see its resolving against my Public IP.


2. Install and Configure ADFS Role on “ADFS01.CloudMegh.in” Server
>There are different scenarios for ADFS deployment in the enterprise environment. You can refer below Microsoft documentation for more detailed understanding and based on your feasibility you can choose one to go with. For my lab ADFS deployment, I’m deploying my lab with “Federation Server Farm Using WID and Proxies” scenario.

AD FS Deployment Topology Considerations:
https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/design/ad-fs-deployment-topology-considerations

ADFS Deployment Scenarios:
1. Stand-Alone Federation Server Using WID (Windows Internal Database).
2. Federation Server Farm Using WID.
3. Federation Server Farm Using WID and Proxies.

>Open Server Manager and Click on “Add Roles and Features”

>Select “Role-Based or feature-based installation” and click on Next to process further


>Select the server and click on Next to process ahead


>Select “Active Directory Federation Services” and Click on Next


>Review the information this page and Click on the Next

>Click on “Install” to start ADFS role installation.


>ADFS Role installation has been completed successfully, now we need to configure federation service on this server.

>Click on “Configure the federation service on this server”, it will open ADFS Configuration Wizard.
>Select “Create the first federation server in a federation server farm” and then Click on “Next” to proceed further.


>Provide the account has domain administrator permission to perform the ADFS configuration


>You need to have SSL certificate created prior starting ADFS configuration that you would need to specify here. I had already created and imported certificate for my Federation Service “sts.cloudmegh.in”



>Specify a service account (basically a domain user account) that will be used by ADFS service.


>ADFS in my lab will be using Windows Internal Database (WID), depending upon your feasibility and requirements you may use SQL Server Database.



>Click on Next to proceed further.



>Click on “Configure” to start ADFS configuration.



>ADFS Configuration has been completed successfully, I will reboot this server now.


>I have my ADFS Federation Server ready for further configuration.



3. Add Relying Party Trust in ADFS:
>Right Click on “Relying Party Trusts” and Click on “Add Relying Party Trust”


>Click on “Claims aware” and then click on “Start”



Note:
Now first we need to download SAML metadata from AWS end using below metadata URL then we will proceed further. Since the end goal of this ADFS lab is to implement SSO for AWS AppStream 2.0 service. So AWS is service provider (Relying Party) here.
https://signin.aws.amazon.com/static/saml-metadata.xml

>Choose “Import data about the relying party from a file” and provide the metadata file path that was downloaded from above URL


>Provide the Display Name for this Relying Party Trust and proceed further


>Proceed with default options here.


>Click on Next to proceed further, we don’t have to modify anything here at the moment. Some of these properties can also be changed after adding relying party trust.



>Check “Configure claims issuance policy for this application” and then click on “Close” to complete this wizard.


>Now we have our Relying Party Trust “AWS AppStream” added successfully.


>Now go to the properties of above relying party trust and add the identifier as below. This is SAML endpoint for AWS.
https://signin.aws.amazon.com/saml



4. Configure Claim Rules for Relying Party Trust
Now we need to configure Claims Rules for “Relying Party Trust” that we added in above steps.  Claim Rules are basically defined as a property of the Claims Provider Trust (incoming claims) and the Relying Party Trust (outgoing claims).

>Right click on the Relying Party Trust “AWS AppStream” and then click on “Edit Claim Issuance Policy”


>At the moment we don’t have any Claim rules for this relying party. Now let’s go ahead and add the required Claim Rules for this replying party. We need total four claims rules to be configured for this relying party trust.


(A). “Name ID” Claim Rule:
>Click on the “Add Rule” and choose “Transform an Incoming Claim” from Claim rule template.



>Configure Claim Rule values:
Claim Rule Name:  Name ID
Incoming Claim Type:  UPN
Outgoing Claim Type:  Name ID
Outgoing name ID format:  Persistent Identifier
Pass through all claim values:  selected



(B). “RoleSessionName” Claim Rule
> This is 2nd rule for this relying party, select “Send LDAP Attributes as Claims” and provide required values as below:


Configure Claim Rule values:
Claim rule name:  RoleSessionName
Attribute store:  Active Directory
LDAP Attribute:  E-Mail-Addresses
Outgoing Claim Type:  https://aws.amazon.com/SAML/Attributes/RoleSessionName


 (C.) “Get Active Directory groups” Claim Rule:
Note: Before creating this rule, you need to create an Active Directory global security group and name of this security should in this format “AWS-YOURAWSACCOUNTID-IAMROLENAME”. So if my AWS Account id is 123456789 and federated AWS IAM Role name is ADFSSSO then my AD Security Group name will be “AWS-123456789-ADFSSSO”. All the AD users that are added to this security group will be able to connect to AWS AppStream using ADFS SSO URL.





>Click on “Add Rule” and then choose “Send Claims Using a Custom Rule”



Configure Claim Rule values:
Claim Rule Name:  Get Active Directory Groups
Custom Rule:
c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname“, Issuer == “AD AUTHORITY”]  => add(store = “Active Directory”, types = (“http://temp/variable“), query = “;tokenGroups;{0}”, param = c.Value);



(D). “Roles” Claim Rule:

>Click on “Add Rule” and then choose “Send Claims Using a Custom Rule”


Configure Claim Rule values:
Claim Rule Name:  Roles
Custom Rule:
c:[Type == “http://temp/variable“, Value =~ “(?i)^AWS-“] => issue(Type = “https://aws.amazon.com/SAML/Attributes/Role“, Value = RegExReplace(c.Value, “AWS-123456789-“, “arn:aws:iam::123456789:saml-provider/ADFS,arn:aws:iam::123456789:role/”));



>Now we have all the four required Claim Rules configured for Relying Party Trust “AWS AppStream”.



5. Download ADFS Metadata file:
Now we need to download ADFS metadata from ADFS Server using below ADFS metadata URL. Once we have this metadata file downloaded then we will go ahead with further configuration from AWS side i.e. creating AWS IAM Identity Provider and IAM roles etc.

https://sts.cloudmegh.in/FederationMetadata/2007-06/FederationMetadata.xml

6.Create SAML Identity Provider (IdP) in AWS IAM:
>Login to AWS Console and navigate to IAM service
>Click on “Identity Providers” and then Click on “Create Provider”
>Provide the desired name for your IdP and then choose your ADFS metadata file.



>Click on “Create” and we have our Identify Provider “ADFS” created in IAM console




7. Create AWS IAM Policy to allow access to AWS AppStream 2.0 Stack
Now we need to create an IAM role policy that will allow access to my AWS AppStream 2.0 Stack. This IAM policy will attached to the IAM role “ADFSSSO” that will be created in next step (step 8). My AWS AppStream 2.0 Stack name is “MeraAppStack” running in “US-East-1” AWS Region.

>Go to IAM Console ——–> Policies——>Create Policy



>Click on “JSON” option and have the policy definition like below. You can copy/paste this JSON after modifying the AppStream Stack ARN
—————————————————–
{
 “Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”
“Action”: “appstream:Stream”,
“Resource”: “arn:aws:appstream:us-east-1:1234567895:stack/MeraAppStack”,
“Condition”: {
StringEquals”: {
“appstream:userId”: “${saml:sub}”,
“saml:sub_type”: “persistent”
}
}
}
]
}
———————————————————


>Provide the name of the Policy and click on “Create”.



>IAM Policy got created successfully.



8.Create SAML 2.0 Federated IAM Role in AWS IAM:
>IAM Console——->Roles——–>Create Role


>Select “SAML 2.0 federation” and choose correct IdP that we created, its “ADFS” in this case.


>On the permissions policies, select “ADFS-SSOPolicy” that we created in previous step.



>Provide appropriate IAM role name and click on “Create role”.



>This IAM role has been crated successfully.



Note:
Till this step we are done with most of the basic configuration of the ADFS SSO and we can now test our default ADFS SSO URL to ensure that its functioning correctly. Below URL is the default ADFS SSO URL for my lab.
https://sts.cloudmegh.in/adfs/ls/idpinitiatedsignon.htm



>I can login using default ADFS SSO URL and as of now it’s taking me to AWS Console instead of AWS AppStream 2.0 console because I’m not logging using RelayState URL and also I haven’t configure IIS to either redirect to RelayState URL. In the next step I’m going to generate RelayState URL and then further I will be configuring ADFS Proxy with some IIS configuration like URL Rewrite and Application Request Routing.



9.Create RelayState URL for AWS AppStream 2.0 Stack
>Now let’s create RelayState URL, I’m using excel sheet available under below path to download. You can input your ADFS service name and AppStream Stack details here to generate RelayState URL.



RelayState URL Generator Download:
https://s3-us-west-2.amazonaws.com/as2-blog-artifacts/RelayGenerator.xlsx


>So I have got my RelayState URL ready and now I can test ADFS SSO and I should be able to connect to AppStream 2.0 Stack using this URL.

10. Test AWS AppStream 2.0 Single-Sign-On with RelayState URL
>Let’s login using RelayState URL and verify if everything is functioning as expected.



>And it connects me to my AWS AppStream 2.0 Stack successfully.



Note: The RelayState URL is not user friendly and can’t be remembered this so we need to have a simple ADFS SSO URL where user can visit and login with their AD credential which should redirect to RelayState URL, we need to have IIS to meet this requirement and also if you would like to enable external excess for your ADFS SSO URL then you would require ADFS Proxy as well that should be running in your DMZ network and ideally should have public IP pointing to your publicly routable domain in ADFS SSO URL like in my case its sts.cloudmegh.in. There can be other scenarios in this configuration depending on your design and requirements.

What’s next ? I will be configuring ADFS Web Application Proxy in DMZ environment which is public facing and configure IIS.

11. Install and Configure ADFS Web Application Proxy (WAP) Server on “ADFS02” Server:
>First add hosts file entry on ADFS Proxy server pointing to ADFS Federation Service domain name.

>Now enable the Web Application Proxy feature using below PowerShell cmdlet.
Install-WindowsFeature Web-Application-Proxy -IncludeManagementTools

>Now I will configure Web Application Proxy using below PowerShell cmdlet.


$credential = Get-Credential
Install-WebApplicationProxy -FederationServiceName “sts.cloudmegh.in” -FederationServiceTrustCredential
$credential -CertificateThumbprint “1E5812E005704E35B08355827941EA5D556E2736”



12. Publish Web Application to ADFS WAP:
>Once the Web Application Proxy is configured, we need to public web applications to proxy. As of now I don’t have any Web Applications published in my ADFS Proxy.
>Open Remote Access Management Console and then navigate to Web Application Proxy, Click on “Publish” option.


>Publish New Application Wizard will start now.



>Choose “Active Directory Federation Services (AD FS) as preauthentication method.



>Select “Web and MSOFBA” and Click on “Next” button to proceed further.


>Select ADFS Relying Party that we have already configured in initially during ADFS configuration.



>Provide External URL and Backend server URL, both URLs should same.



>Click on “Publish” button to finally publish this application.



>And it has been published now successfully.


13. ADFS URL binding in IIS:

>Since we will be accessing ADFS SSO URL from public network also, so we need to bind it as HTTPS site in IIS on ADFS Proxy Server.



14. Configure the URL Rewrite and Application Request Routing in IIS for SSO URL:
This configuration will help us shortening the ADFS SSO URL because at the moment if we need to login via RelayState URL to connect to AWS AppStream 2.0 and due to complexity of the RelayState URL we can’t remember it. So we will configure URL Rewrite and Application Request Routing in IIS to shorten the SSO URL. Please refer below steps for this configuration.

I’m not an IIS guy, I just went through some documentations to get this working and I hope this would help you too.

Note: You would need to manually download and install URL Rewrite and ARR module in IIS to achieve this. This is not available with default IIS installation.

>Open IIS Manager console and then go to Application Request Routing Cache.

>In the right pane, Click on “Server Proxy Settings” to proceed further.


>Click on “Enable Proxy” and configure the settings as per below screenshots.





>Now again go back to the IIS home console, Click on “URL Rewrite”

>Now click on “Add Rules(s)” and choose “Blank Rule” from Inbound Rules templates





>Now provide desired Inbound Rule name, I’m specifying name as “redirecttorelaystate”, In the pattern mention .* and provide your “relayState” URL in Rewrite URL box and choose “Rewrite” action in the Action Type.




15. Test AWS AppStream 2.0 SSO from outside (public) network:
>Now we are done with all the required configuration from ADFS and IIS side and we are ready to test our SSO from external network using htts://sts.cloudmegh.in instead of accessing with complex RelayState URL.

>I can access it from public network now, let’s go ahead and see if it connects to AWS AppStream 2.0 successfully after entering credentials.



>And Yes, it connected me to my AppStream 2.0 Stack successfully and I can see my application published in this stack.



So this lab deployment and configuration ends here, I hope this will you help if you are deploying similar configuration in your lab or production environment.

Thank you so much for visiting and reading this blog post. Happy Learning!!

This blog post/document is provided “AS IS” with no warranties and confers no rights.

6 thoughts on “ADFS 4.0 Deployment and SSO with AWS AppStream 2.0 Service in my Lab”

  1. Very well documented. The formatting is perfect and very easy to go through despitr the write up being so detailed. The language is easy and straightforward, the way a technical blog should be.
    Thumbs up.

  2. Hey man, just FYI if you’re running a new ADFS (4.0) you need to enable it to use RelayState URLs:

    Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
    Set-AdfsProperties -EnableRelayStateForIdpInitiatedSignOn $true
    Restart-Service adfssrv

    1. Hi Simon, thanks for your feedback.

      You are absolutely correct, I did run those cmdlets but looks like I missed it adding to the doc here. I will be updating the information soon. Thanks again.

    1. Hi Stephen,

      Thank you for your question.

      Yes, you will be asked to enter the password for the domain user if the AppStream fleet is domain joined after you click on application in the web catalog to launch it.

      If the AppStream fleet isn’t domain joined then once SSO part completed and you click on application to launch it will auto login to the session using “PhotonUser” which is local user created for streaming.

      Let me know if you have any questions.

Leave a Reply

Your email address will not be published.