You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/active-directory/develop/active-directory-saml-claims-customization.md
+52-17Lines changed: 52 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,23 +6,21 @@ services: active-directory
6
6
documentationcenter: ''
7
7
author: rwike77
8
8
manager: CelesteDG
9
-
editor: ''
10
-
11
9
ms.assetid: f1daad62-ac8a-44cd-ac76-e97455e47803
12
10
ms.service: active-directory
13
11
ms.subservice: develop
14
12
ms.workload: identity
15
13
ms.tgt_pltfrm: na
16
14
ms.devlang: na
17
-
ms.topic: conceptual
18
-
ms.date: 10/01/2019
15
+
ms.topic: article
16
+
ms.date: 10/22/2019
19
17
ms.author: ryanwi
20
18
ms.reviewer: luleon, paulgarn, jeedes
21
19
ms.custom: aaddev
22
20
ms.collection: M365-identity-device-management
23
21
---
24
22
25
-
# How to: Customize claims issued in the SAML token for enterprise applications
23
+
# How to: customize claims issued in the SAML token for enterprise applications
26
24
27
25
Today, Azure Active Directory (Azure AD) supports single sign-on (SSO) with most enterprise applications, including both applications pre-integrated in the Azure AD app gallery as well as custom applications. When a user authenticates to an application through Azure AD using the SAML 2.0 protocol, Azure AD sends a token to the application (via an HTTP POST). And then, the application validates and uses the token to log the user in instead of prompting for a username and password. These SAML tokens contain pieces of information about the user known as *claims*.
28
26
@@ -39,7 +37,7 @@ There are two possible reasons why you might need to edit the claims issued in t
39
37
* The application requires the `NameIdentifier` or NameID claim to be something other than the username (or user principal name) stored in Azure AD.
40
38
* The application has been written to require a different set of claim URIs or claim values.
41
39
42
-
## Editing NameID
40
+
## Editing nameID
43
41
44
42
To edit the NameID (name identifier value):
45
43
@@ -74,8 +72,8 @@ Select the desired source for the `NameIdentifier` (or NameID) claim. You can se
74
72
| Email | Email address of the user |
75
73
| userprincipalName | User principal name (UPN) of the user |
76
74
| onpremisessamaccount | SAM account name that has been synced from on-premises Azure AD |
77
-
| objectid |objectid of the user in Azure AD |
78
-
| employeeid |employeeid of the user |
75
+
| objectid |Objectid of the user in Azure AD |
76
+
| employeeid |Employee ID of the user |
79
77
| Directory extensions | Directory extensions [synced from on-premises Active Directory using Azure AD Connect Sync](../hybrid/how-to-connect-sync-feature-directory-extensions.md)|
80
78
| Extension Attributes 1-15 | On-premises extension attributes used to extend the Azure AD schema |
81
79
@@ -87,15 +85,15 @@ You can also assign any constant (static) value to any claims which you define i
87
85
88
86
1. Click on the required claim which you want to modify.
89
87
90
-
1. Enter the constant value in the **Source attribute** as per your organization and click **Save**.
88
+
1. Enter the constant value without quotes in the **Source attribute** as per your organization and click **Save**.
91
89
92
90

93
91
94
92
1. The constant value will be displayed as below.
95
93
96
94

97
95
98
-
### Special claims - Transformations
96
+
### Special claims - transformations
99
97
100
98
You can also use the claims transformations functions.
101
99
@@ -114,31 +112,68 @@ To add application-specific claims:
114
112
1. Enter the **name** of the claims. The value doesn't strictly need to follow a URI pattern, per the SAML spec. If you need a URI pattern, you can put that in the **Namespace** field.
115
113
1. Select the **Source** where the claim is going to retrieve its value. You can select a user attribute from the source attribute dropdown or apply a transformation to the user attribute before emitting it as a claim.
116
114
117
-
### Application-specific claims - Transformations
115
+
### Claim transformations
118
116
119
-
You can also use the claims transformations functions.
117
+
To apply a transformation to a user attribute:
118
+
119
+
1. In **Manage claim**, select *Transformation* as the claim source to open the **Manage transformation** page.
120
+
2. Select the function from the transformation dropdown. Depending on the function selected, you will have to provide parameters and a constant value to evaluate in the transformation. Refer to the table below for more information about the available functions.
121
+
3. To apply multiple transformation, click on **Add transformation**.You can apply a maximum of two transformation to a claim. For example, you could first extract the email prefix of the `user.mail`. Then, make the string upper case.
122
+
123
+

