{"id":3431,"date":"2021-03-26T00:48:36","date_gmt":"2021-03-26T00:48:36","guid":{"rendered":"https:\/\/wiki.thomasandsofia.com\/?p=3431"},"modified":"2021-03-26T21:10:03","modified_gmt":"2021-03-26T21:10:03","slug":"oauth-and-openid-connect","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=3431","title":{"rendered":"OAuth 2.0 and OpenID Connect"},"content":{"rendered":"<p><a href=\"https:\/\/www.youtube.com\/watch?v=996OiexHze0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=996OiexHze0<\/a><\/p>\n<h1>OAuth 2.0 Definitions<\/h1>\n<ul>\n<li>Resource owner\n<ul>\n<li>The user \/ person logging in<\/li>\n<li>The owner of the data that the application needs to access<\/li>\n<\/ul>\n<\/li>\n<li>Client\n<ul>\n<li>The application the Resource owner is using<\/li>\n<\/ul>\n<\/li>\n<li>Authorization server\n<ul>\n<li>Service that grants the requested access to the Client\n<ul>\n<li>Client: I would like access to Resource owner&#8217;s contacts<\/li>\n<li>Auth server: Resource owner, do you grant this access?<\/li>\n<li>Resource owner: Yes, please grant that access<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Resource server\n<ul>\n<li>Server \/ API that holds the data the Client wants to get to.<\/li>\n<\/ul>\n<\/li>\n<li>Authorization grant\n<ul>\n<li>The &#8220;thing&#8221; that proves the Resource owner granted access<\/li>\n<\/ul>\n<\/li>\n<li>Redirect URI, aka Call back\n<ul>\n<li>The URI the Authorization server redirects back to after auth is granted<\/li>\n<\/ul>\n<\/li>\n<li>Access token, aka Bearer token\n<ul>\n<li>The key the Client will use to gain access to the requested Scopes<\/li>\n<li>Any Scope requests not permitted by the Access token will be denied.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1>OAuth Authorization code flow<\/h1>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3432\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake.png\" alt=\"\" width=\"801\" height=\"438\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake.png 801w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake-300x164.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake-768x420.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/oauth-handshake-150x82.png 150w\" sizes=\"auto, (max-width: 801px) 100vw, 801px\" \/><\/a><\/p>\n<ol>\n<li>Client sends request (Scopes) to Authorization server with Redirect URI<\/li>\n<li>Authorization server gets login from Resource owner<\/li>\n<li>Authorization server asks for permission from Resource owner to grant Client access to Scopes<\/li>\n<li>Resource owner agrees to grant access<\/li>\n<li>Authorization server returns to Client at Redirect URI with Authorization grant<\/li>\n<li>Client provides Authorization server with Auth grant requesting Access token\n<ol>\n<li>This step also includes the Client Secret (See below)<\/li>\n<\/ol>\n<\/li>\n<li>Authorization server verifies Auth grant and replies with Access token.<\/li>\n<li>Client submits request for Scopes to Resource server with Access token<\/li>\n<li>Resource server validates token, verifies it is in Scope of request and returns data<\/li>\n<\/ol>\n<h1>More Terminology<\/h1>\n<ul>\n<li>Scopes\n<ul>\n<li>The list of access levels the Authorization server understands are called Scopes.\n<ul>\n<li>contacts.read<\/li>\n<li>contacts.write<\/li>\n<li>email.read<\/li>\n<li>email.delete<\/li>\n<\/ul>\n<\/li>\n<li>Client may request multiple Scopes<\/li>\n<\/ul>\n<\/li>\n<li>Consent\n<ul>\n<li>The &#8220;screen&#8221; where Authorization server presents the list of Scopes to Resource owner to grant permission<\/li>\n<\/ul>\n<\/li>\n<li>Back Channel (Dashed lines in diagram)\n<ul>\n<li>Highly secure channel\n<ul>\n<li>APIs<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Front Channel (Solid lines in diagram)\n<ul>\n<li>Secure, but not as secure, channel.\n<ul>\n<li>Browsers<\/li>\n<li>Anything that interacts with the user<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1>The Flow<\/h1>\n<h2>Before this can happen, the Client needs to be registered with Google.<\/h2>\n<ul>\n<li>client_id<\/li>\n<li>client_secret<\/li>\n<\/ul>\n<h2>1. Starting the flow<\/h2>\n<pre>https:\/\/accounts.google.com\/o\/oauth2\/v2\/auth?client_id=abc123&amp;\r\n  redirect_uri=https:\/\/my.client.com\/callback&amp;\r\n  scope=profile&amp;\r\n  response_type=code&amp;\r\n  state=foobar<\/pre>\n<h2>5. Calling Back<\/h2>\n<p><strong>Auth has been denied by Resource owner or some other error<br \/>\n<\/strong><\/p>\n<pre>https:\/\/my.client.com\/callback?error=access_denied&amp;error_description=The user did not consent<\/pre>\n<p><strong>Auth accepted<\/strong><\/p>\n<pre>https:\/\/my.client.com\/callback?code=oMsCelvIaQm6bTrgtp7&amp;state=foobar<\/pre>\n<h2>6. Requesting the token<\/h2>\n<pre>POST www.googleapis.com\/oauth2\/v4\/token content-Type: application\/x-www\/form-urlencoded\r\n\r\ncode=oMsCelvIaQm6bTrgtp7&amp;\r\n  client_id=abc123&amp;\r\n  client_secret=secret123&amp;\r\n  grant_type=authorization_code<\/pre>\n<h2>7. Get the token<\/h2>\n<pre>{\r\n  \"access_token\": \"fFAGrNJru1FTz70BzhT3zG\",\r\n  \"expires_in\": 3920,\r\n  \"token_type\": \"Bearer\"\r\n}<\/pre>\n<h2>8. Use the access token<\/h2>\n<pre>GET api.google.com\/some\/endpoint\r\nAuthorization: Bearer fFAGrNJru1FTz70BzhT3zG<\/pre>\n<h2>9. Data returned \/ Action taken<\/h2>\n<p>This is only performed after the token has been verified and IF the token is within the Scope of the request.<\/p>\n<p>&nbsp;<\/p>\n<h1>OAuth 2.0 Flows<\/h1>\n<ul>\n<li>Authorization code\n<ul>\n<li>Front channel + Back channel<\/li>\n<\/ul>\n<\/li>\n<li>Implicit\n<ul>\n<li>Front channel only (no backchannel available)<\/li>\n<li>Can have a direct request for the token via the browser<\/li>\n<\/ul>\n<\/li>\n<li>Resource owner password credentials\n<ul>\n<li>Back channel only\n<ul>\n<li>May already have credentials<\/li>\n<li>Usually only used to get older applications to work correctly<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Client credentials\n<ul>\n<li>Back channel only\n<ul>\n<li>Example: Machine to machine service communication<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1>Implicit Flow<\/h1>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3436\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake.png\" alt=\"\" width=\"800\" height=\"428\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake-300x161.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake-768x411.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/implicit-handshake-150x80.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<ul>\n<li>The big difference between Implicit Flow vs Authorization code starts with the initial contact is <code>response_type=token<\/code> vs. <code>response_type=code<\/code><\/li>\n<li>Slightly less secure\n<ul>\n<li>No code verification<\/li>\n<li>Token can be exposed to the browser<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>https:\/\/accounts.google.com\/o\/oauth2\/v2\/auth?client_id=abc123&amp;\r\n  redirect_uri=https:\/\/my.client.com\/callback&amp;\r\n  scope=profile&amp;\r\n  response_type=token&amp;\r\n  state=foobar<\/pre>\n<p>&nbsp;<\/p>\n<h1>Difference between Authorization vs Authentication<\/h1>\n<ul>\n<li>OAuth is designed for Authorization\n<ul>\n<li>Is your token scoped for that thing you want to do<\/li>\n<li>Does not really care who you are.\n<ul>\n<li>No standard way for getting the user&#8217;s creds.<\/li>\n<li>No common set of scopes.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Authentication was still handed external to OAuth and differently by each company.<\/li>\n<\/ul>\n<h1>Introducing OpenID Connect<\/h1>\n<ul>\n<li>OpenID Connect is for Authentication<\/li>\n<li>Not really a new protocol, but an extension added to OAuth 2.0<\/li>\n<li>Includes\n<ul>\n<li>ID token\n<ul>\n<li>Represents information about the user<\/li>\n<li>Formatted as a JSON Web Token (JWT &#8211; pronounced &#8216;Jwot&#8217;?)\n<ul>\n<li>Looks encrypted but can be decoded with <a href=\"https:\/\/jsonwebtoken.io\" target=\"_blank\" rel=\"noopener\">https:\/\/jsonwebtoken.io<\/a> and other tools.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>UserInfo endpoint for getting more user information<\/li>\n<li>Standard set of scopes<\/li>\n<li>Standardized implementation<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1>OpenID Connect Flow<\/h1>\n<ul>\n<li>Is both an OpenID request AND an OAuth request<\/li>\n<li>When exchanging the code, you get both the access token and ID token.<\/li>\n<\/ul>\n<pre>scope: openid profile<\/pre>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3440\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow.png\" alt=\"\" width=\"800\" height=\"422\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow-300x158.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow-768x405.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/openid-and-oath-flow-150x79.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>The ID token (JWT)<\/h1>\n<pre>(Header)\r\n...\r\n{\r\n  \"iss\": \"https:\/\/auth.server.com\",\r\n  \"sub\": \"user@email.com\",\r\n  \"name\": \"User Name\",\r\n  \"aud\": \"BlAhbLah\",\r\n  \"exp\": UNIXDATETIME,\r\n  \"iat\": UNIXDATETIME,\r\n  \"auth_time\": UNIXDATETIME\r\n}\r\n...\r\n(Signature)<\/pre>\n<ul>\n<li>Signature includes validation information that authenticates that the ID token is legit and not forged.<\/li>\n<\/ul>\n<h1>Using the userinfo endpoint<\/h1>\n<ul>\n<li>Part of the OpenID Connect protocol<\/li>\n<\/ul>\n<pre>GET api.google.com\/some\/endpoint \r\nAuthorization: Bearer fFAGrNJru1FTz70BzhT3zG\r\n\r\n200 OK\r\n\r\nContent-Type: application\/json\r\n\r\n{\r\n  \"sub\": \"user@email.com\",\r\n  \"name\": \"User Name\",\r\n  \"profile_picture\": \"http:\/\/dude.picture.link\/dude\"\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h1>Identity Use Cases<\/h1>\n<ul>\n<li>Simple Login: OpenID Connect (Authentication)<\/li>\n<li>Single sign-on across sites: OpenID Connect (Authentication)<\/li>\n<li>Mobile app login: OpenID Connect (Authentication)<\/li>\n<li>Delegated authorization: OAuth 2.0 (Authorization)<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h1>Which grant type (flow) to use<\/h1>\n<h3>Web application with server backend: Authorization code flow<\/h3>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3442\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp.png\" alt=\"\" width=\"800\" height=\"367\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp-300x138.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp-768x352.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/webapp-150x69.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<h3>Native mobile app: Authorization code flow with PKCE (proof code for Key Exchange, aka Pixie)<\/h3>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3443\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp.png\" alt=\"\" width=\"800\" height=\"413\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp-300x155.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp-768x396.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/mobileapp-150x77.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h3>JavaScript app (SPA single page app) with API backend: Implicit flow<\/h3>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3444\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp.png\" alt=\"\" width=\"800\" height=\"426\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp-300x160.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp-768x409.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/javaapp-150x80.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<h3>Microservices and APIs: Client credentials flow<\/h3>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3445\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso.png\" alt=\"\" width=\"800\" height=\"385\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso.png 800w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso-300x144.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso-768x370.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2021\/03\/3rdpartysso-150x72.png 150w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<h1>Additional resources<\/h1>\n<ul>\n<li>oauth.com (get free ebook)<\/li>\n<li>developer.okta.com (free account)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/www.youtube.com\/watch?v=996OiexHze0 OAuth 2.0 Definitions Resource owner The user \/ person logging in The owner of the data that the application needs to access Client The application the Resource owner is using Authorization server Service that grants the requested access to the Client Client: I would like access to Resource owner&#8217;s contacts Auth server: Resource owner, ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=3431\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[67,49],"tags":[],"class_list":["post-3431","post","type-post","status-publish","format-standard","hentry","category-oauth","category-security-2"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3431"}],"version-history":[{"count":7,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3431\/revisions"}],"predecessor-version":[{"id":3446,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3431\/revisions\/3446"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}