<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alan Lamas</title>
    <description>The latest articles on Forem by Alan Lamas (@adlamas).</description>
    <link>https://forem.com/adlamas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F350693%2Fd25609a8-2ec5-404a-9388-aa7191e7aea3.jpg</url>
      <title>Forem: Alan Lamas</title>
      <link>https://forem.com/adlamas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adlamas"/>
    <language>en</language>
    <item>
      <title>¿Querés empezar a programar y no tenés ni idea de como? Esto te puede servir.</title>
      <dc:creator>Alan Lamas</dc:creator>
      <pubDate>Sat, 24 Jul 2021 20:22:07 +0000</pubDate>
      <link>https://forem.com/adlamas/queres-empezar-a-programar-y-no-tenes-ni-idea-de-como-esto-te-puede-servir-1356</link>
      <guid>https://forem.com/adlamas/queres-empezar-a-programar-y-no-tenes-ni-idea-de-como-esto-te-puede-servir-1356</guid>
      <description>&lt;h2&gt;
  
  
  Que aborda el articulo y a quien está dirigido
&lt;/h2&gt;

&lt;p&gt;Este artículo está pensado para quien no tiene conocimiento previo en la programación pero quisiera empezar a aprender, y no sabe cuales son los primeros pasos.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Me interesa pero no sé si soy lo suficientemente inteligente para eso ¿Yo también puedo programar?"
&lt;/h2&gt;

&lt;p&gt;Dejame decir esto así: &lt;strong&gt;Todas, absolutamente todas las personas podemos programar&lt;/strong&gt;, si te interesa, hacelo, vas a poder, te lo aseguro.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Quiero programar pero no me gustan las matemáticas"
&lt;/h2&gt;

&lt;p&gt;No te hagas drama, muchos campos de la programación no necesitan matemática muy compleja, aunque sí vas a tener que aprender sobre lógica.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consideraciones previas
&lt;/h2&gt;

&lt;p&gt;Para programar, literalmente, sólo vas a necesitar una computadora con internet, no hay más que eso, pero (Y es importante) tenés que entender que trabajar en software, es estar en un &lt;strong&gt;constante&lt;/strong&gt; estado de incertidumbre en el que no sabés que tenés que hacer, pero debés investigar (O sea, googlear, el 95% de las veces) y resolverlo. Quisiera, primero, que pienses y medites eso puesto que es un punto muy relevante. &lt;br&gt;
Por otro lado, recordar que esto te va a llevar, &lt;strong&gt;al menos&lt;/strong&gt;, un año, dependiendo de cuanto le dediques, para encontrar un trabajo en la industria, no va a ser de la noche a la mañana.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cuáles son los beneficios de ser programador/a?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vas a poder trabajar desde cualquier parte del mundo.&lt;/li&gt;
&lt;li&gt;Vas a poder conocer personas de toda parte del mundo.&lt;/li&gt;
&lt;li&gt;Vas a tener la oportunidad de trabajar en compañías con un ambiente relajado, flexible y amistoso.&lt;/li&gt;
&lt;li&gt;Vas a tener un trabajo muy poco repetitivo en el que siempre hay cosas nuevas que aprender y, por lo tanto, inmune a la obsolescencia.&lt;/li&gt;
&lt;li&gt;Hay una demanda de programadores ENORME en todo el planeta, hay mucho, mucho trabajo. &lt;a href="https://www.equiposytalento.com/talentstreet/noticias/2021/02/05/en-2021-la-demanda-de-desarrolladores-y-programadores-expertos-aumentara-en-un-30/4499/"&gt;Nota&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Y si, si sos de Latinoamérica, tus expectativas de crecimiento a nivel salarial son absurdamente grandes. Si no sos de LATAM, igualmente tus expectativas son muy considerables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nota: Estos beneficios están sujetos principalmente a &lt;strong&gt;vos&lt;/strong&gt; , a como trabajes y cuan proactivo/a seas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ahora si, ¿Cómo empiezo?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lo primero, en la programación hay diferentes paradigmas, el que yo creo más conveniente aprender es la &lt;strong&gt;Programación orientada a objetos&lt;/strong&gt; o POO o OOP que es lo mismo y, personalmente me decanto por empezar con el lenguaje &lt;strong&gt;Python&lt;/strong&gt;, del que te dejo un curso completamente gratis &lt;a href="https://www.youtube.com/watch?v=G2FCfQj-9ig&amp;amp;list=PLU8oAlHdN5BlvPxziopYZRd55pdqFwkeS&amp;amp;index=1"&gt;acá&lt;/a&gt; que te recomiendo llegar, al menos, hasta el video 42.&lt;/li&gt;
&lt;li&gt;Todo lo que sea referente a métodos, funciones, variables, tipos de datos, clases, herencia, polimorfismo y estructura de datos (Pilas, colas, arreglos, arboles, etc), son cosas que debés saberlas perfectamente tanto a nivel teórico como a nivel práctico (Te dejo los temas para que vos por tu propia cuenta investigues en libros, artículos o videos que encuentres, eso es parte de ser programador/a, también).&lt;/li&gt;
&lt;li&gt;Tenés que ejercitar y ejercitar. El ejercicio de estos conceptos nuevos va a hacer que tu mente comprenda de a poco las bases de la programación a nivel más profundo y que, por consecuencia, puedas implementar estos nuevos saberes en un sin fin de problemas, pero para eso, tenés que chocarte una y otra vez con ejercicios desafiantes que te hagan pensar y re-pensar sobre lo aprendido (Spoiler. la más minima cosa te va a llevar un tiempo considerable al principio). Te dejo un link &lt;a href="https://byte-mind.net/curso-python-objetivos-primer-programa/"&gt;acá&lt;/a&gt; con muchísimos ejercicios de Python para que practiques, aunque no te limites con estos y buscá más.&lt;/li&gt;
&lt;li&gt;No sólo tenés que codear, sino que también, tenés que hacer pruebas, todo código que hagas &lt;strong&gt;debe&lt;/strong&gt; estar probado y eso no es opcional. Es importante que aprendas bien el proceso de como probar tu propio código, las &lt;strong&gt;pruebas unitarias&lt;/strong&gt; y, después, las pruebas de integración. Te dejo &lt;a href="https://www.youtube.com/watch?v=5ufpsjfk99U&amp;amp;ab_channel=CodinEric"&gt;acá&lt;/a&gt; un video sobre pruebas unitarias en Python y la recomendación de que le hagas las pruebas que se te ocurran a TODOS los ejercicios anteriores.&lt;/li&gt;
&lt;li&gt;Cuando hayas hecho tantos pero TANTOS ejercicios que ya tengas hasta biceps en los dedos, algo que si o si vas a necesitar saber, es GIT. Create un repositorio en Github y hacé un curso de GIT con los ejercicios que hiciste antes.&lt;/li&gt;
&lt;li&gt;¿Terminaste con GIT? Ahora toca Django. Django es un framework (Buscá que es eso) de Python que te permite crear páginas web como la que estás viendo ahora mismo y, que es súper popular hoy en día (2021)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  "¿Genial, algo más?"
&lt;/h2&gt;

