能否通过Microsoft Graph API在Azure企业应用中创建指定组声明及自定义声明?
Absolutely, you can use Microsoft Graph API to set up the exact claims mapping policy you need—including the groups claim for security groups and your custom username, displayname, and email claims. Let's break this down into actionable steps to get it working correctly.
Step 1: Ensure You Have the Right Permissions
First, make sure your registered application has the necessary permissions to manage claims mapping policies. You'll need the Policy.ReadWrite.ApplicationConfiguration application permission (with admin consent granted). If you're using delegated permissions, pair it with Directory.Read.All for full access to directory data.
Step 2: Refine Your Claims Mapping Policy Definition
Your existing policy is close, but we can tweak it to explicitly target security groups and ensure all claims are properly structured. Here's an updated version aligned with your requirements:
{ "definition": [ "{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [ {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\":\"username\"}, {\"Source\":\"user\",\"ID\":\"displayname\",\"SamlClaimType\":\"displayname\"}, {\"Source\":\"user\",\"ID\":\"mail\",\"SamlClaimType\":\"email\"}, {\"Source\":\"user\",\"ID\":\"groups\",\"SamlClaimType\":\"groups\",\"JwtClaimType\":\"groups\",\"GroupFilter\":\"SecurityGroup\"} ]}}" ], "displayName": "Jenkins CM policy", "isOrganizationDefault": false }
Key tweaks here:
- Added
GroupFilter":"SecurityGroup"to ensure only security groups are included in thegroupsclaim (matches your requirement). - Included both
SamlClaimTypeandJwtClaimTypeto cover both SAML and JWT token scenarios—remove one if you only need support for a single token type. - Ordered claims to match your listed requirements for readability.
Step 3: Create the Policy via Graph API
Use a POST request to the claims mapping policies endpoint to create your policy. Here's an example using curl:
curl --request POST \ --url https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies \ --header 'Authorization: Bearer {your-access-token}' \ --header 'Content-Type: application/json' \ --data '{ "definition": [ "{\"ClaimsMappingPolicy\":{\"Version\":1,\"IncludeBasicClaimSet\":\"true\", \"ClaimsSchema\": [ {\"Source\":\"user\",\"ID\":\"userprincipalname\",\"SamlClaimType\":\"username\"}, {\"Source\":\"user\",\"ID\":\"displayname\",\"SamlClaimType\":\"displayname\"}, {\"Source\":\"user\",\"ID\":\"mail\",\"SamlClaimType\":\"email\"}, {\"Source\":\"user\",\"ID\":\"groups\",\"SamlClaimType\":\"groups\",\"JwtClaimType\":\"groups\",\"GroupFilter\":\"SecurityGroup\"} ]}}" ], "displayName": "Jenkins CM policy", "isOrganizationDefault": false }'
Replace {your-access-token} with a valid token obtained using your app's credentials (via client credentials flow or delegated auth).
Step 4: Bind the Policy to Your Service Principal
Creating the policy alone won't activate it—you need to assign it to your Jenkins application's service principal. First, retrieve the service principal ID with this request:
curl --request GET \ --url 'https://graph.microsoft.com/v1.0/servicePrincipals?$filter=displayName eq ''Jenkins''' \ --header 'Authorization: Bearer {your-access-token}'
Grab the id value from the response. Then, use a PUT request to link the policy to the service principal:
curl --request PUT \ --url https://graph.microsoft.com/v1.0/servicePrincipals/{service-principal-id}/claimsMappingPolicies/$ref \ --header 'Authorization: Bearer {your-access-token}' \ --header 'Content-Type: application/json' \ --data '{ "@odata.id": "https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/{policy-id}" }'
Replace {service-principal-id} with the ID you retrieved, and {policy-id} with the ID of the policy created in Step 3.
Step 5: Verify the Policy Works
Test your Jenkins application's authentication flow and inspect the resulting token (SAML assertion or ID token). You should see:
- A
groupsclaim containing the user's security groups usernamepopulated from the user'suserprincipalnamedisplaynamepopulated from the user'sdisplaynameemailpopulated from the user'smailattribute (note this will only appear if the user has a valid mail set in Azure AD)
Quick Tips
- If you don't need both SAML and JWT support, remove the unused claim type (e.g.,
JwtClaimTypeif you only use SAML). - Double-check JSON escaping in the
definitionarray—missing backslashes will cause validation errors. - To update the policy later, use a
PATCHrequest to the policy's endpoint with your modified definition.
内容的提问来源于stack exchange,提问作者hashim vayalar

