terraform-provider-azuread icon indicating copy to clipboard operation
terraform-provider-azuread copied to clipboard

Using unverified domains in `azuread_application`'s `identifier_uris` (for SAML 2.0 based SSO integrations) requires two-step apply

Open 7326922 opened this issue 2 years ago • 1 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritise this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritise the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureAD Provider) Version

Terraform v1.1.9
on linux_amd64
+ provider registry.terraform.io/hashicorp/azuread v2.22.0

Affected Resource(s)

  • azuread_application
  • azuread_service_principal

Terraform Configuration Files

data "azuread_client_config" "test" {
}

resource "azuread_application" "test" {
  display_name = "Example.com"
  identifier_uris = [
    "https://example.com/saml/customer/0",  # I don't own this domain so I can't make it a verified domain in my tenant
  ]
  owners = [
    data.azuread_client_config.test.object_id,
  ]
  web {
    redirect_uris = [
      "https://example.com/saml/redirect/0",
    ]
  }
}

resource "azuread_service_principal" "test" {
  application_id = azuread_application.test.application_id
  owners = [
    data.azuread_client_config.test.object_id,
  ]
  preferred_single_sign_on_mode = "saml"
}

Output

╷
│ Error: Could not create application
│ 
│   with azuread_application.test,
│   on main.tf line 4, in resource "azuread_application" "test":
│    4: resource "azuread_application" "test" {
│ 
│ ApplicationsClient.BaseClient.Post(): unexpected status 400 with OData
│ error: HostNameNotOnVerifiedDomain: Values of identifierUris property must
│ use a verified domain of the organization or its subdomain:
│ 'https://example.com/saml/customer/0'
╵

Steps to Reproduce

  1. terraform apply

Workaround

  1. Comment out identifier_uris and run terraform apply
  2. Uncomment identifier_uris and run terraform apply

Expected Behavior

We have kind of a circular dependency here: the Azure AD app must be created first because the serviceprincipal needs the application_id but to set the app's identifier_uris the service principal must exist with preferred_single_sign_on_mode set to "saml". Currently Terraform itself can't handle circular dependencies, see hashicorp/terraform#27188, so maybe there is some way to address the issue inside the azuread provider?

Related:

  • #778
  • #635
  • #655
  • https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-breaking-changes#appid-uri-in-single-tenant-applications-will-require-use-of-default-scheme-or-verified-domains

7326922 avatar May 13 '22 11:05 7326922

I have a working fix for this for Gallery apps based on SAML over on #778 - just awaiting writing the tests and getting it approved

gtmtech avatar May 26 '22 07:05 gtmtech

While setting up SAML SSO for AWS via AAD today, I found another possible workaround which might be useful for some until this is issue is fixed:

Based on the list of Supported application ID URI formats, combined with values and details from this documentation for setting up SAML-based single sign-on using the Microsoft Graph API, I decided to use api://<tenantId>/<string> instead of the URI scheme https://signin.aws.amazon.com/saml#123456 mentioned in many documentations around the web, resulting in the HostNameNotOnVerifiedDomain error mentioned in the issue description above due to it being an AWS-owned domain.

It seems to be sufficient to provide the global (https://signin.aws.amazon.com/saml) or a regional (https://eu-central-1.signin.aws.amazon.com/saml) AWS SAML endpoint in the web.redirect_uris list and use something like api://a8573488-ff46-450a-b09a-6eca0c6a02dc/api as identifier_uri for the app.

Terraform example:

resource "azuread_application" "example" {
  [...]

  web {
    redirect_uris = [
      "https://eu-central-1.signin.aws.amazon.com/saml",
    ]

    [...]
  }

  identifier_uris = [
    "api://<our-tenant-id>/aws-saml-sso-258",
  ]

  [...]
}

This, combined with the correct app role assignments, claims mapping policy and a service principal token signing certificate, now allows our users to select the AWS Console app from the My Apps dashboard and log in to the AWS Console from there using SAML SSO.

danielfernau avatar Apr 24 '23 12:04 danielfernau

Thanks again for reporting this issue, and for the explanation around this use case. We're releasing a new set of resources for application management, which are being built to enable more fine grained control of properties like identifier_uris, and should resolve this issue. Accordingly, I've linked this issue to #1214.

Our recommendation will be to consider adopting the soon-to-be-introduced azuread_application_registration and azuread_application_identifier_uri resources. This will defer the assignment of identifier URIs until after the application is created, which will allow the azuread_service_principal resource to first set preferred_single_sign_on_mode.

manicminer avatar Oct 17 '23 17:10 manicminer