&lt;p&gt;Si, vas a tener que aprender una dinámica de trabajo, vas a tener que aprender a buscar las soluciones a tus problemas, a googlear y leer muchísimo y a que las cosas casi nunca te van a venir servidas, la proactividad acá te va a abrir puertas que no creés.&lt;/p&gt;

&lt;h2&gt;
  
  
  Una encuesta muy util
&lt;/h2&gt;

&lt;p&gt;Te dejo esta encuesta de StackOverflow para que veas algunos detalles de como es visto Python (O de lo que quieras, hay mucha información interesante), cuanto trabajo hay y cuales son los sueldos hoy en día. &lt;a href="https://insights.stackoverflow.com/survey/2020"&gt;Encuesta&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muchas gracias por tomarte el tiempo de leer el artículo, mi intención es brindar mi perspectiva sobre como alguien con cero conocimiento, puede empezar a dar sus primeros pasos en la industria hasta llegar a ser un desarrollador senior. Si tenés comentarios o sugerencias, escribímelas abajo que las leeré y veré si puedo mejorar el articulo en base a estas.&lt;/p&gt;

&lt;p&gt;Happy coding :) &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How can we login through SAML 2.0 using our API REST developed in Ruby on Rails?</title>
      <dc:creator>Alan Lamas</dc:creator>
      <pubDate>Tue, 24 Mar 2020 23:11:52 +0000</pubDate>
      <link>https://forem.com/adlamas/how-can-we-login-through-saml-2-0-using-our-api-rest-developed-in-ruby-on-rails-2en9</link>
      <guid>https://forem.com/adlamas/how-can-we-login-through-saml-2-0-using-our-api-rest-developed-in-ruby-on-rails-2en9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Our problem&lt;/strong&gt;&lt;br&gt;
