Funciones de Azure y autenticación de Azure AD
Esta publicación es parte de una serie sobre Azure Functions y PowerShell. ¡Consulta la lista de otras publicaciones de la serie!
Funciones de Azure y autenticación de Azure AD
Las funciones de Azure son fáciles, económicas y escalables.
PowerShell es un lenguaje poderoso perfecto para automatizar y crear integraciones que "pegan" sistemas.
Esta es una combinación perfecta para mí, pero ¿cómo sé y valido quién llama a mi código? Aquí es donde la autenticación entra en escena. La autenticación consiste en verificar quién se conecta a mi aplicación para que yo (o mi código) podamos determinar si deben estar autorizados para hacerlo o no.
Requerir que el usuario de Azure AD inicie sesión en Azure Functions
Empecemos de forma sencilla. Quiero que los usuarios se autentiquen con AzureAD cuando llamen a mi función.
Este escenario es realmente simple porque es una característica incluida en Azure Functions o, para ser justos, está incluida en Azure App Service sobre la cual se basan las funciones. Esta función se puede habilitar en uno de los dos modos de administración, Express o Advanced. Y como me gusta entender realmente cómo funcionan las cosas, los cubriré a ambos.
La función que utilizamos para esto solía llamarse easyauth. La búsqueda de Azure App Service y easyauth o “easy auth” puede brindarle información valiosa.
Elegir entre el modo Express y Advanced para la autenticación
Como en la mayoría de los otros casos, hay una manera fácil y una manera menos fácil de hacer las cosas. En este caso, la forma fácil se llama modo Express. Para citar la explicación al pasar el mouse:
“El modo Express utilizará su AAD predeterminado y puede crear una aplicación AAD para usted. Seleccione el modo avanzado si desea tener una configuración de AAD personalizada”
El modo Express se puede configurar en segundos y funciona para la mayoría de los escenarios simples, pero solo puedes configurarlo una vez y a menudo termino en una situación en la que quiero cambiar las cosas más tarde, lo cual es un poco más difícil cuando uso el modo Express.
También hay otro inconveniente del modo exprés que debes tener en cuenta. Al momento de escribir esto en octubre de 2020, el modo rápido configura una aplicación Azure AD V1. Si queremos utilizar el punto final V2 más nuevo, debemos utilizar el modo avanzado. Microsoft recomienda utilizar el punto final V2 para nuevos proyectos. Consulte por qué actualizar a Microsoft Identity Platform (v2.0) para obtener más información.
Modo de autenticación Express de Active Directory
En este escenario, asumo que tenemos una aplicación de función en funcionamiento y que el usuario que realiza estos pasos puede registrar aplicaciones en Azure Active Directory.
Comience yendo a la hoja "Autenticación/Autorización".
Como nos indica el texto de advertencia, debemos tener nuestra configuración SSL en orden, usar la versión .NET 4.5 o superior y configurar el modo de administración de canalización en "integrado". Dado que esta es la configuración predeterminada para una nueva aplicación de funciones, no entraré en esto aquí.
Active la autenticación de App Service y configure el menú desplegable "Acción a realizar cuando la solicitud no está autenticada" en "Iniciar sesión con Azure Active Directory". Esto redirigirá cualquier solicitud no autenticada a un mensaje de inicio de sesión.
En Proveedores de autenticación, haga clic en Azure Active Directory.
Una vez en la configuración de Azure Active Directory, cambie el Modo de administración de Desactivado a Rápido, elija un buen nombre para su nueva aplicación (debe ser única en su inquilino), deje el resto como está y haga clic en Aceptar.
Una vez de regreso en la hoja de autenticación/autorización, no olvide hacer clic en el botón Guardar.
¡Y así de simple! ¡Ahora tenemos una función que requiere autenticación de Azure AD! ¡Probémoslo!
Obtenga la URL de una función yendo a Funciones, elija una función, en mi caso "HttpTrigger1" y haga clic en "Obtener URL de función" en la parte superior de la hoja.
Ingrese la URL de función completa en un navegador web y será redirigido a un mensaje de inicio de sesión. Si es la primera vez que inicia sesión en esta aplicación, se le presentará una solicitud de consentimiento.
Si es administrador de aplicaciones en el inquilino, también verá una casilla de verificación que dice "Consentimiento en nombre de su organización". Simplemente haciendo clic en Aceptar se aceptará solo para el usuario actual. Al marcar la casilla y luego hacer clic en aceptar, se otorgará a la aplicación el consentimiento para cada usuario del inquilino, el llamado consentimiento del administrador.
Para no recibir esta pregunta en absoluto, podemos otorgar el consentimiento del administrador antes de intentar iniciar sesión. Esto se puede hacer en el Portal de Azure navegando a Azure Active Directory y a la hoja Registros de aplicaciones. Seleccione la pestaña "Todas las aplicaciones", ubique la aplicación que acaba de crear y baje a "Permisos API" en el menú de la izquierda. En la nueva hoja que se abre podemos ver que la aplicación requiere el permiso delegado de User.Read para Graph API. Para aprobar esto para todos los usuarios de su organización, simplemente haga clic en "Otorgar consentimiento de administrador para
¡Y eso es!
Modo avanzado de autenticación de Active Directory
Si alguna de las afirmaciones siguientes es cierta, probablemente desee utilizar la configuración avanzada de Autorización.
- Quiero usar la nueva plataforma de identidad de Microsoft
- Quiero usar una aplicación registrada en otro inquilino de Azure AD
- Quiero un mejor control y comprensión de lo que configuro
- No tengo acceso para crear aplicaciones por mi cuenta y necesito pedirle a alguien que las cree por mí.
Para configurar la Autorización con configuraciones avanzadas, primero debemos crear un registro de aplicación para nuestra API.
Como no soy partidario de hacer clic en portales, me gusta hacerlo con algún tipo de script. Esta vez usaré la CLI de Azure desde PowerShell. Actualice el nombre para mostrar y el identificador uri para que se ajusten a su escenario y ejecute el script.
Este script hace algunas cosas. Primero, estoy configurando un nombre para mostrar para mi aplicación y el nombre de mi aplicación Functions.
Luego, estoy recopilando algunos permisos de acceso que mi aplicación requiere para obtener información sobre el usuario que inició sesión. Hago esto para poder dar su consentimiento a todos estos permisos en mi secuencia de comandos y no tener que ver nunca ese cuadro de diálogo de consentimiento.
Una vez que tenemos toda esa información, creamos la aplicación usando az ad app create y una entidad de servicio usando az ad sp create.
Luego otorgamos los permisos email, openid y perfil para todos los usuarios, esta es la parte de consentimiento.
Por último, configuramos requestedAccessTokenVersion en el valor 2. Esto establecerá el valor accessTokenAcceptedVersion en nuestro manifiesto en 2 y le indicará a Azure AD que queremos tokens de punto final V2. Ahora la CLI de Azure usa la API Graph de Azure AD que no admite esto, por lo que estoy usando az rest para llamar a Microsoft Graph para este paso.
$ServerAppDisplayName = 'MySuperAPI'
$SystemName = 'mycoolfunction'
# Get tenant id of current tenant
# (make sure to be signed in with az cli)
$TenantId = az account show --query 'tenantId' -o tsv
# Server app identifier, needs to be unique
# I'll default to an azure websites url
# Update to something that fits you
$ServerAppIdentifierUri = "https://$SystemName.azurewebsites.net"
# ReplyUris, this is where AzureAD will send the token.
# Make sure to get this right!
$ReplyUri = "https://$SystemName.azurewebsites.net/.auth/login/aad/callback"
# Create configuration for delegated permissions to graph API
# Get application id of Microsoft Graph
$GraphAppId = az ad sp list --query '[?appDisplayName==''Microsoft Graph''].appId' -o tsv --all
# Get all permissions available to graph
$Permissions = az ad sp show --id $GraphAppId --query 'oauth2Permissions' | ConvertFrom-Json
# Select the permissions we need
$EmailPermission = $Permissions.Where{ $_.value -eq 'email' }.id
$ProfilePermission = $Permissions.Where{ $_.value -eq 'profile' }.id
$OpenIdPermission = $Permissions.Where{ $_.value -eq 'openid' }.id
# Build part of a manifest for requiredResourceAccess
$requiredResourceAccess = @(
@{
resourceAppId = $GraphAppId
resourceAccess = @(
@{
id = $EmailPermission
type = 'Scope'
},
@{
id = $ProfilePermission
type = 'Scope'
},
@{
id = $OpenIdPermission
type = 'Scope'
}
)
}
) | ConvertTo-Json -AsArray -Depth 4 -Compress | ConvertTo-Json
# Pipe to ConvertTo-Json twice to escape all quotes, or az cli will remove them when parsing
# Register the application
$ServerApp = az ad app create --display-name $ServerAppDisplayName --identifier-uris $ServerAppIdentifierUri --required-resource-accesses $requiredResourceAccess --reply-urls $ReplyUri | ConvertFrom-Json
# Create a service principal for the application
$null = az ad sp create --id $ServerApp.AppId
# Consent the application for all users
$null = az ad app permission grant --id $ServerApp.AppId --api $GraphAppId --scope "email openid profile"
# Set application to use V2 access tokens
$Body = @{
api = @{
requestedAccessTokenVersion = 2
}
} | ConvertTo-Json -Compress | ConvertTo-Json
# Pipe to ConvertTo-Json twice to escape all quotes, or az cli will remove them when parsing
$null = az rest --method PATCH --uri "https://graph.microsoft.com/v1.0/applications/$($ServerApp.objectId)" --body $Body --headers "Content-Type=application/json"
# Output the ClientId for use later
Write-Output $ServerApp.AppId
En mi caso obtuve el AppId de c491d3f8-0d15-4ea5-96fd-957601d579fa. Esto también se conoce como clientId de mi aplicación. Necesitaremos esto más tarde, así que asegúrese de anotarlo.
Vayamos a nuestra aplicación de funciones en el Portal de Azure. Navegue hasta la hoja Autenticación/Autorización, elija
Esta vez seleccionaremos Avanzado en lugar de Express. Aquí debemos ingresar el ClientId (AppId) de nuestro registro anterior, así como una URL del emisor. La URL del emisor consta de las siguientes partes: “az account show o usando el comando de PowerShell Get-AzContext.
Y ahora deberíamos poder navegar hasta nuestra función, ser redirigidos a una página de inicio de sesión y luego llegar a nuestra función. ¡Simple como eso!
Conclusiones para la autenticación
En resumen, si está dispuesto a dedicar unos minutos en lugar de unos segundos a configurar la autenticación, ¡puede valer la pena el esfuerzo por la llamada ruta avanzada!
Como hemos visto anteriormente, para obtener tokens de acceso necesitamos una aplicación registrada en Azure AD. Las aplicaciones que hemos creado hasta ahora están diseñadas para actuar como una aplicación de servidor web. Esto significa que cuando un usuario inicia sesión, el emisor del token (Azure AD en nuestro caso) no devolverá el token de acceso al cliente, Azure AD lo enviará al URI de redireccionamiento especificado por el cliente. Azure AD solo aceptará los URI de redireccionamiento que figuran en el registro de nuestra aplicación. Esto significa que es EXTREMADAMENTE importante agregar los redireccionURI correctos y solo esos.
En el escenario avanzado anterior, configuramos este URI de redireccionamiento a nuestro URI de funciones seguido de "/.auth/login/aad/callback".





