<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «ciberseguridad»</title><description>Feed RSS de publicaciones etiquetadas con ciberseguridad</description><link>https://javguerra.github.io/</link><item><title>El algoritmo de Karaca</title><link>https://javguerra.github.io/blog/karaca</link><guid isPermaLink="true">https://javguerra.github.io/blog/karaca</guid><description>Solución en JavaScript al reto semanal n. 50 de @MoureDev</description><pubDate>Thu, 15 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cifrado.Hb5hRkab_Z2qxri.webp&quot; alt=&quot;Cifrado&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#criptografía&lt;/em&gt;, &lt;em&gt;#ciberseguridad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En este post resuelvo, en JavaScript el &lt;a href=&quot;https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt&quot;&gt;reto de programación&lt;/a&gt; consistente en desarrollar una función que es capaz de encriptar y desencriptar texto utilizando el algoritmo de encriptación de Karaca.&lt;/p&gt;
&lt;p&gt;Descubrí esta semana, un poco tarde, los &lt;a href=&quot;https://retosdeprogramacion.com/semanales2022&quot;&gt;retos de programación semanales de Mouredev para 2022&lt;/a&gt; y me atrajo el enunciado de este ejercicio.&lt;/p&gt;
&lt;p&gt;Busqué información en Internet sobre el algoritmo, encontrando lo siguiente:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Make a function that encrypts a given input with these steps:&lt;br&gt;
Input: “apple”&lt;br&gt;
Step 1: Reverse the input: “elppa”&lt;br&gt;
Step 2: Replace all vowels using the following chart:&lt;br&gt;
a =&amp;gt; 0, e =&amp;gt; 1, i =&amp;gt; 2, o =&amp;gt; 3, u =&amp;gt; 4  # “1lpp0”&lt;br&gt;
Step 3: Add “aca” to the end of the word: “1lpp0aca”&lt;br&gt;
Output: “1lpp0aca”&lt;br&gt;
All inputs are strings, no uppercases and all output must be strings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Y me tomé la libertad de corregir la relación entre vocales y números que, en &lt;a href=&quot;https://edabit.com/challenge/JzBLDzrcGCzDjkk5n&quot;&gt;la fuente original&lt;/a&gt; publicada por Furkan Karaca, en el &lt;a href=&quot;https://edabit.com/&quot;&gt;portal de retos Edabit&lt;/a&gt; parece no ser correcta.&lt;/p&gt;
&lt;p&gt;El algoritmo, sin una aparente utilidad práctica, es un buen ejercicio de programación que combina el uso de expresiones regulares, uso de arreglos y cadenas y lógica.&lt;/p&gt;
&lt;h1 id=&quot;entendiendo-el-problema&quot;&gt;Entendiendo el problema&lt;/h1&gt;
&lt;p&gt;Lo que pide el ejercicio es que nuestra función debe poder codificar y decodificar un texto, en minúsculas, que le pasemos por parámetro. Este texto, lógicamente, no puede estar vacío.&lt;/p&gt;
&lt;p&gt;Cualquier dato que le pasemos que no sea texto debe impedir la ejecución de la codificación/decodificación. La función puede devolver un error, o bien el dato original suministrado. Opto por esta segunda posibilidad.&lt;/p&gt;
&lt;p&gt;La cadena de caracteres suministrada a la función puede tener espacios al inicio y/o al final, incluso puede contener sólo espacios, por lo que amerita limpiar la cadena, y que esta contenga algo más que sólo espacios.&lt;/p&gt;
&lt;p&gt;La cadena no puede contener sólo números, esto equivaldría a suministrar un número entero a la función. De hecho, el algoritmo presenta un problema importante con esto. Si se le suministra un frase que contenga dígitos en el rango del mapeo de vocales (0-1-2-3-4) no realizará bien el cifrado, pues tomará estos dígitos como parte del descifrado, mostrando un galimatías. Ej. «100 horas» -&amp;gt; «s0r3h 001aca» -&amp;gt; «eaa horas».&lt;/p&gt;
&lt;p&gt;Para saber si se puede decodificar una cadena proporcionada, es decir, para saber si está codificada con el algoritmo de Karaca, se debe cumplir que esta termine con un «aca», que contenga algún número entre el 0 y el 4, y que su longitud sea mayor que la de la cadena de control «aca». De no cumplirse esto, se entiende que la cadena que se proporciona a la función no está codificada, y entonces puede ser codificada.&lt;/p&gt;
&lt;p&gt;Para realizar la conversión, se debe recorrer la cadena teniendo en cuenta el mapeo de vocales del enunciado (a =&amp;gt; 0, e =&amp;gt; 1, i =&amp;gt; 2, o =&amp;gt; 3, u =&amp;gt; 4) y viceversa.&lt;/p&gt;
&lt;h1 id=&quot;resolución&quot;&gt;Resolución&lt;/h1&gt;
&lt;p&gt;El algoritmo de Karaca en JavaScript, atendiendo a las consideraciones anteriores, es el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;01&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;02.  * Función en JavaScript que encripta y desencripta texto en minúsculas en &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;03.  * inglés, sin números, utilizando el algoritmo de encriptación de Karaca.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;04.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; {String}&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;05.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@returns&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;06.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@author&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Javier Guerra&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;07.  */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;08.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;09.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;??&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;11.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\D&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;13.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;14.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLowerCase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; vowels&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;aeiou&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;17.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; control&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;aca&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;18.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;19.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;startsWith&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(control) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;21.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\d&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;22.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; control.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;23.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;24.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // decode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;25.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(control.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;26.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            vowels.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;27.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(i)) str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(i, chr);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;28.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;29.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;30.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // encode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;31.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            vowels.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;32.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(chr)) str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(chr, i);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;33.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;34.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; control;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;35.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;37.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;38.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;39.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En la línea 8, con el valor por defecto &lt;code&gt;&quot;&quot;&lt;/code&gt; del parámetro se evita el error si llamemos a la función sin ningún parámetro, devolviendo una cadena vacía.&lt;/p&gt;
&lt;p&gt;en la línea 10 se comprueba que el parámetro recibido no está colando un valor &lt;code&gt;null&lt;/code&gt; o &lt;code&gt;undefined&lt;/code&gt; con el operador coalescente nulo (&lt;code&gt;??&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;En la línea 12 se comprueba que el dato recibido es una cadena, que tiene al menos un carácter, y cuenta con alguna consonante. De no ser así, se devuelve el parámetro recibido.&lt;/p&gt;
&lt;p&gt;En la línea 14 se realizan varias conversiones al parámetro recibido: se limpian los espacios iniciales y/o finales, se pasa la  cadena a minúsculas, y se invierte la cadena. Esto último se hace mediante la concatenación de varios métodos: &lt;code&gt;split&lt;/code&gt;, para convertir la cadena en un arreglo, &lt;code&gt;reverse&lt;/code&gt; para invertir el orden del contenido del arreglo y &lt;code&gt;join&lt;/code&gt; para unir el contenido del arreglo en una cadena.&lt;/p&gt;
&lt;p&gt;Las líneas 16 y 17 definen las variables que usaremos en el algoritmo.&lt;/p&gt;
&lt;p&gt;En la comprobación de las líneas de la 19 a la 23 se decide si se va a decodificar la cadena recibida, es decir, si se cumple que la cadena termina en «aca», contiene algún dígito y su longitud es mayor que la longitud de «aca». Si es así, se lleva a cabo la codificación a partir de la línea 25. en caso contrario, se lleva a cabo la codificación a partir de la línea 31.&lt;/p&gt;
&lt;p&gt;Para la decodificación, primero se elimina el control «aca» y luego se recorre el arreglo de vocales con forEach, de tal forma que si alguno de los elementos del arreglo es encontrado en la cadena a decodificar, este se sustituye por la vocal correspondiente.&lt;/p&gt;
&lt;p&gt;Para la codificación se lleva a cabo el proceso contrario. Al recorrer el arreglo de vocales, se sustituye el dígito por la vocal correspondiente. Luego se añade la cadena de control «aca».&lt;/p&gt;
&lt;p&gt;Por último, se devuelve el resultado de las operaciones sobre la cadena recibida convertida a cadena, por si el valor recibido fue un número, ya que la función debe devolver una cadena.&lt;/p&gt;
&lt;h1 id=&quot;prueba&quot;&gt;Prueba&lt;/h1&gt;
&lt;p&gt;El siguiente código de prueba debe poder codificar y decodificar la cadena original suministrada obteniendo la cadena original como resultado.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Testing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Solving an equation produces, instantly, great euphoria.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(str));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(str)));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El resultado esperado debe ser:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.02r3hp41 t01rg ,yltn0tsn2 ,s1c4d3rp n32t04q1 n0 gn2vl3saca&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;solving an equation produces, instantly, great euphoria.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La frase, en inglés, incluye las palabras &lt;code&gt;equation&lt;/code&gt; y &lt;code&gt;euphoria&lt;/code&gt; que cuentan con todas las vocales.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://retosdeprogramacion.com/semanales2022&quot;&gt;Retos de programación semanales de Mouredev para 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt&quot;&gt;Reto de programación semanal n. 50 de Mouredev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://edabit.com/challenge/JzBLDzrcGCzDjkk5n&quot;&gt;La fuente original del reto por Furkan Karaca&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://edabit.com/&quot;&gt;Portal de retos Edabit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/retos-programacion&quot;&gt;Ver el código de este y otros retos de programación en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cifrado.Hb5hRkab_Z2qxri.webp"/><category>código</category><category>javascript</category><category>criptografía</category><category>ciberseguridad</category><author>JavGuerra</author></item><item><title>Logout personalizado con Spring Security</title><link>https://javguerra.github.io/blog/logout-spring-security</link><guid isPermaLink="true">https://javguerra.github.io/blog/logout-spring-security</guid><description>Limpiando el contexto de seguridad sin borrar la cookie</description><pubDate>Sat, 13 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cookies.CQlbddQu_TNB6F.webp&quot; alt=&quot;cookies&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#ciberseguridad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En un &lt;a href=&quot;/blog/notificaciones-thymeleaft&quot;&gt;artículo anterior&lt;/a&gt; he usado variables de sesión para guardar información de la aplicación: mensajes para el usuario, aviso de cookies… Puede que, cuando el usuario salga de su sesión, queramos conservar estos datos que seguirán siendo útiles aunque no esté autenticado. En esta entrada muestro mi solución usando Spring Security.&lt;/p&gt;
&lt;p&gt;Se asume que el lector tiene conocimientos generales de Spring Boot y Spring Security para aplicar el contenido.&lt;/p&gt;
&lt;h1 id=&quot;el-contexto-de-seguridad&quot;&gt;El contexto de seguridad&lt;/h1&gt;
&lt;p&gt;El primer paso en el proceso de logout que lleva a cabo Spring Security es invalidar la sesión del usuario. Esto significa que Spring Security elimina cualquier información asociada con la sesión del usuario, como datos de estado de sesión almacenados en el servidor o en cookies (borra la información, pero no la cookie). Al invalidar la sesión, se asegura de que el usuario ya no pueda acceder a la aplicación como si estuviera autenticado.&lt;/p&gt;
&lt;p&gt;Después de invalidar la sesión, Spring Security también limpia el contexto de seguridad actual. Esto incluye eliminar cualquier token de Authentication que represente al usuario autenticado, asegurando que el usuario ya no sea reconocido como autenticado en la aplicación.&lt;/p&gt;
&lt;p&gt;Pero en este caso no interesa ese borrado completo, sino sólo la información de autenticación. Para ello debo codificar mi propio logout limpiando el contexto de seguridad pero sin invalidar la sesión.&lt;/p&gt;
&lt;h1 id=&quot;tomando-el-control-de-logout&quot;&gt;Tomando el control de Logout&lt;/h1&gt;
&lt;p&gt;Como sabemos, para configurar Spring Security se usa la clase &lt;code&gt;SecurityConfig.class&lt;/code&gt;, que generalmente incluye el componente &lt;code&gt;SecurityFilterChain&lt;/code&gt;, fundamental para establecer filtros a las peticiones HTTP que se reciben en la aplicación. En este ejemplo me centraré en la parte de su configuración relativa al logout.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Configuration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;EnableWebSecurity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  SecurityConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SecurityFilterChain &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;securityFilterChain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSecurity &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;http&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Exception {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authorizeHttpRequests&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(authRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; authRequest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;requestMatchers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpMethod.POST, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anyRequest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authenticated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(logout &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; logout&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logoutUrl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;...&lt;/code&gt; indico que el código puede ser más amplio y contener otras configuraciones.&lt;/p&gt;
&lt;p&gt;En la línea &lt;code&gt;.requestMatchers(HttpMethod.POST, &quot;/logout&quot;).permitAll()&lt;/code&gt; estoy permitiendo el acceso a la ruta personalizada para llevar a cabo el logout. Realmente, esto no sería necesario al incluir &lt;code&gt;.permitAll()&lt;/code&gt; después de &lt;code&gt;logoutUrl(&quot;/logout&quot;)&lt;/code&gt;. Tampoco sería necesario porque la ruta &lt;code&gt;/logout&lt;/code&gt; está disponible por defecto. No obstante, esto puede ser útil si decidimos usar otra ruta distinta a &lt;code&gt;/logout&lt;/code&gt; en la aplicación.&lt;/p&gt;
&lt;p&gt;Para la gestión del token del usuario, será necesario definir un controlador propio para la ruta &lt;code&gt;logout&lt;/code&gt;. Algo similar a esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; LogoutController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SecurityContextHolder.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getContext&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAuthentication&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // cosas que hacer tras el cierre de sesión aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La información de sesión se guarda en una cookie llamada &lt;code&gt;JSESSIONID&lt;/code&gt;, que contendrá las variables de sesión, incluido el token de autenticación.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;SecurityContextHolder.getContext().setAuthentication(null);&lt;/code&gt; elimino el token de autenticación, pero sin borrar toda la información de la cookie, como las variables de sesión.&lt;/p&gt;
&lt;p&gt;Después de esto, puedo realizar algunas acciones asociadas al cierre y redirigir al login, o como en este caso, mostrar la vista &lt;code&gt;logout&lt;/code&gt; para mostrar un mensaje de despedida.&lt;/p&gt;
&lt;h1 id=&quot;refinando-el-logout&quot;&gt;Refinando el logout&lt;/h1&gt;
&lt;p&gt;Al usar &lt;code&gt;null&lt;/code&gt; elimino el token de autenticación del usuario, pero puede que, en la plantilla que devuelvo con return (&lt;code&gt;logout&lt;/code&gt; en el caso anterior), sea necesario usar el contexto de seguridad, por ejemplo mostrando una información u otra en un fragmento de la plantilla si estamos autenticados o no. Con este método, ni &lt;code&gt;sec:authorize=&quot;isAnonymous()&quot;&lt;/code&gt; ni &lt;code&gt;sec:authorize=&quot;isAuthenticated()&quot;&lt;/code&gt; funcionarán en Thymeleaft, ya que ahora no existe el token que indique si el usuario es anónimo o está autenticado.&lt;/p&gt;
&lt;p&gt;Esto ocurre sólo para la vista asociada al controlador que es llamada tras borrar el token, pero no ocurre así para las siguientes vistas, en las que parece que el token es regenerado como anónimo.&lt;/p&gt;
&lt;p&gt;Entonces, si en la siguiente vista no vamos a usar la autenticación, será suficiente con usar &lt;code&gt;null&lt;/code&gt;, pero si no es así, entonces hay que cambiar el token en vez de eliminarlo, pero Spring Boot no tiene un token por defecto que pueda usar, así que debo construir uno.&lt;/p&gt;
&lt;p&gt;Primeramente añado el siguiente código en&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AnonymousAuthenticationToken &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anonymousAuthenticationToken&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    List&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GrantedAuthority&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; authorities &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Collections.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;singletonList&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SimpleGrantedAuthority&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ROLE_ANONYMOUS&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; AnonymousAuthenticationToken&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ANONYMOUS_USER&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ANONYMOUS_USER&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, authorities);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Que me permitirá crear &lt;code&gt;anonymousAuthenticationToken&lt;/code&gt; como un &lt;code&gt;Bean&lt;/code&gt;. Este método es responsable de crear e inicializar el objeto &lt;code&gt;AnonymousAuthenticationToken&lt;/code&gt;. Este token es utilizado por Spring Security para representar la autenticación de usuarios anónimos dentro de una aplicación.&lt;/p&gt;
&lt;p&gt;El método realiza las siguientes acciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inicialización de Autoridades&lt;/strong&gt;: Primero, creo una lista (&lt;code&gt;List&amp;lt;GrantedAuthority&amp;gt;&lt;/code&gt;) con un solo elemento, que es una instancia de &lt;code&gt;SimpleGrantedAuthority&lt;/code&gt; con el rol &lt;code&gt;&quot;ROLE_ANONYMOUS&quot;&lt;/code&gt;. Las autoridades (o roles) determinan los privilegios que tiene un usuario dentro de la aplicación. En este caso, asigno al usuario anónimo el rol de &lt;code&gt;ROLE_ANONYMOUS&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Creación del Token&lt;/strong&gt;: Luego, utilizo esta lista de autoridades para construir un nuevo &lt;code&gt;AnonymousAuthenticationToken&lt;/code&gt;, pasando también dos cadenas de texto (&lt;code&gt;&quot;ANONYMOUS_USER&quot;&lt;/code&gt;) como nombre y detalles del usuario. Estos valores pueden ser personalizados según sea necesario.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ya puedo usar el token en el controlador, como se muestra:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; LogoutController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AnonymousAuthenticationToken anonymousAuthenticationToken;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SecurityContextHolder.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getContext&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAuthentication&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(anonymousAuthenticationToken);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // cosas que hacer tras el cierre de sesión aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ahora sí, el usuario será anónimo, y cualquier comprobación en la plantilla Thymeleaft que incluya &lt;code&gt;sec:authorize=&quot;isAnonymous()&quot;&lt;/code&gt; permitirá que la etiqueta HTML que lo use sea mostrada.&lt;/p&gt;
&lt;h1 id=&quot;consideraciones&quot;&gt;Consideraciones&lt;/h1&gt;
&lt;p&gt;Tal vez podría crearse un servicio al que llamar desde el controlador para gestionar el logout, o un manejador propio &lt;code&gt;CustomLogoutHandler&lt;/code&gt; que realice esta función de cierre de sesión sin la necesidad de crear un controlador, y que se use directamente desde &lt;code&gt;SecurityConfig.class&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Se han de tener en cuenta las consideraciones de seguridad relacionadas con este método. Mantener información de la sesión de usuario una vez se lleva a cabo el logout no siempre es seguro, y se deben controlar las posibles fugas de información para evitar problemas.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Puedes ver el código que implementan esta funcionalidad en el repositorio de la aplicación &lt;a href=&quot;/blog/cartelera-daw&quot;&gt;Cartelera DAW&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio de Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mira también el artículo donde se usan las variables de sesión que quiero preservar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/notificaciones-thymeleaft&quot;&gt;Notificaciones con Thymeleaft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cookies.CQlbddQu_TNB6F.webp"/><category>código</category><category>java</category><category>spring boot</category><category>spring security</category><category>ciberseguridad</category><author>JavGuerra</author></item></channel></rss>