Personalización de notificaciones emitidas en JSON Web Token (JWT) para aplicaciones empresariales
La plataforma de identidad de Microsoft admite el inicio de sesión único (SSO) con la mayoría de las aplicaciones pre integradas en la galería de aplicaciones de Microsoft Entra y las aplicaciones personalizadas. Cuando un usuario se autentica en una aplicación a través de la plataforma de identidad de Microsoft mediante el protocolo OIDC, ésta envía un token a la aplicación. La aplicación valida el token y lo usa para que el usuario inicie sesión en lugar de solicitar un nombre de usuario y una contraseña.
Estas instancias de JSON Web Token (JWT) usadas por las aplicaciones OIDC y OAuth contienen información sobre el usuario conocido como notificaciones. Una notificación es información que un proveedor de identidades declara sobre un usuario dentro del token que se emite para dicho usuario. En una respuesta OIDC, los datos de notificaciones normalmente se incluyen en el token de id. emitido por el proveedor de identidades en forma de JWT.
Visualización o edición de notificaciones
Sugerencia
Los pasos de este artículo pueden variar ligeramente en función del portal desde donde comienza.
Las notificaciones JWT opcionales se pueden configurar en el registro de aplicación original, pero también se pueden configurar en la aplicación empresarial. Para ver o editar las notificaciones emitidas en la instancia de JWT a la aplicación:
- Inicie sesión en el Centro de administración de Microsoft Entra como Administrador de aplicaciones en la nube.
- Vaya a Identidad> Aplicaciones>aplicaciones para empresas> Todas las aplicaciones.
- Seleccione la aplicación, seleccione Inicio de sesión único en el menú de la izquierda y, a continuación, seleccione Editar en la sección Atributos y notificaciones.
Una aplicación puede necesitar personalización de notificaciones por varios motivos. Por ejemplo, cuando una aplicación requiere un conjunto diferente de URI de notificación o valores de notificación. Con la sección Atributos y notificaciones, puede agregar o quitar una notificación para la aplicación. También puede crear una notificación personalizada específica para una aplicación en función del caso de uso.
En los pasos siguientes se describe cómo asignar un valor constante:
- Seleccione la notificación que desea modificar.
- Escriba el valor constante sin comillas en Atributo de origen según su organización y luego haga clic en Guardar.
La información general sobre atributos muestra el valor constante.
Transformaciones de notificaciones especiales
Puede usar las siguientes funciones de transformaciones de notificaciones especiales.
Función | Descripción |
---|---|
ExtractMailPrefix() | Quita el sufijo de dominio de la dirección de correo electrónico o el nombre principal de usuario. Esta función extrae solo la primera parte del nombre de usuario. Por ejemplo, joe_smith en lugar de joe_smith@contoso.com . |
ToLower() | Convierte los caracteres del atributo seleccionado en caracteres en minúscula. |
ToUpper() | Convierte los caracteres del atributo seleccionado en caracteres en mayúscula. |
Incorporación de notificaciones específicas de la aplicación
Para agregar notificaciones específicas de la aplicación:
- En Atributos y notificaciones de usuario, seleccione Agregar nueva notificación para abrir la página Administrar las notificaciones del usuario.
- Escriba el nombre de las notificaciones. El valor no tiene que seguir un patrón de URI estrictamente. Si necesita un patrón de URI, puede colocarlo en el campo Espacio de nombres.
- Seleccione el origen en el que la notificación va a recuperar su valor. Puede seleccionar un atributo de usuario en la lista desplegable de atributos de origen o aplicar una transformación al atributo de usuario antes de emitirlo como una notificación.
Transformaciones de notificación
Para aplicar una transformación a un atributo de usuario:
- En Administrar notificaciones, seleccione Transformación como origen de la notificación para abrir la página Administrar la transformación.
- Seleccione la función en la lista desplegable transformación. Dependiendo de la función seleccionada, proporciona parámetros y un valor constante para evaluar en la transformación.
- Tratar el origen como multivalor indica si la transformación se aplica a todos los valores o solo al primero. De forma predeterminada, el primer elemento de una notificación de varios valores se aplica a las transformaciones. Al activar esta casilla, se asegura de que se aplica a todos. Esta casilla de verificación solo está habilitada para atributos de varios valores. Por ejemplo,
user.proxyaddresses
. - Para aplicar varias transformaciones, seleccione Agregar transformación. Puede aplicar un máximo de dos transformaciones a una notificación. Por ejemplo, puede extraer primero el prefijo de correo del
user.mail
. Después, convierta la cadena en mayúsculas.
Puede utilizar las siguientes funciones para transformar notificaciones.
Función | Descripción |
---|---|
ExtractMailPrefix() | Quita el sufijo de dominio de la dirección de correo electrónico o el nombre principal de usuario. Esta función extrae solo la primera parte del nombre de usuario. Por ejemplo, joe_smith en lugar de joe_smith@contoso.com . |
Join() | Crea un nuevo valor al combinar dos atributos. Si quiere, puede usar un separador entre los dos atributos. Para la transformación de notificaciones NameID, la función Join() tiene un comportamiento específico cuando la entrada de la transformación tiene una parte del dominio. La función quita la parte de dominio de la entrada antes de unirla al separador y al parámetro seleccionado. Por ejemplo, si la entrada de la transformación es joe_smith@contoso.com , el separador @ y el parámetro fabrikam.com , esta combinación de entrada da como resultado joe_smith@fabrikam.com . |
ToLowercase() | Convierte los caracteres del atributo seleccionado en caracteres en minúscula. |
ToUppercase() | Convierte los caracteres del atributo seleccionado en caracteres en mayúscula. |
Contains() | Genera un atributo o una constante si la entrada coincide con el valor especificado. En caso contrario, puede especificar otra salida si no hay ninguna coincidencia. Por ejemplo, si quieres emitir una notificación en la que el valor es la dirección de correo electrónico del usuario si contiene el dominio @contoso.com , en caso contrario, quieres obtener el nombre principal de usuario. Para realizar esta función, configure los valores siguientes:Parámetro 1 (entrada) : user.email Valor: "@contoso.com" Parámetro 2 (salida): user.email Parámetro 3 (salida si no hay ninguna coincidencia): user.userprincipalname |
EndWith() | Genera un atributo o una constante si la entrada finaliza con el valor especificado. En caso contrario, puede especificar otra salida si no hay ninguna coincidencia. Por ejemplo, si quiere emitir una notificación en la que el valor es el id. de empleado del usuario, si el id. de empleado termina con 000 ; de lo contrario, se recomienda generar un atributo de extensión. Para realizar esta función, configure los valores siguientes:Parámetro 1 (entrada) : user.employeeid Valor: "000" Parámetro 2 (salida): user.employeeid Parámetro 3 (salida si no hay ninguna coincidencia): user.extensionattribute1 |
StartWith() | Genera un atributo o una constante si la entrada empieza con el valor especificado. En caso contrario, puede especificar otra salida si no hay ninguna coincidencia. Por ejemplo, si quiere emitir una notificación en la que el valor es el id. de empleado del usuario, si el país o la región comienza por US ; de lo contrario, se recomienda generar un atributo de extensión. Para realizar esta función, configure los valores siguientes:Parámetro 1 (entrada) : user.country Valor: "US" Parámetro 2 (salida): user.employeeid Parámetro 3 (salida si no hay ninguna coincidencia): user.extensionattribute1 |
Extract(): después de la coincidencia | Devuelve el valor de substring que aparece después de la coincidencia con el valor especificado. Por ejemplo, si el valor de entrada es Finance_BSimon , el valor coincidente es Finance_ , entonces la salida de la notificación es BSimon . |
Extract(): antes de la coincidencia | Devuelve el valor de substring que aparece antes de la coincidencia con el valor especificado. Por ejemplo, si el valor de entrada es BSimon_US , el valor coincidente es _US , entonces la salida de la notificación es BSimon . |
Extract(): entre coincidencias | Devuelve el valor de substring que aparece antes de la coincidencia con el valor especificado. Por ejemplo, si el valor de la entrada es Finance_BSimon_US , el primer valor coincidente es Finance_ , el segundo valor coincidente es _US , entonces la salida de la notificación es BSimon . |
ExtractAlpha(): prefijo | Devuelve la parte alfabética del prefijo de la cadena. Por ejemplo, si el valor de la entrada es BSimon_123 , entonces devuelve BSimon . |
ExtractAlpha(): sufijo | Devuelve la parte alfabética del sufijo de la cadena. Por ejemplo, si el valor de la entrada es 123_Simon , entonces devuelve Simon . |
ExtractNumeric(): prefijo | Devuelve la parte numérica del prefijo de la cadena. Por ejemplo, si el valor de la entrada es 123_BSimon , entonces devuelve 123 . |
ExtractNumeric(): sufijo | Devuelve la parte numérica del sufijo de la cadena. Por ejemplo, si el valor de la entrada es BSimon_123 , entonces devuelve 123 . |
IfEmpty() | Genera un atributo o una constante si la entrada es nula o está vacía. Por ejemplo, si quieres generar un atributo almacenado en un atributo de extensión si la ID de empleado de un usuario determinado está vacía. Para realizar esta función, configura los siguientes valores: Parámetro 1 (entrada): user.employeeid Parámetro 2 (salida): user.extensionattribute1 Parámetro 3 (salida si no hay ninguna coincidencia): user.employeeid |
IfNotEmpty() | Genera un atributo o una constante si la entrada no es nula ni está vacía. Por ejemplo, si quieres generar un atributo almacenado en un atributo de extensión si la ID de empleado de un usuario determinado no está vacía. Para realizar esta función, configure los valores siguientes: Parámetro 1 (entrada): user.employeeid Parámetro 2 (salida): user.extensionattribute1 |
Substring(): longitud fija | Extrae partes de un tipo de notificación de cadena, comenzando por el carácter que se encuentra en la posición especificada, y devuelve el número de caracteres especificado. SourceClaim: el origen de notificación de la transformación que se debe ejecutar. StartIndex: posición de carácter inicial de base cero de una substring en la instancia. Length: longitud en caracteres de la substring. Por ejemplo: sourceClaim: PleaseExtractThisNow StartIndex: 6 Length: 11 Output: ExtractThis |
Substring() - EndOfString | Extrae partes de un tipo de notificación de cadena, comenzando por el carácter que se encuentra en la posición especificada, y devuelve el resto de la notificación del índice de inicio especificado. SourceClaim: el origen de notificación de la transformación. StartIndex: posición de carácter inicial de base cero de una substring en la instancia. Por ejemplo: sourceClaim: PleaseExtractThisNow StartIndex: 6 Output: ExtractThisNow |
RegexReplace() | La transformación RegexReplace() acepta como parámetros de entrada: - Parámetro 1: un atributo de usuario como entrada de regex - Una opción para confiar en el origen como multivalor - Patrón de regex - Patrón de reemplazo El patrón de reemplazo puede contener formato de texto estático junto con una referencia que apunte a los grupos de salida de expresión regular y más parámetros de entrada. |
Si necesita otras transformaciones, envíe su idea al foro de comentarios de Microsoft Entra ID, en la categoría Aplicación SaaS.
Transformación de notificaciones basada en regex
En la imagen siguiente se muestra un ejemplo del primer nivel de transformación:
En la tabla siguiente se proporciona información sobre el primer nivel de transformaciones. Las acciones enumeradas en la tabla corresponden a las etiquetas de la imagen anterior. Seleccione Editar para abrir la hoja de transformación de reclamaciones.
Acción | Campo | Descripción |
---|---|---|
1 | Transformation |
Seleccione la opción RegexReplace() en las opciones Transformación para usar el método de transformación de notificaciones basada en regex para transformación de notificaciones. |
2 | Parameter 1 |
Entrada de la transformación de expresión regular. Por ejemplo, user.mail que tiene una dirección de correo electrónico de usuario como admin@fabrikam.com . |
3 | Treat source as multivalued |
Algunos atributos de usuario de entrada pueden ser atributos de usuario de varios valores. Si el atributo de usuario seleccionado admite varios valores y el usuario quiere usar varios valores para la transformación, debe seleccione Tratar origen como multivalor. Si esta opción está seleccionada, se usan todos los valores para la coincidencia de regex; de lo contrario, solo se usa el primer valor. |
4 | Regex pattern |
Expresión regular que se evalúa con respecto al valor del atributo de usuario seleccionado como Parámetro 1. Por ejemplo, una expresión regular para extraer el alias de usuario de la dirección de correo electrónico del usuario se representa como (?'domain'^.*?)(?i)(\@fabrikam\.com)$ . |
5 | Add additional parameter |
Se puede usar más de un atributo de usuario para la transformación. Los valores de los atributos se combinarían con la salida de transformación de regex. Se admiten hasta cinco parámetros más. |
6 | Replacement pattern |
El patrón de reemplazo es la plantilla de texto, que contiene marcadores de posición para el resultado de regex. Todos los nombres de grupo deben ir entre llaves, por ejemplo, {nombre-de-grupo}. Supongamos que la administración quiere usar el alias de usuario con algún otro nombre de dominio, por ejemplo, xyz.com y combinar el nombre del país con él. En este caso, el patrón de reemplazo sería {country}.{domain}@xyz.com , donde {country} es el valor del parámetro de entrada y {domain} es la salida del grupo de evaluación de expresiones regulares. En tal caso, el resultado esperado será US.swmal@xyz.com . |
En la imagen siguiente se muestra un ejemplo del segundo nivel de transformación:
En la tabla siguiente se proporciona información sobre el segundo nivel de transformaciones. Las acciones enumeradas en la tabla corresponden a las etiquetas de la imagen anterior.
Acción | Campo | Descripción |
---|---|---|
1 | Transformation |
Las transformaciones de notificaciones basadas en regex no se limitan a la primera transformación y también se pueden usar como transformación de segundo nivel. Cualquier otro método de transformación se puede usar como primera transformación. |
2 | Parameter 1 |
Si se selecciona RegexReplace() como transformación de segundo nivel, la salida de la transformación de primer nivel se usa como entrada para la transformación de segundo nivel. Para aplicar la transformación, la expresión regular de segundo nivel debe coincidir con la salida de la primera transformación. |
3 | Regex pattern |
Patrón de regex es la expresión regular para la transformación de segundo nivel. |
4 | Parameter input |
Entradas de atributo de usuario para las transformaciones de segundo nivel. |
5 | Parameter input |
Los administradores pueden eliminar el parámetro de entrada seleccionado si ya no lo necesitan. |
6 | Replacement pattern |
El patrón de reemplazo es la plantilla de texto, que contiene marcadores de posición para el nombre del grupo de resultados de regex, el nombre del grupo de parámetros de entrada y el valor de texto estático. Todos los nombres de grupo deben ir entre llaves, como {group-name} . Supongamos que la administración quiere usar el alias de usuario con algún otro nombre de dominio, por ejemplo, xyz.com y combinar el nombre del país con él. En este caso, el patrón de reemplazo sería {country}.{domain}@xyz.com , donde {country} es el valor del parámetro de entrada y {domain} es la salida del grupo de evaluación de expresiones regulares. En tal caso, el resultado esperado será US.swmal@xyz.com . |
7 | Test transformation |
La transformación RegexReplace() solo se evalúa si el valor del atributo de usuario seleccionado para Parámetro 1 coincide con la expresión regular proporcionada en el cuadro de texto Patrón de regex. De lo contrario, se agrega el valor de notificación predeterminado al token. Para validar la expresión regular con el valor del parámetro de entrada, hay disponible una experiencia de prueba en la hoja de transformación. Esta experiencia de prueba solo funciona con valores ficticios. Cuando se usan los parámetros de entrada adicionales, el nombre del parámetro se agrega al resultado de la prueba en lugar de al valor real. Para acceder a la sección de prueba, seleccione Probar transformación. |
En la imagen siguiente, se muestra un ejemplo de prueba de las transformaciones:
En la tabla siguiente se proporciona información sobre la prueba de las transformaciones. Las acciones enumeradas en la tabla corresponden a las etiquetas de la imagen anterior.
Acción | Campo | Descripción |
---|---|---|
1 | Test transformation |
Seleccione el botón cerrar o botón con una cruz (X) para ocultar la sección de prueba y que aparezca de nuevo el botón Probar transformación en la hoja. |
2 | Test regex input |
Acepta la entrada que se usa para la evaluación de pruebas de expresiones regulares. Cuando una transformación de notificaciones basada en expresiones regulares se configura como una transformación de segundo nivel, proporciona un valor que sea el resultado esperado de la primera transformación. |
3 | Run test |
Una vez proporcionada la entrada de regex de prueba y configuradas las opciones Patrón de regex, Patrón de reemplazo y Parámetros de entrada, la expresión se puede evaluar seleccionando Ejecutar prueba. |
4 | Test transformation result |
Si la evaluación tiene éxito, se representa una salida de la transformación de prueba en la etiqueta de resultado de la transformación de prueba. |
5 | Remove transformation |
La transformación de segundo nivel se puede quitar seleccionando Quitar transformación. |
6 | Specify output if no match |
Cuando se configura un valor de entrada de regex con respecto al Parámetro 1, que no coincide con la Expresión regular, la transformación se omite. En tales casos, se puede configurar el atributo de usuario alternativo, el cual se agregará al token de la notificación activando la Especificar el resultado si no se encuentran coincidencias. |
7 | Parameter 3 |
Si es necesario devolver un atributo de usuario alternativo cuando no hay ninguna coincidencia y Especificar el resultado si no se encuentran coincidencias está activada, se puede seleccionar un atributo de usuario alternativo mediante la lista desplegable. Esta lista desplegable está disponible en Parámetro 3 (resultado si no hay coincidencias). |
8 | Summary |
En la parte inferior de la hoja, se muestra el resumen completo del formato, que explica el significado de la transformación en texto simple. |
9 | Add |
Una vez comprobadas las opciones de configuración de la transformación, se puede guardar en una directiva de notificaciones seleccionando Agregar. Selecciona Guardar en la hoja Administrar notificación para guardar los cambios. |
La transformación RegexReplace() también está disponible para las transformaciones de notificaciones de grupo.
Validaciones de transformación
Un mensaje proporciona más información cuando se producen las condiciones siguientes después de seleccionar Agregar o Ejecutar prueba:
- Se utilizaron parámetros de entrada con atributos de usuario duplicados.
- Se encontraron parámetros de entrada sin usar. Los parámetros de entrada definidos deben tener un uso respectivo en el texto del patrón de reemplazo.
- La entrada de regex de prueba proporcionada no coincide con la expresión regular proporcionada.
- No se encuentran orígenes para los grupos en el patrón de reemplazo.
Emisión de notificaciones basadas en condiciones
Puede especificar el origen de una notificación en función del tipo de usuario y el grupo al que pertenece el usuario.
El tipo de usuario puede ser:
- Cualquiera: todos los usuarios pueden tener acceso a la aplicación.
- Miembros: Miembro nativo del inquilino
- Todos los invitados: el usuario se movió de una organización externa con o sin Microsoft Entra ID.
- Invitados de Microsoft Entra: el usuario invitado pertenece a otra organización mediante Microsoft Entra ID.
- Invitados externos: el usuario invitado pertenece a una organización externa que no tiene Microsoft Entra ID.
Un escenario en el que el tipo de usuario resulta útil es cuando el origen de una notificación es diferente para un invitado y para un empleado que tiene acceso a una aplicación. Puedes especificar que, si el usuario es un empleado, obtén el NameID de user.email. Si el usuario es un invitado, el NameID proviene de user.extensionattribute1.
Para agregar una condición de notificaciones:
- En Administrar notificaciones, expanda las Condiciones de la notificación.
- Seleccione el tipo de usuario.
- Seleccione los grupos a los que debe pertenecer el usuario. Puede seleccionar hasta 50 grupos únicos en todas las notificaciones para una aplicación determinada.
- Seleccione el origen en el que la notificación va a recuperar su valor. Puede seleccionar un atributo de usuario en la lista desplegable de atributos de origen o aplicar una transformación al atributo de usuario antes de emitirlo como una notificación.
El orden en que se agregan las condiciones es importante. En primer lugar, Microsoft Entra evalúa todas las condiciones con el origen Attribute
y, a continuación, evalúa todas las condiciones con el origen Transformation
para decidir qué valor emitir en la notificación. Microsoft Entra ID evalúa las condiciones con el mismo origen de arriba a abajo. La notificación emite el último valor que coincide con la expresión de la notificación. Transformaciones como IsNotEmpty
y Contains
actúan como restricciones.
Por ejemplo, Britta Simon es un usuario invitado en el suscriptor de Contoso. Britta pertenece a otra organización que también usa Microsoft Entra ID. Dada la siguiente configuración para la aplicación de Fabrikam, cuando Britta intenta iniciar sesión en Fabrikam, la Plataforma de identidad de Microsoft evalúa las condiciones.
En primer lugar, la Plataforma de identidad de Microsoft comprueba si el tipo de usuario de Britta es Todos los invitados. Dado que el tipo de usuario es Todos los invitados, la plataforma de identidad de Microsoft asigna el origen de la notificación a user.extensionattribute1
. En segundo lugar, la Plataforma de identidad de Microsoft comprueba si el tipo de usuario de Britta es Invitados de Microsoft Entra. Dado que el tipo de usuario es Todos los invitados, la plataforma de identidad de Microsoft asigna el origen de la notificación a user.mail
. Por último, la notificación se emite con un valor de user.mail
para Britta.
Como otro ejemplo, considera cuando Britta Simon intenta iniciar sesión con la siguiente configuración. En primer lugar,Microsoft Entra evalúa todas las condiciones con el origen Attribute
. El origen de la notificación es user.mail
cuando el tipo de usuario de Britta es invitados de Microsoft Entra. A continuación, Microsoft Entra ID evalúa las transformaciones. Dado que Britta es un invitado, user.extensionattribute1
es el nuevo origen de la notificación. Dado que Britta está en Invitados de Microsoft Entra, user.othermail
es el nuevo origen de esta notificación. Por último, la notificación se emite con un valor de user.othermail
para Britta.
Como ejemplo final, veamos lo que sucede si Britta no tiene configurado user.othermail
o está vacío. La notificación vuelve a user.extensionattribute1
ignorando la entrada de condición en ambos casos.
Consideraciones sobre la seguridad
Las aplicaciones que reciben tokens confían en los valores que no pueden ser manipulados. Al modificar el contenido de los tokens mediante la personalización de las notificaciones, estas suposiciones pueden dejar de ser correctas. Las aplicaciones deben reconocer explícitamente que los tokens han sido modificados para protegerse de las personalizaciones creadas por actores malintencionados. Proteja frente a personalizaciones inapropiadas de una de las maneras siguientes:
- Configurar una clave de firma personalizada
- actualice la aplicación para aceptar notificaciones asignadas.
Sin esto, Microsoft Entra ID devuelve un código de error AADSTS50146.
Configurar una clave de firma personalizada
Para aplicaciones multi inquilino, se debe utilizar una clave de firma personalizada. No establezca acceptMappedClaims
en el manifiesto de la aplicación. Al configurar una aplicación en el portal de Azure, se obtiene un objeto de registro de aplicación y un servicio principal en el inquilino. Esa aplicación usa la clave de inicio de sesión global de Azure, que no se puede usar para personalizar las notificaciones en los tokens. Para obtener notificaciones personalizadas en los tokens, cree una clave de inicio de sesión personalizada a partir de un certificado y agréguela a la entidad de servicio. Para fines de prueba, puede usar un certificado autofirmado. Después de configurar la clave de firma personalizada, el código de la aplicación debe validar la clave de firma de token.
Agregue la siguiente información a la entidad de servicio:
- Clave privada (como credenciales de clave)
- Contraseña (como credenciales de contraseña)
- Clave privada (como credenciales de clave)
Extraiga las claves pública y privada codificadas en base 64 de la exportación de archivos PFX del certificado. Asegúrese de que el valor keyId
de keyCredential
que se usa para "Sign" coincide con el valor keyId
de passwordCredential
. Puede generar el customkeyIdentifier
obteniendo el hash de la huella digital del certificado.
Solicitud
Nota:
En primer lugar, deshabilite cualquier configuración de bloqueo de entidad de servicio en las aplicaciones recién creadas desde la hoja registros de aplicaciones del centro de administración de Microsoft Entra antes de intentar realizar un PATCH en la entidad de servicio, lo que da lugar a una solicitud incorrecta 400.
El siguiente ejemplo muestra el formato de la solicitud HTTP PATCH para agregar una clave de firma personalizada a una entidad de servicio. El valor "key" de la propiedad keyCredentials
se acorta para mejorar la legibilidad. El valor está codificado en base 64. En la clave privada, el uso de la propiedad es Sign
. En la clave pública, el uso de la propiedad es Verify
.
PATCH https://graph.microsoft.com/v1.0/servicePrincipals/aaaaaaaa-bbbb-cccc-1111-222222222222
Content-type: servicePrincipals/json
Authorization: Bearer {token}
{
"keyCredentials":[
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"endDateTime": "2021-04-22T22:10:13Z",
"keyId": "aaaaaaaa-0b0b-1c1c-2d2d-333333333333",
"startDateTime": "2020-04-22T21:50:13Z",
"type": "X509CertAndPassword",
"usage": "Sign",
"key":"cD2eF3gH4iJ5kL6mN7-oP8qR9sT==",
"displayName": "CN=contoso"
},
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"endDateTime": "2021-04-22T22:10:13Z",
"keyId": "bbbbbbbb-1c1c-2d2d-3e3e-444444444444",
"startDateTime": "2020-04-22T21:50:13Z",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"key": "cD2eF3gH4iJ5kL6mN7-oP8qR9sT==",
"displayName": "CN=contoso"
}
],
"passwordCredentials": [
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"keyId": "cccccccc-2d2d-3e3e-4f4f-555555555555",
"endDateTime": "2022-01-27T19:40:33Z",
"startDateTime": "2020-04-20T19:40:33Z",
"secretText": "mypassword"
}
]
}
Configurar una clave de firma personalizada con PowerShell
Use PowerShell para crear instancias de una aplicación cliente pública de MSAL y usar el flujo de concesión de código de autorización para obtener un token de acceso de permiso delegado para Microsoft Graph. Use el token de acceso para llamar a Microsoft Graph y configurar una clave de firma personalizada para la entidad de servicio. Después de configurar la clave de firma personalizada, el código de la aplicación debe validar la clave de firma de token.
Para ejecutar el script, necesita lo siguiente:
- El Id. de objeto de la entidad de seguridad de servicio de su aplicación, que se encuentra en la hoja Información general de la entrada de su aplicación en Aplicaciones empresariales en el Azure portal.
- Un registro de la aplicación para iniciar la sesión de un usuario y obtener un token de acceso para llamar a Microsoft Graph. Obtenga el identificador de esta aplicación (cliente) en la hoja Información general de la entrada de la aplicación en Registros de aplicaciones en Azure Portal. El registro de la aplicación debe tener la configuración siguiente:
- Un identificador URI de redireccionamiento de "http://localhost"", que aparece en la configuración de la plataforma Aplicaciones móviles y de escritorio.
- En Permisos de API, los permisos delegados de Microsoft Graph Application.ReadWrite.All y User.Read (asegúrese de conceder consentimiento del administrador a estos permisos).
- Un usuario que inicie sesión para obtener el token de acceso de Microsoft Graph. El usuario debe tener uno de los siguientes roles administrativos de Microsoft Entra (necesarios para actualizar la entidad de servicio):
- Administrador de aplicaciones en la nube
- Administrador de aplicaciones
- Un certificado que se configurará como clave de firma personalizada para nuestra aplicación. Puede crear un certificado autofirmado o bien obtener uno de la entidad de certificación de confianza. En el script se usan los componentes del certificado siguientes:
- clave pública (normalmente un archivo .cer)
- clave privada en formato PKCS#12 (en archivo .pfx)
- contraseña de la clave privada (archivo .pfx)
Importante
La clave privada debe estar en formato PKCS #12, ya que Microsoft Entra ID no admite otros tipos de formato. Si se usa un formato incorrecto, puede producirse un error de tipo "Certificado no válido: el valor de la clave es un certificado no válido" al usar Microsoft Graph para aplicar PATCH a la entidad de servicio con un keyCredentials
que contenga la información del certificado.
##########################################################
# Replace the variables below with the appropriate values
$fqdn="yourDomainHere" # This is used for the 'issued to' and 'issued by' field of the certificate
$pwd="password" # password for exporting the certificate private key
$tenantId = "aaaabbbb-0000-cccc-1111-dddd2222eeee" # Replace with your Tenant ID
$appObjId = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" # Replace with the Object ID of the App Registration
##########################################################
# Create a self-signed cert
$cert = New-SelfSignedCertificate -certstorelocation cert:\currentuser\my -DnsName $fqdn
$pwdSecure = ConvertTo-SecureString -String $pwd -Force -AsPlainText
$path = 'cert:\currentuser\my\' + $cert.Thumbprint
$location="C:\\temp" # path to folder where both the pfx and cer file will be written to
$cerFile = $location + "\\" + $fqdn + ".cer"
$pfxFile = $location + "\\" + $fqdn + ".pfx"
# Export the public and private keys
Export-PfxCertificate -cert $path -FilePath $pfxFile -Password $pwdSecure
Export-Certificate -cert $path -FilePath $cerFile
$pfxpath = $pfxFile # path to pfx file
$cerpath = $cerFile # path to cer file
$password = $pwd # password for the pfx file
# Check PowerShell version (minimum 5.1) (.Net) or PowerShell Core (.Net Core) and read the certificate file accordingly
if ($PSVersionTable.PSVersion.Major -gt 5)
{
$core = $true
}
else
{
$core = $false
}
# this is for PowerShell Core
$Secure_String_Pwd = ConvertTo-SecureString $password -AsPlainText -Force
# reading certificate files and creating Certificate Object
if ($core)
{
$pfx_cert = get-content $pfxpath -AsByteStream -Raw
$cer_cert = get-content $cerpath -AsByteStream -Raw
$cert = Get-PfxCertificate -FilePath $pfxpath -Password $Secure_String_Pwd
}
else
{
$pfx_cert = get-content $pfxpath -Encoding Byte
$cer_cert = get-content $cerpath -Encoding Byte
# calling Get-PfxCertificate in PowerShell 5.1 prompts for password - using alternative method
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfxpath, $password)
}
# base 64 encode the private key and public key
$base64pfx = [System.Convert]::ToBase64String($pfx_cert)
$base64cer = [System.Convert]::ToBase64String($cer_cert)
# getting id for the keyCredential object
$guid1 = New-Guid
$guid2 = New-Guid
# get the custom key identifier from the certificate thumbprint:
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
$hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($cert.Thumbprint))
$customKeyIdentifier = [System.Convert]::ToBase64String($hash)
# get end date and start date for our keycredentials
$endDateTime = ($cert.NotAfter).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
$startDateTime = ($cert.NotBefore).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
# building our json payload
$object = [ordered]@{
keyCredentials = @(
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
endDateTime = $endDateTime
keyId = $guid1
startDateTime = $startDateTime
type = "AsymmetricX509Cert"
usage = "Sign"
key = $base64pfx
displayName = "CN=$fqdn"
},
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
endDateTime = $endDateTime
keyId = $guid2
startDateTime = $startDateTime
type = "AsymmetricX509Cert"
usage = "Verify"
key = $base64cer
displayName = "CN=$fqdn"
}
)
passwordCredentials = @(
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
displayName = "CN=$fqdn"
keyId = $guid1
endDateTime = $endDateTime
startDateTime = $startDateTime
secretText = $password
hint = $null
}
)
}
Connect-MgGraph -tenantId $tenantId -Scopes Application.ReadWrite.All
$graphuri = "https://graph.microsoft.com/v1.0/applications/$appObjId"
Invoke-MgGraphRequest -Method PATCH -Uri $graphuri -Body $object
$json = $object | ConvertTo-Json -Depth 99
Write-Host "JSON Payload:"
Write-Output $json
Validar la clave de firma de tokens
Las aplicaciones que tienen habilitada la asignación de notificaciones deben validar sus claves de firma de tokens mediante la anexión de appid={client_id}
a las solicitudes de metadatos de OpenID Connect. El siguiente ejemplo muestra el formato del documento de metadatos de OpenID Connect que debe usar:
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}
Actualización del manifiesto de aplicación
Para las aplicaciones de inquilino único, puede establecer la propiedad acceptMappedClaims
en true
en el manifiesto de aplicación. Como se documenta en el apiApplication
tipo de recurso. Establecer la propiedad permite que una aplicación use la asignación de notificaciones sin especificar ninguna clave de firma personalizada.
Advertencia
No establezca la propiedad acceptMappedClaims en true en aplicaciones multiinquilino, ya que puede permitir a agentes malintencionados crear directivas de asignación de reclamaciones para su aplicación.
Es necesario que el público del token solicitado use un nombre de dominio verificado de su inquilino de Microsoft Entra, lo que significa que debe establecer el Application ID URI
(representado por el identifierUris
en el manifiesto de la aplicación) por ejemplo a https://contoso.com/my-api
o (simplemente usando el nombre de inquilino predeterminado)https://contoso.onmicrosoft.com/my-api
.
Si no está usando un dominio verificado, Microsoft Entra devuelve un código de error AADSTS501461
con el mensaje "_AcceptMappedClaims solo se admite para un público de tokens que coincida con el GUID de la aplicación o un público dentro de los dominios verificados del inquilino". Cambie el identificador de recurso o use una clave de firma específica de la aplicación".
Opciones de notificaciones avanzadas
Configura las opciones de notificaciones avanzadas para que las aplicaciones OIDC expongan la misma notificación que los tokens SAML. También para aplicaciones que pretenden usar el mismo reclamo para tokens de respuesta SAML2.0 y OIDC.
Configura las opciones de reclamos avanzados marcando la casilla debajo de Opciones de notificaciones avanzadas en la hoja Administrar notificaciones.