<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JoseLCAguilar &#8211; JoseLCAguilar</title>
	<atom:link href="https://www.joselcaguilar.com/author/joselca92/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.joselcaguilar.com</link>
	<description></description>
	<lastBuildDate>Sun, 14 Apr 2019 23:44:31 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.8</generator>

<image>
	<url>https://www.joselcaguilar.com/wp-content/uploads/2018/02/Favicon_64x64.png</url>
	<title>JoseLCAguilar &#8211; JoseLCAguilar</title>
	<link>https://www.joselcaguilar.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Azure Functions &#038; MSI vs. Key Vault Rest API</title>
		<link>https://www.joselcaguilar.com/2018/06/azure-functions-msi-vs-key-vault-rest-api/</link>
					<comments>https://www.joselcaguilar.com/2018/06/azure-functions-msi-vs-key-vault-rest-api/#respond</comments>
		
		<dc:creator><![CDATA[JoseLCAguilar]]></dc:creator>
		<pubDate>Mon, 25 Jun 2018 17:29:35 +0000</pubDate>
				<category><![CDATA[Azure Functions]]></category>
		<category><![CDATA[Key Vaults]]></category>
		<category><![CDATA[MSI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure PowerShell]]></category>
		<category><![CDATA[AzureRM]]></category>
		<guid isPermaLink="false">https://www.joselcaguilar.com/?p=232</guid>

					<description><![CDATA[Buenas tardes a tod@s, En [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="color: #000000;">Buenas tardes a tod@s,</span></p>
<p><span style="color: #000000;">En otra entrega más por este fabuloso y cambiante mundo del <strong>Cloud Computing</strong>, me gustaría presentaros un reto, el cual, en el momento que estoy escribiendo esta entrada <strong>2</strong> de los <strong>servicios</strong> que voy a enseñar se encuentran en modo <strong>Preview</strong>, pero&#8230; ¿quién dice que la proactividad e investigación no deba estar por delante para recomendar lo mejor a tus clientes, y más, cuando tratamos temas de <strong>seguridad</strong>?</span></p>
<p><span style="color: #000000;">¿Cuántas veces no hemos escrito <strong>credenciales hardcodeadas</strong> en un <strong>script/app</strong> al picar el código y se nos ha quedado ahí al compartirlo o simplemente al llevarlo a producción?</span></p>
<p><span style="color: #000000;">Por suerte a la hora de compartir, tenemos gracias a <strong>GIT</strong> un archivo brillante denominado <a href="https://git-scm.com/docs/gitignore">.gitignore</a> en el cual podemos almacenar nuestras credenciales y no se sincronizarán, pero, ¿y si quisiéramos dejar corriendo una <strong>aplicación</strong> o <strong>script</strong> en modo <strong>serverless</strong>? ¿y si me comprometen el acceso a la <strong>webapp</strong> o símplemente me consiguen impersonar el usuario?</span></p>
<p><span style="color: #000000;">Ya es hora de cambiar eso, así que, en esta entrada, vamos a mostrar la posibilidad de olvidarnos de credenciales en <strong>Azure Functions</strong> gracias a <strong>Management Service Identity</strong> y <strong>Key Vaults</strong>.</span></p>
<p><span style="color: #000000;">Para aquel o aquella que no sepa de qué hablo, pongo un poco en contexto:</span></p>
<ul>
<li><strong>Azure Functions:</strong> Nos permite <strong>ejecutar código a petición</strong> sin necesidad de aprovisionar ni administrar explícitamente la infraestructura, ese código puede ser ejecutado mediante llamadas webhook, scheduler, etc.</li>
</ul>
<p style="padding-left: 60px;"><span style="color: #000000;">Más info: </span><a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview">https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview</a></p>
<ul>
<li><strong>Managed Service Identity:</strong> Proporciona a los servicios de Azure una <strong>identidad administrada</strong> automáticamente en <strong>Azure Active Directory</strong>.</li>
</ul>
<p style="padding-left: 60px;"><span style="color: #000000;">Más info y servicios disponibles actualmente:</span> <a href="https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/services-support-msi">https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/services-support-msi</a></p>
<ul>
<li><strong>Key Vaults: </strong>Ayuda a proteger claves criptográficas y secretos usados por servicios y aplicaciones en la nube a través del uso de claves que están protegidas por <strong>módulos de seguridad de hardware (HSM)</strong>.</li>
</ul>
<p style="padding-left: 60px;"><span style="color: #000000;">Más info:</span> <a href="https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis">https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis</a></p>
<p><span style="color: #000000;">Ahora que nos hemos puesto un poco en contexto, comentar que los dos servicios en <strong>Preview</strong> actualmente son: <strong>Azure Functions</strong> haciendo uso de <strong>PowerShell</strong> y <strong>MSI</strong> (Managed Service Identity).</span></p>
<p><span style="color: #000000;">Pues bien, es hora de ponernos manos a la obra, mediante los siguientes pasos:</span></p>
<ul>
<li>Creamos nuestra aplicación de identidad administrada habilitando <strong>Managed Service Identity</strong> en nuestra función, dentro del mismo blade de <strong>Azure Functions</strong>:</li>
</ul>
<p><img fetchpriority="high" decoding="async" class="aligncenter size-large wp-image-233" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-1024x399.png" alt="" width="640" height="249" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-1024x399.png 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-300x117.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-768x299.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-500x195.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-950x370.png 950w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1-900x351.png 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions1.png 1050w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p><img decoding="async" class="aligncenter wp-image-256" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions2.jpg" alt="" width="374" height="128" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions2.jpg 739w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions2-300x103.jpg 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AzureFunctions2-500x171.jpg 500w" sizes="(max-width: 374px) 100vw, 374px" /></p>
<ul>
<li>Una vez creada, procedemos a <strong>dar permisos</strong> a nuestra aplicación administrada sobre las <strong>políticas de acceso</strong> de nuestro <strong>Key Vault</strong> para poder así obtener los secretos:</li>
</ul>
<p><img decoding="async" class="aligncenter size-large wp-image-235" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-1024x430.png" alt="" width="640" height="269" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-1024x430.png 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-300x126.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-768x323.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-500x210.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-1166x490.png 1166w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-881x370.png 881w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies-900x378.png 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultAccessPolicies.png 1514w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<ul>
<li>Imaginemos que hemos insertado <strong>2 Secrets</strong> manualmente, por ejemplo, <strong>appId</strong> y <strong>appKey</strong> para que otro <strong>SPN</strong> realice la autenticación con Azure en nuestra aplicación, a continuación mostraremos el caso de <strong>appId</strong>:</li>
</ul>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-236 " src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets.png" alt="" width="448" height="211" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets.png 847w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets-300x141.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets-768x362.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets-500x236.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/KeyVaultSecrets-785x370.png 785w" sizes="auto, (max-width: 448px) 100vw, 448px" /></p>
<ul>
<li>En este último punto, veremos cómo se realizaría la parte del código en <strong>PowerShell</strong>, pero de igual manera, al tratarse de un <strong>GET</strong> a la <strong>REST API</strong> de <strong>Azure</strong> podemos realizar de manera similar la llamada para obtener nuestro secreto deseado con <strong>cualquier lenguaje</strong> que soporte <strong>Azure Functions</strong>:</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">$vaultName = "z0"
$vaultSecretName = "appId"

$tokenAuthURI = $Env:MSI_ENDPOINT + "?resource=https://vault.azure.net&amp;api-version=2017-09-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers @{"Secret"="$env:MSI_SECRET"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
Write-Output $accessToken

$headers = @{ 'Authorization' = "Bearer $accessToken" }
$queryUrl = "https://$vaultName.vault.azure.net/secrets/" +$vaultSecretName + "?api-version=2016-10-01"

$keyResponse = Invoke-RestMethod -Method GET -Uri $queryUrl -Headers $headers

Write-Output $KeyResponse.value</code></pre>
<p><span style="color: #000000;">Si nos fijamos en el código, estamos solicitando nuestro token a un audience diferente (<a href="https://vault.azure.net">https://vault.azure.net</a>), nos ocurre algo parecido a la </span><a href="https://www.joselcaguilar.com/2018/06/autenticacion-azure-sql-service-principal-en-powershell/">entrada anterior</a><span style="color: #000000;">, debemos de tenerlo en cuenta para no llamar al audience por defecto.</span></p>
<p><span style="color: #000000;">Si decodificamos nuestro token con la herramienta proporcionada por <a href="https://jwt.io/">jwt.io</a> podemos ver que la estructura es correcta:</span></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-238" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-1024x410.png" alt="" width="640" height="256" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-1024x410.png 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-300x120.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-768x307.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-500x200.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-1225x490.png 1225w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-925x370.png 925w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault-900x360.png 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/JWTAudienceKeyVault.png 1705w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p><span style="color: #000000;">En la variable <strong>$KeyResponse.value</strong> ya tendríamos nuestro secret <strong>AppId</strong>, podemos ver su valor si activamos el trigger de la función:</span></p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-237" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/ExecutionAzureFunction.jpg" alt="" width="391" height="287" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/ExecutionAzureFunction.jpg 569w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/ExecutionAzureFunction-300x220.jpg 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/ExecutionAzureFunction-454x333.jpg 454w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/ExecutionAzureFunction-505x370.jpg 505w" sizes="auto, (max-width: 391px) 100vw, 391px" /></p>
<p><span style="color: #000000;"><em>No olvidéis que la <strong>seguridad</strong> sustenta uno de los pilares principales de toda empresa y desarrollador, saquemos ese perfil <strong>DevOps</strong></em> que llevamos dentro <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.joselcaguilar.com/2018/06/azure-functions-msi-vs-key-vault-rest-api/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure SQL y Service Principals en PowerShell</title>
		<link>https://www.joselcaguilar.com/2018/06/autenticacion-azure-sql-service-principal-en-powershell/</link>
					<comments>https://www.joselcaguilar.com/2018/06/autenticacion-azure-sql-service-principal-en-powershell/#respond</comments>
		
		<dc:creator><![CDATA[JoseLCAguilar]]></dc:creator>
		<pubDate>Thu, 07 Jun 2018 08:53:12 +0000</pubDate>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Service Principals]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Aplicacion]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure Active Directory]]></category>
		<category><![CDATA[Azure SQL]]></category>
		<category><![CDATA[AzureRM]]></category>
		<category><![CDATA[Service Principal]]></category>
		<guid isPermaLink="false">https://www.joselcaguilar.com/?p=191</guid>

					<description><![CDATA[¡Hola a tod@s! Después de [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="color: #000000;">¡Hola a tod@s!</span></p>
<p><span style="color: #000000;">Después de un tiempo sin escribir debido a motivos laborales y el máster de ciberseguridad a punto de finalizar, nos aventuraremos a realizar algo en lo que no encontré mucha documentación en la web, pero necesario para mejorar la <strong>seguridad</strong> en los mismos y centralizar la autenticación en AAD, exactamente explicaré cómo realizar una autenticación mediante un Service Principal en Azure SQL haciendo uso de nuestra gran arma: <strong>PowerShell</strong>.</span></p>
<p><span style="color: #000000;">Debemos de tener generado nuestro Service Principal, en caso de que así no sea, es tan sencillo como dirigirnos a <strong>Azure Active Directory</strong> y registrar una nueva aplicación de tipo <strong>Web App/API</strong> indicando un <strong>URI Endpoint</strong> cualquiera:</span></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-198" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-1024x675.jpg" alt="" width="640" height="422" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-1024x675.jpg 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-300x198.jpg 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-768x506.jpg 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-500x329.jpg 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-744x490.jpg 744w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-562x370.jpg 562w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal-900x593.jpg 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-1-ServicePrincipal.jpg 1726w" sizes="auto, (max-width: 640px) 100vw, 640px" /><br />
<span style="color: #000000;">Apuntamos el <strong>Application Id</strong> que nos genera, además debemos de obtener un <strong>Secret</strong>, para ello nos vamos al apartado de <strong>Keys</strong> y generamos 1 con la fecha de expiración que deseemos apuntando ambos valores:</span></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-199" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-1024x514.jpg" alt="" width="640" height="321" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-1024x514.jpg 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-300x151.jpg 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-768x386.jpg 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-500x251.jpg 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-976x490.jpg 976w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-737x370.jpg 737w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal-900x452.jpg 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/Step-2-ServicePrincipal.jpg 1878w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p><span style="color: #000000;">Vale, pero&#8230; ¿Cómo va a reconocer el acceso mi <strong>Azure SQL</strong> si no lo he indicado en ningún sitio?</span></p>
<p><span style="color: #000000;">¡Vamos con ello!</span></p>
<p><span style="color: #000000;">Entramos en nuestra DB con un usuario con autenticación básica que sea administrador de la DB y ejecutamos la siguiente query <strong>T-SQL</strong> para crear el usuario desde un proveedor externo, le ponemos el rol que nos interese, en nuestro caso lo dejamos como <strong>db_owner</strong>:</span></p>
<pre class="line-numbers"><code class="language-sql">CREATE USER [ApplicationName] FROM EXTERNAL PROVIDER
GO
ALTER ROLE db_owner ADD MEMBER[ApplicationName]</code></pre>
<p><span style="color: #000000;">Para llegar a nuestro objetivo, tenemos que estudiar las diferentes posibilidades:</span></p>
<ul>
<li><strong>Invoke-SQLCMD:</strong> No permite modificar en el ConnectionString la posibilidad de añadirle un token de acceso, además, el campo Authentication cuenta con:
<ul>
<li>Autenticación integrada (hace uso de SSO y nuestro cliente unido a dominio).</li>
<li>Autenticación mediante Azure AD con Usuario/Contraseña.</li>
<li>Autenticación básica SQL Server.</li>
</ul>
</li>
<li><strong>ADO.NET:</strong> Si estudiamos la conexión que se realiza desde C# (mucho más documentada, todo hay que decirlo), podemos observar que tenemos ya algo que nos puede servir dentro de las propiedades de la clase <a href="https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx">System.Data.SqlClient.SqlConnection</a> <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.accesstoken(v=vs.110).aspx">AccessToken</a>.</li>
</ul>
<p><span style="color: #000000;">Por lo tanto, tenemos claro el camino que tenemos que seguir, ahora tenemos otras 2 opciones, ¿me compilo una librería en <strong>C#</strong> y realizo la llamada posteriormente o intentamos hacer uso de la clase de manera directa desde PowerShell?</span></p>
<p><span style="color: #000000;">Por temas de performance, vamos a intentar ir por la segunda opción, ¿pero cómo obtengo Access Token si además me vendrá cifrado y en <strong>JSON</strong>?</span></p>
<p><span style="color: #000000;">Para ello, en primer lugar autenticaríamos con nuestro <strong>Service Principal</strong> que podría obtener el Secret de nuestro Service Principal de un <a href="https://azure.microsoft.com/es-es/services/key-vault/">Azure Key Vault</a> por ejemplo, evitando así tener passwords hardcoded:</span></p>
<pre class="line-numbers"><code class="language-powershell">$securePassword = ConvertTo-SecureString $appKey -AsPlainText -Force
$secureCredential = New-Object System.Management.Automation.PSCredential($appId, $securePassword)
Connect-AzureRmAccount -ServicePrincipal -Credential $secureCredential -TenantId $tenantId -SubscriptionId $subscriptionId</code></pre>
<p><span style="color: #000000;">A continuación, procedemos a generar la función que nos devuelva nuestro Access Token solicitándolo al audience correspondiente (<a href="https://database.windows.net/">https://database.windows.net/</a>&#8220;) mediante una petición de REST API diréctamente a Azure, aquí es necesario que le pasemos en las variables correspondientes el <strong>Application Id</strong> y <strong>Secret Key</strong>:</span></p>
<pre class="line-numbers"><code class="language-powershell">function Get-AccessToken{
    $TokenEndpoint = {https://login.windows.net/{0}/oauth2/token} -f $tenantId 
    $ARMResource = "https://database.windows.net/";

    $Body = @{
            'resource'= $ARMResource
            'client_id' = $appId
            'grant_type' = 'client_credentials'
            'client_secret' = $appKey
    }
    $params = @{
        ContentType = 'application/x-www-form-urlencoded'
        Headers = @{'accept'='application/json'}
        Body = $Body
        Method = 'Post'
        URI = $TokenEndpoint
    }
    $token = Invoke-RestMethod @params
    return $token.access_token
}</code></pre>
<p><span style="color: #000000;">Una vez que tenemos nuestro token, podemos comprobar que es correcto <strong>decodificándolo</strong> con <a href="https://jwt.io">jwt.io</a>, tenemos que obtener algo parecido a:</span></p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-193 size-large" src="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-1024x554.png" alt="" width="640" height="346" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-1024x554.png 1024w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-300x162.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-768x415.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-500x270.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-906x490.png 906w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-684x370.png 684w, https://www.joselcaguilar.com/wp-content/uploads/2018/06/AccessToken-900x487.png 900w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p><span style="color: #000000;">Por último, nos creamos la función de conexión que lanzará la query que le pasemos como parámetro contra <strong>Azure SQL</strong> y cerrará la conexión para evitar tener sockets abiertos, aquí es necesario que añadamos el <strong>nombre</strong> del servidor SQL y la <strong>DB</strong> a la cual queremos conectar:</span></p>
<pre class="line-numbers"><code class="language-powershell">function SQLConnection {
    param(
     [string]$query
    )
    $ConnectionString = 'Server=&lt;YOUR SQL SERVER&gt;.database.windows.net;Database=&lt;YOUR DB&gt;;Integrated Security=False;'
    $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection($ConnectionString)
    $connection.AccessToken = Get-AccessToken
    $connection.Open()
    $cmd=new-object system.Data.SqlClient.SqlCommand($query,$connection)
    $cmd.CommandTimeout = 30
    $DataSet = New-Object system.Data.DataSet
    $Adapter = New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
    [void]$Adapter.fill($DataSet)
    $value = $DataSet.Tables[0]
    $connection.Close()
    return $value
}</code></pre>
<p>&nbsp;</p>
<p><span style="color: #000000;">¡Espero que hayáis aprendido tanto como yo al escribir esta entrada!</span> <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.joselcaguilar.com/2018/06/autenticacion-azure-sql-service-principal-en-powershell/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure PowerShell Contexts</title>
		<link>https://www.joselcaguilar.com/2018/02/azure-powershell-contexts/</link>
					<comments>https://www.joselcaguilar.com/2018/02/azure-powershell-contexts/#respond</comments>
		
		<dc:creator><![CDATA[JoseLCAguilar]]></dc:creator>
		<pubDate>Tue, 27 Feb 2018 10:23:56 +0000</pubDate>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[AzureRM]]></category>
		<category><![CDATA[cmdlet]]></category>
		<category><![CDATA[Context]]></category>
		<guid isPermaLink="false">https://www.joselcaguilar.com/?p=143</guid>

					<description><![CDATA[¡Buenos días a tod@s! Me [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="color: #000000;">¡Buenos días a tod@s!</span></p>
<p><span style="color: #000000;">Me gustaría comenzar esta entrada poniéndonos todos en contexto (nunca mejor dicho) y siguiendo lo comentado en la primera entrada: </span><a href="https://www.joselcaguilar.com/2018/02/hi-world/">Hi World!</a></p>
<p><span style="color: #000000;">A final de septiembre de 2017, Microsoft incluyó </span><span style="color: #000000;">un cmdlet muy interesante: <strong>Azure Context Autosave</strong>, éste funciona desde la versión 4.4.0 del módulo de <a href="https://docs.microsoft.com/es-es/powershell/azure/servicemanagement/install-azure-ps?view=azuresmps-4.0.0">AzureRM</a> de PowerShell, en el momento que estoy escribiendo estas líneas, estamos ya por la versión 5.4.0.</span></p>
<p><span style="color: #000000;">Ante el tedioso motivo de tener que insertar la credencial cada vez que queremos interactuar con nuestras suscripciones de Azure o de nuestros clientes al tener varias cuentas, tenemos que hacer uso en numerosas ocasiones de:</span></p>
<pre class="line-numbers"><code class="language-powershell">Login-AzureRmAccount</code></pre>
<p><span style="color: #000000;"><img loading="lazy" decoding="async" class=" wp-image-147 aligncenter" src="https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-300x280.png" alt="" width="329" height="307" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-300x280.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-768x718.png 768w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-356x333.png 356w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-524x490.png 524w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-396x370.png 396w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1-900x841.png 900w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/1.png 913w" sizes="auto, (max-width: 329px) 100vw, 329px" /></span><br />
<span style="color: #000000;"> En este ejemplo, vamos a enseñar cómo hacer uso del nuevo cmdlet para 2 cuentas diferentes gracias a las plantillas JSON de ARM siguiendo los siguientes pasos:</span></p>
<ul>
<li>
<h6><span style="color: #000000;">Habilitamos AzureRM Context, que nos guardará la información en: <strong>%AppData%\Roaming\Windows Azure PowerShell</strong> para ello, ejecutamos el siguiente cmdlet:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Enable-AzureRmContextAutosave</code></pre>
<ul>
<li>
<h6><span style="color: #000000;">Agregamos las 2 cuentas mediante el cmdlet:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Connect-AzureRmAccount</code></pre>
<ul>
<li>
<h6><span style="color: #000000;">Nos fijamos en el nombre de los 2 contextos que se han creado en: <strong>%AppData%\Roaming\Windows Azure PowerShell\AzureRmContext.json </strong>ó también ejecutando el siguiente cmdlet:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Get-AzureRMContext -ListAvailable</code></pre>
<p style="text-align: center;"><span style="color: #000000;"><img loading="lazy" decoding="async" class="alignnone wp-image-148" src="https://www.joselcaguilar.com/wp-content/uploads/2018/02/2-300x157.png" alt="" width="319" height="167" srcset="https://www.joselcaguilar.com/wp-content/uploads/2018/02/2-300x157.png 300w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/2-500x262.png 500w, https://www.joselcaguilar.com/wp-content/uploads/2018/02/2.png 587w" sizes="auto, (max-width: 319px) 100vw, 319px" /></span></p>
<ul>
<li>
<h6><span style="color: #000000;">Renombramos el contexto con un nombre familiar, como podemos ver en la imagen de más arriba se han renombrado ambos contextos, uno pertenece a &#8220;<strong>Yoda</strong>&#8221; y el otro personal &#8220;<strong>JoseLCAguilar</strong>&#8220;, para ello hacemos uso del siguiente cmdlet en ambos contextos:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Rename-AzureRMContext "NombreOriginal" "NombreFamiliar"</code><code class="language-powershell"></code></pre>
<ul>
<li>
<h6><span style="color: #000000;">Para cambiar de un contexto a otro, símplemente ejecutamos lo siguiente:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Select-AzureRMContext "NombreFamiliar"</code></pre>
<ul>
<li>
<h6><span style="color: #000000;">Por último, para eliminar un contexto, podemos hacer uso de:</span></h6>
</li>
</ul>
<pre class="line-numbers"><code class="language-powershell">Remove-AzureRmAccount -ContextName "NombreDeContexto"</code></pre>
<p><span style="color: #000000;">Si nos fijamos, al abrir y cerrar la sesión de PowerShell, <strong><span style="color: #ff0000;">¡voilá!</span></strong> podremos ver que automágicamente el equipo nos coge el último contexto usado y podemos hacer uso de todos los cmdlets de Azure sin tener que escribir las credenciales una y otra vez en nuestra consola de PowerShell.</span></p>
<p><span style="color: #000000;">Podéis encontrar más info </span><a href="https://docs.microsoft.com/en-us/powershell/azure/context-persistence?view=azurermps-5.3.0">aquí</a><span style="color: #000000;">.</span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.joselcaguilar.com/2018/02/azure-powershell-contexts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hi World!</title>
		<link>https://www.joselcaguilar.com/2018/02/hi-world/</link>
					<comments>https://www.joselcaguilar.com/2018/02/hi-world/#respond</comments>
		
		<dc:creator><![CDATA[JoseLCAguilar]]></dc:creator>
		<pubDate>Thu, 15 Feb 2018 07:04:24 +0000</pubDate>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Personal]]></category>
		<guid isPermaLink="false">http://clini140-cp46.wordpresstemporal.com/?p=124</guid>

					<description><![CDATA[¡Hola mundo! ¿Cuántas veces no [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="color: #000000;"><strong>¡Hola mundo!</strong></span></p>
<p><span style="color: #000000;">¿Cuántas veces no hemos dicho eso los ingenieros? Siguiendo la tradición y dado que esta es la primera entrada de muchas del blog, es un placer poder seguir diciéndolo con cada nuevo entorno que se lleva a cabo.</span></p>
<p><span style="color: #000000;">En este proyecto he querido mezclar <strong>blogging</strong> junto con <strong>web personal</strong>, intentando seguir el idioma nativo en toda información técnica para así aportar más a un idioma tan completo como es el <strong>español</strong>.</span></p>
<p><span style="color: #000000;">En el blog se mezclarán diversos temas de toda índole técnica, desde la especialización en tecnologías Microsoft hasta diversas pruebas que se puedan realizar con UNIX, sobre todo para entornos IoT, móviles, etc.</span></p>
<p><span style="color: #000000;">Las diferentes entradas del blog las podréis seguir en vuestro cliente <strong>RSS</strong> favorito agregando el </span><a href="https://www.joselcaguilar.com/feed/">feed</a><span style="color: #000000;">.</span></p>
<blockquote><p><span style="color: #000000;">Como no podía ser de otra manera y dado el auge de los entornos <strong>Cloud</strong>, comenzaremos la próxima entrada explicando cómo realizar autenticación en algo tan común como Azure Powershell mediante contextos alejándonos de ésta manera de obligarnos a repetir login en numerosas ocasiones.</span></p></blockquote>
<p><span style="color: #000000;">¡Muchas gracias por estos minutos de atención lectora, será un orgullo comenzar esta nueva odisea con todos vosotros!</span></p>
<p><span style="color: #000000;">J.</span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.joselcaguilar.com/2018/02/hi-world/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Almacenamiento en caché de páginas con Disk: Enhanced 
Caché de base de datos usando Disk (En toda la solicitud modification query)

Served from: www.joselcaguilar.com @ 2026-09-10 19:56:59 by W3 Total Cache
-->