Configure SAML-based single sign-on for your application using the Microsoft Graph API
In this article, you'll learn how to create and configure a SAML-based single sign-on (SSO) for your application in Azure Active Directory (Azure AD) using the Microsoft Graph API. The application configuration includes basic SAML URLs, a claims mapping policy, and using a certificate to add a custom signing key. After the application is created, you assign a user to it to be an administrator. You then can use a URL to obtain Azure AD SAML metadata for additional configuration of the application.
This article uses an AWS Azure AD application template as an example, but you can use the steps in this article for any SAML-based app in the Azure AD Gallery.
Prerequisites
This tutorial assumes that you are using Graph Explorer, but you can use Postman, or create your own client app to call Microsoft Graph. To call Microsoft Graph APIs in this tutorial, you need to use an account with the global administrator role and the appropriate permissions. For this tutorial, the Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, Policy.Read.All, Policy.ReadWrite.ApplicationConfiguration, and User.ReadWrite.All delegated permissions are needed. Complete the following steps to set permissions in Graph Explorer:
Go to Graph Explorer.
Select Sign-In with Microsoft and sign in using an Azure AD global administrator account. After you successfully sign in, you can see the user account details in the left-hand pane.
Select the settings icon to the right of the user account details, and then select Select permissions.

In the list of permissions, scroll to and expand AppRoleAssignment (1), and then select the AppRoleAssignment.ReadWrite.All permission. Scroll further down and expand Application (2), and then select the Application.ReadWrite.All permission. Continue to and expand Policy (13), and then select the Policy.Read.All and Policy.ReadWrite.ApplicationConfiguration permissions. Finally, scroll to and expand Users (8), and then select User.ReadWrite.All.

Select Consent, and then select Accept to accept the consent of the permissions. You do not need to consent on behalf of your organization for these permissions.

