<?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>DEV Community: Julius Pedersen</title>
    <description>The latest articles on DEV Community by Julius Pedersen (@deifyed_rt).</description>
    <link>https://dev.to/deifyed_rt</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%2F209540%2Faa2ee541-2676-4043-baf7-fb2a9985f3f5.jpg</url>
      <title>DEV Community: Julius Pedersen</title>
      <link>https://dev.to/deifyed_rt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deifyed_rt"/>
    <language>en</language>
    <item>
      <title>The Gatekeeper, OAuth2 OIDC authentication handling as a microservice</title>
      <dc:creator>Julius Pedersen</dc:creator>
      <pubDate>Fri, 18 Sep 2020 06:59:25 +0000</pubDate>
      <link>https://dev.to/deifyed_rt/the-gatekeeper-oauth2-oidc-authentication-handling-as-a-microservice-4khh</link>
      <guid>https://dev.to/deifyed_rt/the-gatekeeper-oauth2-oidc-authentication-handling-as-a-microservice-4khh</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Ever since I started programming I've been afraid of authentication. It seemes infinitely complex with sink holes around every corner. When implementing authentication in a web app, I wished login was as easy as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"AUTH_URL/login"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 and logout was as easy as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AUTH_URL/logout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 Since I was always dodging /outsourcing authentication, I never acquired the knowledge as to whether it was even possible. Due to a situation at work, I was forced to indulge and so; queue, the Gatekeeper.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffdmsdaj6dvh3ss74r23a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffdmsdaj6dvh3ss74r23a.png" alt="Alt Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Gatekeeper API is minimal. It exposes four endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;gatekeeper.url/login?redirect=&amp;lt;return url&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;gatekeeper.url/logout&lt;/span&gt;
&lt;span class="s"&gt;gatekeeper.url/userinfo&lt;/span&gt;
&lt;span class="s"&gt;gatekeeper.url/api&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/login?redirect=&amp;lt;return url&amp;gt;&lt;/code&gt; redirects the user to the authentication provider's login screen, and makes sure the user gets returned to return url upon successful login&lt;br&gt;
&lt;code&gt;/logout&lt;/code&gt; logs a user out&lt;br&gt;
&lt;code&gt;/userinfo&lt;/code&gt; returns a JSON object containing the logged in user's info&lt;br&gt;
&lt;code&gt;/api&lt;/code&gt; converts cookie to authentication header and proxies requests to backend services while making sure the session stays alive. &lt;/p&gt;
&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It is a service designed to handle integration against an OAuth2 OpenID Connect authentication provider. Instead of implementing the Authorization Code Flow in each of your frontends, the Gatekeeper will handle it for them.&lt;/li&gt;
&lt;li&gt;It's a tool for generating access tokens and refresh tokens for your web application and storing them in a best practice way. More specifically, as HttpOnly and Secure cookies.&lt;/li&gt;
&lt;li&gt;Ever wondered how you can set the authentication token as a HttpOnly cookie in your SPA? Gatekeeper knows. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What it isn't
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It's not an authentication provider, it's a tool for integrating your frontend with an OAuth2 OpenID Connect authentication provider.&lt;/li&gt;
&lt;li&gt;It's not a tool for validating tokens, though it can be used as such by sending the token to /userinfo and handling the 200 or 401. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;To run the Gatekeeper in a docker container, run the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 4554:4554 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:4554 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;a client &lt;span class="nb"&gt;id &lt;/span&gt;from your auth provider&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;a secret &lt;span class="k"&gt;for &lt;/span&gt;the client &lt;span class="k"&gt;in &lt;/span&gt;the auth provider&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;DISCOVERY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;the discovery url &lt;span class="k"&gt;for &lt;/span&gt;your client provider&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;ORIGIN_WHITELIST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;TOKEN_COOKIES_SECURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  docker.pkg.github.com/oslokommune/gatekeeper/gatekeeper:1.0.35
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By navigating from your frontend application to &lt;a href="http://localhost:4554/login" rel="noopener noreferrer"&gt;http://localhost:4554/login&lt;/a&gt;, the Gatekeeper will redirect you to your auth providers login screen. Upon a successful login, the Gatekeeper will set the access token and refresh token as HttpOnly cookies. To clear these cookies and invalidate the refresh token, simply post to &lt;a href="http://localhost:4554/logout" rel="noopener noreferrer"&gt;http://localhost:4554/logout&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To fetch information about the currently logged in user, your frontend app can GET &lt;a href="http://localhost:4554/userinfo" rel="noopener noreferrer"&gt;http://localhost:4554/userinfo&lt;/a&gt;. Requests to /userinfo will automatically refresh the access token if need be. &lt;/p&gt;

&lt;p&gt;You can also configure the Gatekeeper to check and refresh the access token on demand with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;UPSTREAMS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-service&lt;span class="o"&gt;=&lt;/span&gt;http://my-service.mydomain.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the requests going through the proxy at &lt;a href="http://localhost:4554/api/my-service/" rel="noopener noreferrer"&gt;http://localhost:4554/api/my-service/&lt;/a&gt; will now get their access tokens refreshed when the need arise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Gatekeeper currently only supports the Authentication Code Flow.&lt;/li&gt;
&lt;li&gt;The Gatekeeper should in theory support all OAuth2 OIDC providers, and it will at some point, but for now it's only been tested with Keycloak and Auth0.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contribution
&lt;/h2&gt;

&lt;p&gt;The code is available at &lt;a href="https://github.com/oslokommune/gatekeeper" rel="noopener noreferrer"&gt;https://github.com/oslokommune/gatekeeper&lt;/a&gt; and we'd very much appreciate PR's, comments and issues.&lt;/p&gt;

</description>
      <category>oauth2</category>
      <category>oidc</category>
      <category>opensource</category>
      <category>express</category>
    </item>
  </channel>
</rss>