We have an API REST developed in RoR and our client has a Single Sign On service which we need to login through SAML 2.0 standard to use our application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br&gt;
We’ll see how integrating these 3 gems help us achieve our goal. If you want to know what these 3 gems do, just go to the Github page of each one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;devise_saml_authenticatble, version 1.5.0 (From now, DSA)&lt;/li&gt;
&lt;li&gt;devise_token_auth, version 1.1.0 (From now, DTA)&lt;/li&gt;
&lt;li&gt;devise, version 4.6.2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Some important concepts&lt;/strong&gt;&lt;br&gt;
There are a large number of articles about SAML standard, but in my opinion, i didn’t found one that explains correctly these concepts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identity Provider or IdP: The service in which we want to login, generally with a user and a password. This is usually provided by our client.&lt;/li&gt;
&lt;li&gt; Service Provider or SP: Is our API. In my case, my RoR API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Installations&lt;/strong&gt;&lt;br&gt;
Previously, we have to have the “create_users” migration and User model, after that, we need to install the 3 gems and run Devise’s generator and then, DTA’s generator setting up the class and the mount path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;br&gt;
We add these two lines in model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;devise&lt;/span&gt; &lt;span class="ss"&gt;:saml_authenticatable&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concerns&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the bottom of the file, add this method and leave it empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# We don't have passwords&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_tokens_after_password_reset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We do this because we don’t need passwords in our database, this is work for the IdP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routes&lt;/strong&gt;&lt;br&gt;
We have to rewrite the routes after run the DTA’s generator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;mount_devise_token_auth_for&lt;/span&gt; &lt;span class="s1"&gt;'User'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;at: &lt;/span&gt;&lt;span class="s1"&gt;'api/v1/auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;skip: &lt;/span&gt;&lt;span class="sx"&gt;%i[omniauth_callbacks]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;controllers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;sessions: &lt;/span&gt;&lt;span class="s1"&gt;'api/v1/sessions'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;devise_scope&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/users/saml/sign_in'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'saml/auth#new'&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/users/saml/metadata'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'devise/saml_sessions#metadata'&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s1"&gt;'/users/saml/auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'dta_saml/sessions#create'&lt;/span&gt;
    &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="s1"&gt;'/users/saml/dta_logout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'dta_saml/sessions#destroy'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Controllers&lt;/strong&gt;&lt;br&gt;
For the controllers, we create two new ones: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;saml/auth_controller.rb&lt;/li&gt;
&lt;li&gt;dta_saml/sessions_controller.rb&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;auth_controller.rb&lt;/em&gt;&lt;br&gt;
This controller will create the URL and redirect us, with a request, to the IdP to login, also the controller will test out if you are logged in or not. We will rewrite the #new method of DSA to edit the authentication flow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Saml&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Devise&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SamlSessionsController&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="n"&gt;idp_entity_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_idp_entity_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OneLogin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RubySaml&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Authrequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="n"&gt;auth_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;RelayState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;relay_state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;relay_state&lt;/span&gt;
      &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;saml_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idp_entity_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;auth_params&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we rewrite the “ require_no_authentication” method of Devise to eliminate all we don’t need and we add a forced logout. This is related to Warden and i won’t explain it here. Keep in mind that the 'action' variable is the URL of the IdP's page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="kp"&gt;private&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;require_no_authentication&lt;/span&gt;
      &lt;span class="n"&gt;assert_is_devise_resource!&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;is_navigational_format?&lt;/span&gt;

      &lt;span class="n"&gt;no_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;devise_mapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;no_input_strategies&lt;/span&gt;
      &lt;span class="n"&gt;authenticated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validate_credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;no_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;logged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;no_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;no_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;no_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt; &lt;span class="ss"&gt;scope: &lt;/span&gt;&lt;span class="n"&gt;resource_name&lt;/span&gt;
        &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticated?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;logged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;
      &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;after_sign_in_path_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;authenticated&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;sessions_controller.rb&lt;/em&gt;&lt;br&gt;
Create&lt;br&gt;
In this controller, we combine all we need of DSA and DTA. When we get the authentication response of the IdP, it will be decoded in the first line of the #create method and it will continue with the common process of DTA returning, in @client_id, 2 variables (client and token) and in @resource, the User object with it’s email. DTA uses these 2 variables and the email to authenticate us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;DtaSaml&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SessionsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SessionsController&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
      &lt;span class="c1"&gt;# retrieves the user to authenticate based on SamlResponse&lt;/span&gt;
      &lt;span class="vi"&gt;@resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth_options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@client_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_token&lt;/span&gt;
      &lt;span class="vi"&gt;@resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;
      &lt;span class="n"&gt;sign_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;store: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bypass: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="vi"&gt;@resource&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;

      &lt;span class="c1"&gt;# Here you can return a JWT token with the 3 variables&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;
      &lt;span class="n"&gt;warden&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;protected&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auth_options&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;scope: :user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;recall: &lt;/span&gt;&lt;span class="s1"&gt;'devise/sessions#new'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, I suggest use JWT to create a token with those 3 variables and retrieve it to the Frontend to continue the authentication flow of DTA, but we won’t see it in this article.&lt;/p&gt;

&lt;p&gt;Destroy&lt;br&gt;
The #destroy method, destroys the DTA's session invalidating the auth tokens.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;br&gt;
/config/initializers/devise.rb and /config/attribute-map.yml&lt;br&gt;
Configure these files as DSA’s page shows. The necessary data to configure the /config/initializers/devise.rb file should be provided by the IdP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migration&lt;/strong&gt;&lt;br&gt;
Modify the DTA’s migration and migrate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;change_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:null&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"email"&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:null&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

      &lt;span class="c1"&gt;## Tokens&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt; &lt;span class="ss"&gt;:tokens&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;add_index&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:provider&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;     &lt;span class="ss"&gt;unique: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;br&gt;
If you have some problem with URL’s creation, you can create them manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
We're done!&lt;br&gt;
Now, we can use at the same time, a SSO by SAML 2.0 with an API REST developed Ruby on Rails,&lt;br&gt;
I hope you find it useful, thank you for reading,&lt;br&gt;
Alan&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