Step 1: Create the application
Azure AD has a gallery that contains thousands of pre-integrated applications that you can use as a template for your application. The application template describes the metadata for that application. Using this template, you can create an instance of the application and service principal in your tenant for management.
To create the application from the gallery, you first get the identifier of the application template and then use that identifier to create the application.
Retrieve the gallery application template identifier
In this tutorial, you retrieve the identifier of the application template for AWS Single Sign-on. Record the value of the id property to use later in this tutorial.
Request
GET https://graph.microsoft.com/v1.0/applicationTemplates?$filter=displayName eq 'AWS Single Sign-on'
Response
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applicationTemplates",
"value": [
{
"id": "21ed01d2-ec13-4e9e-86c1-cd546719ebc4",
"displayName": "AWS Single Sign-on",
"homePageUrl": "https://aws.amazon.com/",
"supportedSingleSignOnModes": [
"saml",
"external"
],
"supportedProvisioningTypes": [
"sync"
],
"logoUrl": "https://az495088.vo.msecnd.net/app-logo/awssinglesignon_215.png",
"categories": [
"developerServices",
"itInfrastructure",
"security",
"New"
],
"publisher": "Amazon Web Services, Inc.",
"description": "Federate once to AWS SSO & use it to manage access centrally to multiple AWS accounts. Provision users via SCIM & get Azure AD single sign-in access to the AWS Console, CLI, & AWS SSO integrated apps."
}
]
}
Create the application
Using the id value that you recorded for the application template, create an instance of the application and service principal in your tenant. Record the value of the id property of the application and the value of the id property for the service principal to use later in this tutorial.
Request
POST https://graph.microsoft.com/v1.0/applicationTemplates/21ed01d2-ec13-4e9e-86c1-cd546719ebc4/instantiate
Content-type: application/json
{
"displayName": "AWS Contoso"
}
Note
Allow some time for the app to be provisioned into your Azure AD tenant. It is not instant. One strategy is to do a GET query on the application or service principal object every 5-10 seconds until the query is successful.
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.applicationServicePrincipal",
"application": {
"id": "a9be408a-6c31-4141-8cea-52fcd4a61be8",
"appId": "17cad0e7-cd2b-4e51-a75d-ba810f3e4045",
"applicationTemplateId": "21ed01d2-ec13-4e9e-86c1-cd546719ebc4",
"createdDateTime": "2021-05-10T20:12:03Z",
"deletedDateTime": null,
"displayName": "AWS Contoso",
"groupMembershipClaims": null,
"identifierUris": [],
"isFallbackPublicClient": false,
"signInAudience": "AzureADMyOrg",
"tags": [],
"tokenEncryptionKeyId": null,
"defaultRedirectUri": null,
"optionalClaims": null,
"verifiedPublisher": {
"displayName": null,
"verifiedPublisherId": null,
"addedDateTime": null
},
"addIns": [],
"api": {
"acceptMappedClaims": null,
"knownClientApplications": [],
"requestedAccessTokenVersion": null,
"oauth2PermissionScopes": [
{
"adminConsentDescription": "Allow the application to access AWS Contoso on behalf of the signed-in user.",
"adminConsentDisplayName": "Access AWS Contoso",
"id": "6f891cd3-c132-4822-930b-f343b4515d19",
"isEnabled": true,
"type": "User",
"userConsentDescription": "Allow the application to access AWS Contoso on your behalf.",
"userConsentDisplayName": "Access AWS Contoso",
"value": "user_impersonation"
}
],
"preAuthorizedApplications": []
},
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "User",
"id": "8774f594-1d59-4279-b9d9-59ef09a23530",
"isEnabled": true,
"description": "User",
"value": null,
"origin": "Application"
},
{
"allowedMemberTypes": [
"User"
],
"displayName": "msiam_access",
"id": "e7f1a7f3-9eda-48e0-9963-bd67bf531afd",
"isEnabled": true,
"description": "msiam_access",
"value": null,
"origin": "Application"
}
],
"info": {
"logoUrl": null,
"marketingUrl": null,
"privacyStatementUrl": null,
"supportUrl": null,
"termsOfServiceUrl": null
},
"keyCredentials": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"publicClient": {
"redirectUris": []
},
"requiredResourceAccess": [],
"web": {
"homePageUrl": "https://*.signin.aws.amazon.com/platform/saml/acs/*?metadata=awssinglesignon|ISV9.1|primary|z",
"redirectUris": []
}
},
"servicePrincipal": {
"id": "a750f6cf-2319-464a-bcc3-456926736a91",
"deletedDateTime": null,
"accountEnabled": true,
"appId": "17cad0e7-cd2b-4e51-a75d-ba810f3e4045",
"applicationTemplateId": "21ed01d2-ec13-4e9e-86c1-cd546719ebc4",
"appDisplayName": "AWS Contoso",
"alternativeNames": [],
"appOwnerOrganizationId": "8500cad3-193d-48a6-8d00-c129b114dc10",
"displayName": "AWS Contoso",
"appRoleAssignmentRequired": true,
"loginUrl": null,
"logoutUrl": null,
"homepage": "https://*.signin.aws.amazon.com/platform/saml/acs/*?metadata=awssinglesignon|ISV9.1|primary|z",
"notificationEmailAddresses": [],
"preferredSingleSignOnMode": null,
"preferredTokenSigningKeyThumbprint": null,
"replyUrls": [],
"servicePrincipalNames": [
"17cad0e7-cd2b-4e51-a75d-ba810f3e4045"
],
"servicePrincipalType": "Application",
"tags": [
"WindowsAzureActiveDirectoryIntegratedApp"
],
"tokenEncryptionKeyId": null,
"samlSingleSignOnSettings": null,
"verifiedPublisher": {
"displayName": null,
"verifiedPublisherId": null,
"addedDateTime": null
},
"addIns": [],
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "User",
"id": "8774f594-1d59-4279-b9d9-59ef09a23530",
"isEnabled": true,
"description": "User",
"value": null,
"origin": "Application"
},
{
"allowedMemberTypes": [
"User"
],
"displayName": "msiam_access",
"id": "e7f1a7f3-9eda-48e0-9963-bd67bf531afd",
"isEnabled": true,
"description": "msiam_access",
"value": null,
"origin": "Application"
}
],
"info": {
"logoUrl": null,
"marketingUrl": null,
"privacyStatementUrl": null,
"supportUrl": null,
"termsOfServiceUrl": null
},
"keyCredentials": [],
"oauth2PermissionScopes": [
{
"adminConsentDescription": "Allow the application to access AWS Contoso on behalf of the signed-in user.",
"adminConsentDisplayName": "Access AWS Contoso",
"id": "6f891cd3-c132-4822-930b-f343b4515d19",
"isEnabled": true,
"type": "User",
"userConsentDescription": "Allow the application to access AWS Contoso on your behalf.",
"userConsentDisplayName": "Access AWS Contoso",
"value": "user_impersonation"
}
],
"passwordCredentials": []
}
}
Step 2: Configure single sign-on
In this tutorial, you set saml as the single sign-on mode in the service principal. Use the id for the service principal that you recorded earlier.
Request
PATCH https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91
Content-type: application/json
{
"preferredSingleSignOnMode": "saml"
}
Response
HTTP/1.1 204
Set basic SAML URLs
Using the id for the application that you recorded earlier, set the identifier URI and redirect URI for AWS in the application object.
Request
PATCH https://graph.microsoft.com/v1.0/applications/a9be408a-6c31-4141-8cea-52fcd4a61be8
Content-type: application/json
{
"web": {
"redirectUris": [
"https://signin.aws.amazon.com/saml"
]
},
"identifierUris": [
"https://signin.aws.amazon.com/saml"
]
}
Response
HTTP/1.1 204
Add app roles (Optional)
If the application requires the role information in the token, add the definition of the roles in the application object.
Note
When adding app roles, don't modify the default app roles msiam_access.
Use the id for the service principal that you recorded earlier.
Request
PATCH https://graph.microsoft.com/v1.0/serviceprincipals/a750f6cf-2319-464a-bcc3-456926736a91
Content-type: application/json
{
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "User",
"id": "8774f594-1d59-4279-b9d9-59ef09a23530",
"isEnabled": true,
"description": "User",
"value": null,
"origin": "Application"
},
{
"allowedMemberTypes": [
"User"
],
"displayName": "msiam_access",
"id": "e7f1a7f3-9eda-48e0-9963-bd67bf531afd",
"isEnabled": true,
"description": "msiam_access",
"value": null,
"origin": "Application"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Admin,WAAD",
"displayName": "Admin,WAAD",
"id": "3a84e31e-bffa-470f-b9e6-754a61e4dc63",
"isEnabled": true,
"value": "arn:aws:iam::212743507312:role/accountname-aws-admin,arn:aws:iam::212743507312:saml-provider/WAAD"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Finance,WAAD",
"displayName": "Finance,WAAD",
"id": "7a960000-ded3-455b-8c04-4f2ace00319b",
"isEnabled": true,
"value": "arn:aws:iam::212743507312:role/accountname-aws-finance,arn:aws:iam::212743507312:saml-provider/WAAD"
}
]
}
Response
HTTP/1.1 204
Step 3: Configure claims mapping
Create a claims mapping policy
In addition to the basic claims, configure the following claims for Azure AD to emit in the SAML token:
| Claim name | Source |
|---|---|
https://aws.amazon.com/SAML/Attributes/Role |
assignedroles |
https://aws.amazon.com/SAML/Attributes/RoleSessionName |
userprincipalname |
https://aws.amazon.com/SAML/Attributes/SessionDuration |
"900" |
| roles | assignedroles |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier |
userprincipalname |
Note
Some keys in the claims mapping policy are case sensitive (for example, "Version"). If you receive an error message such as "Property has an invalid value", it might be a case sensitive issue.
Create the claims mapping policy and record the value of the id property to use later in this tutorial.
Request
POST https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies
Content-type: application/json
{
"definition": [
"{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [{\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/Role\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/RoleSessionName\"}, {\"Value\":\"900\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/SessionDuration\"}, {\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"appRoles\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/nameidentifier\"}]}}"
],
"displayName": "AWS Claims Policy",
"isOrganizationDefault": false
}
Response
HTTP/1.1 201 Created
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#policies/claimsMappingPolicies/$entity",
"id": "4bce7ba7-466d-4239-94b8-cf4f21428ca7",
"deletedDateTime": null,
"definition": [
"{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [{\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/Role\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/RoleSessionName\"}, {\"Value\":\"900\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/SessionDuration\"}, {\"Source\":\"user\",\"ID\":\"assignedroles\",\"SamlClaimType\": \"appRoles\"}, {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\": \"https://aws.amazon.com/SAML/Attributes/nameidentifier\"}]}}"
],
"displayName": "AWS Claims Policy",
"isOrganizationDefault": false
}
Assign a claims mapping policy to a service principal
Use the id for the service principal that you recorded earlier to assign a claims mapping policy to it. Use the value of the id property for the claims mapping policy in the body of the request.
Request
POST https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91/claimsMappingPolicies/$ref
Content-type: application/json
{
"@odata.id":"https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78"
}
Response
HTTP/1.1 204
Step 4: Configure a signing certificate
You need a self-signed certificate that Azure AD can use to sign a SAML response. You can use your own certificate or you can use the following example.
Create a signing certificate
Using the id of the service principal that you created, create a new certificate and add it to the service principal.
Request
POST https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91/addTokenSigningCertificate
Content-type: application/json
{
"displayName":"CN=AWSContoso",
"endDateTime":"2024-01-25T00:00:00Z"
}
Response
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.selfSignedCertificate",
"customKeyIdentifier": "p9PEYmuKhP2oaMzGfSdNQC/9ChA=",
"displayName": "CN=AWSContoso",
"endDateTime": "2024-01-25T00:00:00Z",
"key": "MIICqjCCAZKgAwIBAgIId....4rnrk43wp75yqjRbOhAZ1ExAxVqW+o2JslhjUeltUMNQW+ynOfs9oHu1ZdnGmxrE=",
"keyId": "70883316-50be-4016-ba80-19d9fbad873d",
"startDateTime": "2021-05-10T20:35:37.5754318Z",
"thumbprint": "A7D3C4626B8A84FDA868CCC67D274D402FFD0A10",
"type": "AsymmetricX509Cert",
"usage": "Verify"
}
Activate the custom signing key
You need to set the preferredTokenSigningKeyThumbprint property of the service principal to the thumbprint of the certificate that you want Azure AD to use to sign the SAML response.
Request
PATCH https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91
Content-type: application/json
{
"preferredTokenSigningKeyThumbprint": "A7D3C4626B8A84FDA868CCC67D274D402FFD0A10"
}
Response
HTTP/1.1 204
Step 5: Assign users
Create a user account
For this tutorial, you create a user account that is added to the application. In the request body, change contoso.com to the domain name of your tenant. You can find tenant information on the Azure Active Directory overview page. Record the id of the user to be used later in this tutorial.
Request
POST https://graph.microsoft.com/v1.0/users
Content-type: application/json
{
"accountEnabled":true,
"displayName":"MyTestUser1",
"mailNickname":"MyTestUser1",
"userPrincipalName":"MyTestUser1@contoso.com",
"passwordProfile": {
"forceChangePasswordNextSignIn":true,
"password":"Contoso1234"
}
}
Response
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"id": "040f9599-7c0f-4f94-aa75-8394c4c6ea9b",
"businessPhones": [],
"displayName": "MyTestUser1",
"userPrincipalName": "MyTestUser1@contoso.com"
}
Assign a user to the application
Assign the user that you created to the service principal and assign the Admin,WAAD app role.
In the request body, provide these values:
- principalId - The id of the user account that you created.
- appRoleId - The id of the
Admin,WAADapp role that you added. - resourceId - The id of the service principal.
Request
POST https://graph.microsoft.com/v1.0/servicePrincipals/a750f6cf-2319-464a-bcc3-456926736a91/appRoleAssignments
Content-type: application/json
{
"principalId": "040f9599-7c0f-4f94-aa75-8394c4c6ea9b",
"principalType": "User",
"appRoleId":"3a84e31e-bffa-470f-b9e6-754a61e4dc63",
"resourceId":"a750f6cf-2319-464a-bcc3-456926736a91"
}
Response
HTTP/1.1 201
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('a750f6cf-2319-464a-bcc3-456926736a91')/appRoleAssignments/$entity",
"id": "mZUPBA98lE-qdYOUxMbqm2qY3odGRGdFtpYJkAfUC0Q",
"deletedDateTime": null,
"appRoleId": "3a84e31e-bffa-470f-b9e6-754a61e4dc63",
"createdDateTime": "2021-05-10T21:04:11.0480851Z",
"principalDisplayName": "MyTestUser1",
"principalId": "040f9599-7c0f-4f94-aa75-8394c4c6ea9b",
"principalType": "User",
"resourceDisplayName": "AWS Contoso",
"resourceId": "a750f6cf-2319-464a-bcc3-456926736a91"
}
Step 6: Get Azure AD SAML metadata
Use the following URL to get the Azure AD SAML metadata for the specific configured application. The metadata contains information such as the signing certificate, Azure AD entityID, and Azure AD SingleSignOnService, among others.
https://login.microsoftonline.com/{tenant-id}/federationmetadata/2007-06/federationmetadata.xml?appid={app-id}
The following shows an example of what you might see for your application:
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="_05fbbf53-e892-43c9-9300-1f6738ace02c" entityID="https://sts.windows.net/2f82f566-5953-43f4-9251-79c6009bdf24/">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/2f82f566-5953-43f4-9251-79c6009bdf24/saml2"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/2f82f566-5953-43f4-9251-79c6009bdf24/saml2"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.microsoftonline.com/2f82f566-5953-43f4-9251-79c6009bdf24/saml2"/>
</IDPSSODescriptor>
</EntityDescriptor>
Step 7: Clean up resources
In this step, you remove the resources that you created.
Delete the application
Delete the application that you created.
Request
DELETE https://graph.microsoft.com/v1.0/applications/a9be408a-6c31-4141-8cea-52fcd4a61be8
Response
No Content - 204
Delete the user account
Delete the MyTestUser1 user account.
Request
DELETE https://graph.microsoft.com/v1.0/users/040f9599-7c0f-4f94-aa75-8394c4c6ea9b
Response
No Content - 204
Delete the claims mapping policy
Delete the claims mapping policy.
Request
DELETE https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/a4b35718-fd5e-4ca8-8248-a3c9934b1b78
Response
No Content - 204
See also
- For AWS, you can enable user provisioning to fetch all the roles from that AWS account. For more information, see Configure the role claim issued in the SAML token.
- Customize claims emitted in tokens for a specific app in a tenant.
- You can use the applicationTemplate API to instantiate Non-Gallery apps. Use applicationTemplateId
8adf8e6e-67b2-4cf2-a259-e3dc5476c621. - applicationTemplate
- appRoleAssignment
- servicePrincipal
- application
- claimsMappingPolicy
- keyCredential
- addTokenSigningCertificate
Saran dan Komentar
Kirim dan lihat umpan balik untuk