124
+
125
+
You can use the following functions to transform claims.
120
126
121
127
| Function | Description |
122
128
|----------|-------------|
123
129
|**ExtractMailPrefix()**| Removes the domain suffix from either the email address or the user principal name. This extracts only the first part of the user name being passed through (for example, "joe_smith" instead of [email protected]). |
124
-
|**Join()**| Creates a new value by joining two attributes. Optionally, you can use a separator between the two attributes. |
130
+
|**Join()**| Creates a new value by joining two attributes. Optionally, you can use a separator between the two attributes. For NameID claim transformation, the join is restricted to a verified domain. If the selected user identifier value has a domain, it will extract the username to append the selected verified domain. For example, if you select the email ([email protected]) as the user identifier value and select contoso.onmicrosoft.com as the verified domain, this will result in [email protected]. |
125
131
|**ToLower()**| Converts the characters of the selected attribute into lowercase characters. |
126
132
|**ToUpper()**| Converts the characters of the selected attribute into uppercase characters. |
127
133
|**Contains()**| Outputs an attribute or constant if the input matches the specified value. Otherwise, you can specify another output if there’s no match.<br/>For example, if you want to emit a claim where the value is the user’s email address if it contains the domain “@contoso.com”, otherwise you want to output the user principal name. To do this, you would configure the following values:<br/>*Parameter 1(input)*: user.email<br/>*Value*: "@contoso.com"<br/>Parameter 2 (output): user.email<br/>Parameter 3 (output if there's no match): user.userprincipalname |
128
-
|**EndWith()**| Outputs an attribute or constant if the input ends with the specified value. Otherwise, you can specify another output if there’s no match.<br/>For example, if you want to emit a claim where the value is the user’s employeeid if the employeeid ends with “000”, otherwise you want to output an extension attribute. To do this, you would configure the following values:<br/>*Parameter 1(input)*: user.employeeid<br/>*Value*: "000"<br/>Parameter 2 (output): user.employeeid<br/>Parameter 3 (output if there's no match): user.extensionattribute1 |
129
-
|**StartWith()**| Outputs an attribute or constant if the input starts with the specified value. Otherwise, you can specify another output if there’s no match.<br/>For example, if you want to emit a claim where the value is the user’s employeeid if the country/region starts with "US", otherwise you want to output an extension attribute. To do this, you would configure the following values:<br/>*Parameter 1(input)*: user.country<br/>*Value*: "US"<br/>Parameter 2 (output): user.employeeid<br/>Parameter 3 (output if there's no match): user.extensionattribute1 |
134
+
|**EndWith()**| Outputs an attribute or constant if the input ends with the specified value. Otherwise, you can specify another output if there’s no match.<br/>For example, if you want to emit a claim where the value is the user’s employee ID if the employee ID ends with “000”, otherwise you want to output an extension attribute. To do this, you would configure the following values:<br/>*Parameter 1(input)*: user.employeeid<br/>*Value*: "000"<br/>Parameter 2 (output): user.employeeid<br/>Parameter 3 (output if there's no match): user.extensionattribute1 |
135
+
|**StartWith()**| Outputs an attribute or constant if the input starts with the specified value. Otherwise, you can specify another output if there’s no match.<br/>For example, if you want to emit a claim where the value is the user’s employee ID if the country/region starts with "US", otherwise you want to output an extension attribute. To do this, you would configure the following values:<br/>*Parameter 1(input)*: user.country<br/>*Value*: "US"<br/>Parameter 2 (output): user.employeeid<br/>Parameter 3 (output if there's no match): user.extensionattribute1 |
130
136
|**Extract() - After matching**| Returns the substring after it matches the specified value.<br/>For example, if the input's value is "Finance_BSimon", the matching value is "Finance_", then the claim's output is "BSimon". |
131
137
|**Extract() - Before matching**| Returns the substring until it matches the specified value.<br/>For example, if the input's value is "BSimon_US", the matching value is "_US", then the claim's output is "BSimon". |
132
138
|**Extract() - Between matching**| Returns the substring until it matches the specified value.<br/>For example, if the input's value is "Finance_BSimon_US", the first matching value is "Finance_", the second matching value is "_US", then the claim's output is "BSimon". |
133
139
|**ExtractAlpha() - Prefix**| Returns the prefix alphabetical part of the string.<br/>For example, if the input's value is "BSimon_123", then it returns "BSimon". |
134
140
|**ExtractAlpha() - Suffix**| Returns the suffix alphabetical part of the string.<br/>For example, if the input's value is "123_Simon", then it returns "Simon". |
135
141
|**ExtractNumeric() - Prefix**| Returns the prefix numerical part of the string.<br/>For example, if the input's value is "123_BSimon", then it returns "123". |
136
142
|**ExtractNumeric() - Suffix**| Returns the suffix numerical part of the string.<br/>For example, if the input's value is "BSimon_123", then it returns "123". |
137
-
|**IfEmpty()**| Outputs an attribute or constant if the input is null or empty.<br/>For example, if you want to output an attribute stored in an extensionattribute if the employeeid for a given user is empty. To do this, you would configure the following values:<br/>Parameter 1(input): user.employeeid<br/>Parameter 2 (output): user.extensionattribute1<br/>Parameter 3 (output if there's no match): user.employeeid |
138
-
|**IfNotEmpty()**| Outputs an attribute or constant if the input is not null or empty.<br/>For example, if you want to output an attribute stored in an extensionattribute if the employeeid for a given user is not empty. To do this, you would configure the following values:<br/>Parameter 1(input): user.employeeid<br/>Parameter 2 (output): user.extensionattribute1 |
143
+
|**IfEmpty()**| Outputs an attribute or constant if the input is null or empty.<br/>For example, if you want to output an attribute stored in an extensionattribute if the employee ID for a given user is empty. To do this, you would configure the following values:<br/>Parameter 1(input): user.employeeid<br/>Parameter 2 (output): user.extensionattribute1<br/>Parameter 3 (output if there's no match): user.employeeid |
144
+
|**IfNotEmpty()**| Outputs an attribute or constant if the input is not null or empty.<br/>For example, if you want to output an attribute stored in an extensionattribute if the employee ID for a given user is not empty. To do this, you would configure the following values:<br/>Parameter 1(input): user.employeeid<br/>Parameter 2 (output): user.extensionattribute1 |
139
145
140
146
If you need additional transformations, submit your idea in the [feedback forum in Azure AD](https://feedback.azure.com/forums/169401-azure-active-directory?category_id=160599) under the *SaaS application* category.
141
147
148
+
## Emitting claims based on conditions
149
+
150
+
You can specify the source of a claim based on user type and the group to which the user belongs.
151
+
152
+
The user type can be:
153
+
-**Any**: All users are allowed to access the application.
154
+
-**Members**: Native member of the tenant
155
+
-**All guests**: User is brought over from an external organization with or without Azure AD.
156
+
-**AAD guests**: Guest user belongs to another organization using Azure AD.
157
+
-**External guests**: Guest user belongs to an external organization that doesn't have Azure AD.
158
+
159
+
160
+
One scenario where this is helpful is when the source of a claim is different for a guest and an employee accessing an application. You may want to specify that if the user is an employee the NameID is sourced from user.email, but if the user is a guest then the NameID is sourced from user.extensionattribute1.
161
+
162
+
To add a claim condition:
163
+
164
+
1. In **Manage claim**, expand the Claim conditions.
165
+
2. Select the user type.
166
+
3. Select the group(s) to which the user should belong. You can select up to 10 unique groups across all claims for a given application.
167
+
4. Select the **Source** where the claim is going to retrieve its value. You can select a user attribute from the source attribute dropdown or apply a transformation to the user attribute before emitting it as a claim.
168
+
169
+
The order in which you add the conditions are important. Azure AD evaluates the conditions from top to bottom to decide which value to emit in the claim.
170
+
171
+
For example, Brita Simon is a guest user in the Contoso tenant. She belongs to another organization that also uses Azure AD. Given the below configuration for the Fabrikam application, when Brita tries to sign in to Fabrikam, Azure AD will evaluate the conditions as follow.
172
+
173
+
First, Azure AD verifies if Brita's user type is `All guests`. Since, this is true then Azure AD assigns the source for the claim to `user.extensionattribute1`. Second, Azure AD verifies if Brita's user type is `AAD guests`, since this is also true then Azure AD assigns the source for the claim to `user.mail`. Finally, the claim is emitted with value `user.email` for Brita.
Copy file name to clipboardExpand all lines: articles/active-directory/develop/scenario-desktop-acquire-token.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ ms.devlang: na
12
12
ms.topic: conceptual
13
13
ms.tgt_pltfrm: na
14
14
ms.workload: identity
15
-
ms.date: 07/16/2019
15
+
ms.date: 10/24/2019
16
16
ms.author: jmprieur
17
17
ms.custom: aaddev
18
18
#Customer intent: As an application developer, I want to know how to write a Desktop app that calls web APIs using the Microsoft identity platform for developers.
@@ -408,7 +408,7 @@ You can also acquire a token by providing the username and password. This flow i
408
408
Thisflowis**notrecommended** becauseyourapplicationaskingauserfortheirpasswordisn'tsecure. Formoreinformationaboutthisproblem, see [thisarticle](https://news.microsoft.com/features/whats-solution-growing-problem-passwords-says-microsoft/). The preferred flow for acquiring a token silently on Windows domain joined machines is [Integrated Windows Authentication](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Integrated-Windows-Authentication). Otherwise you can also use [Device code flow](https://aka.ms/msal-net-device-code-flow)
|**Identifier (Entity ID)**| Required for some apps | Required for some apps | Uniquely identifies the application. Azure AD sends the identifier to the application as the Audience parameter of the SAML token. The application is expected to validate it. This value also appears as the Entity ID in any SAML metadata provided by the application. *You can find this value as the **Issuer** element in the **AuthnRequest** (SAML request) sent by the application.*|
51
-
|**Reply URL**|Optional| Required | Specifies where the application expects to receive the SAML token. The reply URL is also referred to as the Assertion Consumer Service (ACS) URL. You can use the additional reply URL fields to specify multiple reply URLs. For example, you might need additional reply URLs for multiple subdomains. Or, for testing purposes you can specify multiple reply URLs (local host and public URLs) at one time. |
51
+
|**Reply URL**|Required| Required | Specifies where the application expects to receive the SAML token. The reply URL is also referred to as the Assertion Consumer Service (ACS) URL. You can use the additional reply URL fields to specify multiple reply URLs. For example, you might need additional reply URLs for multiple subdomains. Or, for testing purposes you can specify multiple reply URLs (local host and public URLs) at one time. |
52
52
|**Sign-on URL**| Required | Don't specify | When a user opens this URL, the service provider redirects to Azure AD to authenticate and sign on the user. Azure AD uses the URL to start the application from Office 365 or the Azure AD Access Panel. When blank, Azure AD performs IdP-initiated sign-on when a user launches the application from Office 365, the Azure AD Access Panel, or the Azure AD SSO URL.|
53
53
| **Relay State** | Optional | Optional | Specifies to the application where to redirect the user after authentication is completed. Typically the value is a valid URL for the application. However, some applications use this field differently. For more information, ask the application vendor.
54
54
| **Logout URL** | Optional | Optional | Used to send the SAML Logout responses back to the application.
0 commit comments