SBN

What’s OpenID Connect (OIDC) and Why Should You Care?

<p>Alright, let’s be honest — login systems are everywhere. From your favourite pizza delivery app to your office tools, every app asks you to <strong>Sign in with Google</strong> or <strong>Log in with Microsoft</strong>. Ever wondered how that works under the hood? That’s where <strong>OpenID Connect (OIDC)</strong> comes into play. In simple terms, OIDC is a modern way for apps to authenticate users by piggy backing on OAuth 2.0 (which you might already know powers those <strong>Sign in with…</strong> buttons). While OAuth is all about granting access to stuff like calendars and photos, OIDC adds an identity layer on top. This means it can also confirm <em>who you are</em>, not just whether you have permission to do something. Let’s take <strong>SSOJet</strong> — the product we’re building — as an example. Our goal is to help businesses connect their apps with multiple identity providers (like Google, Azure AD, Okta, and more) using standards like SAML and OIDC. If a customer wants users to log in with their Google account or Azure AD account, we plug into those providers using OIDC behind the scenes. <strong>Why should you care?</strong> Because OIDC makes logins faster, safer, and easier for both developers and users. No one wants to remember another password, and you don’t want to store passwords you don’t have to. With OIDC, you can offload that to trusted providers while still knowing exactly who’s using your app. <strong>In a nutshell:</strong></p>
<ul>
<li><strong>OAuth 2.0</strong> = &quot;Can this app access my stuff?&quot;</li>
<li><strong>OpenID Connect</strong> = &quot;Who’s the person behind this login?&quot;</li>
</ul>
<p>And the best part? They work together beautifully. In the next section, I’ll break down how this login flow actually works — with a simple, clean diagram to make sense of it all.</p>
<h2><strong>How the OIDC Login Flow Actually Works</strong></h2>
<p>Okay, so now you know what OIDC is. But how does it actually work when you hit that <strong>Login with Google</strong> button? Let’s break it down in plain English — no jargon, no fluff. Here’s the idea: your app (called the <strong>Relying Party</strong> in OIDC land, but let’s just call it your app) doesn’t want to deal with passwords. So, it hands that job over to a trusted <strong>Identity Provider (IdP)</strong> like Google, Microsoft, or whoever you choose. They’ll handle the login, and then tell your app <em>who just signed in</em>. Here’s a super simple version of the flow we use at <strong>SSOJet</strong>:</p>
<h3><strong>The OIDC Login Flow in 6 Quick Steps:</strong></h3>
<ol>
<li><strong>User clicks &quot;Login with Google&quot;</strong> on your app.</li>
<li>Your app redirects them to the Google login page with a special request (this includes things like your app’s client ID, what info you want, and where to send them after).</li>
<li>Users logs into Google (or maybe they’re already logged in).</li>
<li>Google asks, “Hey, is it cool if this app accesses your basic info?” The user clicks <strong>Allow</strong>.</li>
<li>Google sends a <strong>code</strong> back to your app through a redirect.</li>
<li>Your app takes that code and makes a secure call to Google’s <strong>/token</strong> endpoint to swap it for tokens — an <strong>ID Token</strong> (which says who logged in) and an <strong>Access Token</strong> (if you need to grab extra stuff like calendar events).</li>
</ol>
<p><strong>That’s it. User’s logged in.</strong></p>
<p><img src="https://cdn.pseo.one/6853a4a8a2796a91bb994a76/687e6d61f6fe799d28851eff/whats-openid-connect-oidc-and-why-should-you-care/oidc-flow-9834feef.webp" alt=""></p>
<h3><strong>Key Endpoints You’ll Use:</strong></h3>
<ul>
<li><code>/authorize</code> — sends users to the login page</li>
<li><code>/token</code> — exchanges the code for tokens</li>
<li><code>/userinfo</code> — (optional) grab extra user profile info</li>
</ul>
<p>At <strong>SSOJet</strong>, we use this exact flow whether our customer picks Google, Microsoft, or another OIDC-compliant provider. The nice part? OIDC standardizes this stuff, so you don’t have to build a new flow for every IdP.</p>
<h2><strong>Picking the Right Identity Provider (IdP)</strong></h2>
<p>Alright, now that we know how the OIDC login flow works, here’s the next thing you’ll need to figure out: <strong>which identity provider should your app use?</strong> If you&#39;re building for yourself, it’s simple — maybe you just need Google or Microsoft. But if you&#39;re building something like <strong>SSOJet</strong>, where your customers might use different providers (Google, Azure AD, Okta, etc.), you need to be a bit smarter about it. <strong>What’s an Identity Provider (IdP) Again?</strong> An IdP is basically the service that handles your users&#39; authentication. It&#39;s the one saying, <strong>&quot;Yep, this person is who they claim to be.&quot;</strong> <strong>How We Pick at SSOJet</strong> At <strong>SSOJet</strong>, our goal is to support whatever IdP our customers use. That’s why we made sure our system can plug into popular ones like:</p>
<ul>
<li><strong>Google</strong> <strong>Workspace</strong></li>
<li><strong>Okta</strong></li>
<li><strong>Microsoft Entra (Azure AD)</strong></li>
<li><strong>OneLogin</strong> and literally any IdP that talks OIDC.</li>
</ul>
<h2><strong>OIDC Login Example — Let’s Build It in a .NET Web App</strong></h2>
<p>Alright — enough theory, let’s build something real. I’m going to show you how we set up a basic OIDC login in a <strong>.NET web app</strong>, similar to how we wired it up for <strong>SSOJet</strong> in our early prototypes. Good news: thanks to OIDC libraries and middleware, you don’t have to start from scratch.</p>
<h3>What You’ll Need:</h3>
<ul>
<li>A <strong>.NET 6 or 7 Web App</strong></li>
<li>An <strong>OIDC provider account</strong> (Google, SSOJet, Azure AD — pick your favorite)</li>
<li>A <strong>Client ID</strong> and <strong>Client Secret</strong> from your IdP</li>
<li>Redirect URI (like <code>https://localhost:5001/signin-oidc</code> for local testing)</li>
</ul>
<h3>Step 1: Configure Your Application</h3>
<p>Go into your IdP’s developer console and create a new app/client:</p>
<ul>
<li>Set <strong>Redirect URI</strong> (where the IdP will send the user after login)</li>
<li>Note down the <strong>Client ID</strong> and <strong>Client Secret</strong></li>
<li>Choose the scopes you need (<code>openid</code>, <code>profile</code>, <code>email</code>)</li>
</ul>
<p>In <strong>SSOJet</strong>, follow <a href="https://docs.ssojet.com/en/how-to-guides/sso/oidc-sso-connection/">this Guide</a> for configurning Application</p>
<h3>Step 2: Add NuGet Packages</h3>
<p>In your .NET project, grab the required package:</p>
<pre><code>dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
</code></pre>
<h3>Step 3: Update Program.cs / Startup.cs</h3>
<p>Here’s a simple config using SSOJet as an example:</p>
<pre><code>builder.Services.AddAuthentication(options =&gt; { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(&quot;oidc&quot;, options =&gt; { options.Authority = &quot;https://aauth.ssojet.com/v1&quot;; options.ClientId = &quot;&quot;; options.ClientSecret = &quot;&quot;; options.CallbackPath = &quot;/signin-oidc&quot;; options.ResponseType = &quot;code&quot;; options.SaveTokens = true; options.Scope.Add(&quot;openid&quot;); options.Scope.Add(&quot;profile&quot;); options.Scope.Add(&quot;email&quot;); options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = &quot;name&quot;, RoleClaimType = &quot;role&quot; }; });
</code></pre>
<p><strong>Breakdown:</strong></p>
<ul>
<li>We’re telling .NET to use cookies for sessions</li>
<li>OIDC config points to the IdP (Google’s endpoint here)</li>
<li>It asks for tokens using the <code>code</code> flow (the safest one)</li>
<li>And we save tokens for later use (if needed)</li>
</ul>
<h3>Step 4: Add Login and Logout Endpoints</h3>
<pre><code>app.MapGet(&quot;/login&quot;, async context =&gt; { await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = &quot;/&quot; }); }); app.MapGet(&quot;/logout&quot;, async context =&gt; { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme); });
</code></pre>
<h3>That’s It — You’re Live</h3>
<p>Run your app, visit <code>/login</code>, and you’ll get redirected to Google’s sign-in page. Log in, and your app now knows who you are — using OIDC. In <strong>SSOJet</strong>, we built this same flow, but made it dynamic based on the customer’s chosen IdP config. So every client could plug in their Google or Microsoft tenant details and go live in minutes.</p>
<h2>Meet the Tokens You’ll See in OIDC</h2>
<p>When the IdP sends your app a response after a successful login, you’ll typically get:</p>
<ul>
<li><strong>ID Token</strong> → This is the important one for OIDC. It’s a JSON Web Token (JWT) that says <em>who</em> logged in.</li>
<li><strong>Access Token</strong> → If your app needs to grab stuff from the IdP’s APIs (like profile info), you’ll use this.</li>
<li><strong>Refresh Token</strong> (optional) → Lets you get new tokens later without asking the user to log in again.</li>
</ul>
<p>In <strong>SSOJet</strong>, we mostly care about the <strong>ID Token</strong> for authentication. If the customer</p>
<h3><strong>What’s Inside an ID Token?</strong></h3>
<p>It’s a JWT — meaning it’s a Base64‑encoded JSON blob. Here’s an example decoded:wants extra profile data, we’ll hit the <strong>/userinfo</strong> endpoint using the Access Token.</p>
<pre><code>{ &quot;iss&quot;: &quot;https://auth.ssojet.com/v1&quot;, &quot;sub&quot;: &quot;110169484474386276334&quot;, &quot;aud&quot;: &quot;123-client-id&quot;, &quot;exp&quot;: 1713541225, &quot;iat&quot;: 1713537625, &quot;email&quot;: &quot;[email protected]&quot;, &quot;name&quot;: &quot;John Doe&quot; }
</code></pre>
<p><strong>Key parts to check:</strong></p>
<ul>
<li><code>iss</code> (issuer) — who issued this token</li>
<li><code>aud</code> (audience) — should match your app’s client ID</li>
<li><code>exp</code> (expiry) — when the token stops being valid</li>
<li><code>sub</code> — the unique ID for this user</li>
</ul>
<h3>How to Validate Tokens (and Why You Should)</h3>
<p>Don’t just accept any token you get. Validate it. Here’s what we check at <strong>SSOJet</strong> before trusting any ID Token:</p>
<ul>
<li><strong>Verify the signature</strong> — Make sure it’s signed by the right IdP</li>
<li><strong>Check the issuer (<code>iss</code>)</strong> — Should be your IdP’s URL</li>
<li><strong>Check the audience (<code>aud</code>)</strong> — Must match your app’s client ID</li>
<li><strong>Check the expiry (<code>exp</code>)</strong> — Don’t accept old tokens</li>
<li><strong>Confirm the nonce (if used)</strong> — Protects against replay attacks</li>
</ul>
<p>You can easily validate JWTs using libraries like <code>System.IdentityModel.Tokens.Jwt</code> in .NET, or decode them on <a href="https://jwt.compile7.org/">jw</a><a href="https://jwt.compile7.org/">t.compile7.org</a> to peek inside.</p>
<h3>Where Should You Store Tokens?</h3>
<p>Here’s the rule we follow at <strong>SSOJet</strong>:</p>
<ul>
<li><strong>ID Tokens and Access Tokens</strong> → Store in secure, HTTP-only cookies or server-side session stores.</li>
<li><strong>Never store them in localStorage or sessionStorage</strong> in the browser — those get snatched easily by cross-site scripting (XSS) attacks.</li>
</ul>
<p>And if you’re keeping Refresh Tokens (which we usually avoid in SPAs or public clients), keep them server-side only.</p>
<h3>Handling Token Expiry</h3>
<p>Tokens don’t live forever — and that’s a good thing. When an <strong>Access Token</strong> or <strong>ID Token</strong> expires:</p>
<ul>
<li>Either redirect the user to log in again</li>
<li>Or if you’ve stored a <strong>Refresh Token</strong> (on the server), swap it for new tokens silently</li>
</ul>
<p>At <strong>SSOJet</strong>, for security, we usually avoid long-lived Refresh Tokens for public-facing apps and opt for short sessions with easy reauthentication flows.</p>
<h2>That’s a Wrap</h2>
<p>So there you go — from what OIDC is, how its login flow works, how to pick your IdP, wire it up in a .NET app, handle tokens safely, to managing sessions and logouts like a pro. This is exactly how we built the authentication flow at <strong>SSOJet</strong>, and it’s been rock solid for customers big and small. <strong>Next move?</strong> Spin up your own test project, plug in Google as an IdP, and watch the magic happen. Once you get the basics down, you’ll be ready to connect Azure AD, Auth0, or any other OIDC-compliant provider you want. If you liked this breakdown, drop a comment — or check out our other posts on SAML, magic links, and passkeys. Always happy to nerd out on auth stuff.</p>

*** This is a Security Bloggers Network syndicated blog from SSOJet - Enterprise SSO &amp; Identity Solutions authored by SSOJet - Enterprise SSO & Identity Solutions. Read the original post at: https://ssojet.com/blog/whats-openid-connect-oidc-and-why-should-you-care