Understanding OAuth2 and OpenID Connect
polarsparc.com
polarsparc.com
I think that if you need that separation between your resource servers and authorization server, the OAuth dance can be a bit complicated, you can just use a simple api key. But as soon as you start to allow outside access to your systems, I'd suggest using an OAuth server (disclosure, I work for FusionAuth, a free as in beer competitor to Keycloak, Gluu, etc).
Additional things that I wish had been in the article:
* Don't use implicit flow, use the authorization code grant with PKCE.
* Don't use resource owner password flow; it was designed to allow existing systems to bridge into OAuth and shouldn't be used in new systems today.
Both the implicit flow and the resource owner password flow are not part of OAuth 2.1--here's a post I wrote about it: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
* Also, storing access tokens should be done carefully in the browser (httponly, secure cookies is the best way). If you can't do that, then use a server side proxy to store the access tokens. Otherwise your access tokens might get stolen by code executing in the browser.
* OIDC is built on top of OAuth and has a standard set of claims. If you can get by on what OIDC defines, you can switch between identity provider implementations fairly easily.
Ack, this should have been
I think that if you do not need that separation between your resource servers and authorization server, ...
Do you have any examples of Authorization servers in the wild doing this or front end SDKs that work with that?
I’m very curious, I’m doing an SPA security research project at work and I’m very interested in these stories and learning more.
I’ve seen some folks do refresh in an httponly cookie, and Access in the js space. I’ve seen another example (auth0) put the refresh token in a web worker and access token accessible in js.
And I’ve seen things like msal.js just say F it and make them all accessible to js.
Sorry, I was wrong. According to the spec you definitely have to send the access token back in the response body[0].
However, a client can store them as cookies (or, as you mention, other places, such as a service worker[1]). This is useful if the client is a single page application (SPA), which may need to present the access token to other resource servers.
RFC 6750 has something to say about how to store the bearer token [2]:
> Don't store bearer tokens in cookies: Implementations MUST NOT store bearer tokens within cookies that can be sent in the clear (which is the default transmission mode for cookies). Implementations that do store bearer tokens in cookies MUST take precautions against cross-site request forgery.
So, I apologize. The authorization server wouldn't send the access token as a cookie. Instead, there'd be a server side proxy which would request the token and then send it down as a secure cookie. Again, best practice would be to keep the access token on the server side proxy and just send a session id down to the client, but that sometimes doesn't work. Here is a diagram illustrating that path (with the 'store' entity acting as the proxy mentioned above)[3].
0: https://tools.ietf.org/html/rfc6749#section-5.1
1: https://gitlab.com/jimdigriz/oauth2-worker
2: https://tools.ietf.org/html/rfc6750#page-13
3: https://fusionauth.io/learn/expert-advice/authentication/web...
The way I see it with SPA and tokens in JS accessible space is that you're exposing your users to the possibility of token theft and user impersonation if someone is able pull off an XSS. This is not so different than using a session cookie that is not marked as 'httponly'. What's old is new again :)
I have also heard the argument that we shouldn't worry about token theft, because it's already too late if you're XSS'd, but I don't buy into that rhetoric(not saying XSS isn't incredibly bad).
Unfortunately I work in financial services, so we can't just skate by and assume that we're so uninteresting that an adversary with advanced capabilities wouldn't look to exploit our external or internal users somehow.
One another thing we're looking into is access tokens, like having the user re-authenticate or use a stronger factor(or multiple) to get the AS to grant them a very short lived, non-refreshable token to do their sensitive operation.
I'm going to check out the fusionauth blog for a bit more inspiration, if you're interested in continuing this discussion I would be interested in carrying it on.
The difference is a session cookie is tied to one server, but an access token could be used with many different APIs or other services. That said, an access token may expire more quickly, so the devil is definitely in the details.
> One another thing we're looking into is access tokens, like having the user re-authenticate or use a stronger factor(or multiple) to get the AS to grant them a very short lived, non-refreshable token to do their sensitive operation.
That makes sense, for sure. You could definitely require MFA to get an access token and have it be short lived. At that point it gets to a question of UX and how much impact you want on your users, but I'm not familiar with all the requirements you have.
> I'm going to check out the fusionauth blog for a bit more inspiration, if you're interested in continuing this discussion I would be interested in carrying it on.
Please do! Happy to respond here or if you want to check out the FusionAuth forum (which I monitor), you can find it on the the website under the resources tab.
I would have really liked to use auth0 or other authn services but not a fan of lock-in platforms, I want to export my db without enterprise plans.
The pricing model I'm thinking of is a pay per usage + a commission of the total usage per month.
Thank you @sjroot
I’m doing something somewhat similar, happy to exchange notes.
Also worth mentioning is ORY Hydra.
Anyways, seems interesting.
We do have a forever free community offering[0], but that's free as in beer, not as in speech.
I think it's a great product (that's part of why I joined the company) but don't want any confusion about that.
[0]: https://fusionauth.io/pricing has a list of the options.
Really amazing group of people, super genuine.
1) Most of the work around authentication is integrations (get the app to integrate with whatever authentication protocol/database). Integration is not a product, it's consulting services.
2) There are very established products for authentication servers. See Microsoft ADFS, PingIdentity and ForgeRock on premise. See Okta and auth0 on SaaS.
3) If you're going to roll some authentication as a company, you stick to Microsoft ADFS for internal employees or to Google/Facebook auth for external accounts. You need them anyway so there is absolutely no point in getting something else. (Yes, your company is gonna use microsoft windows internally and your customer will request google auth support).
4) There is absolutely no point for yet another product. What is it gonna do? It's gonna sit on top of google auth so you can integrate with it rather than with google? Pointless, might as well integrate to google/microsoft directly.
5) Where there is money is in consulting services, libraries and plugins. For examples make a plugin for apache/nginx/haproxy to use google auth, so developers can just put that in front of their service (legacy application) and it's mostly plug and play. Or easy library for python/java/whatever to integrate (developer can just configure a google id and URL and can retrieve user info). It's hard though because of customization hell, every use case wants to do things slightly differently.
That's my 2 cents working in the industry. For reference I've worked on authentication in startups for customers, in government projects for citizens and in companies for 100k+ employees.
https://github.com/HostedMetrics/django-allauth-sso
Hope folks find it useful!
Just dropped my job in order to catch up with everything I wanted to learn and what better way than to build a business.
Currently I'm a bit (1 month) behind the schedule cause I complicated everything in order to learn k8s, rust, web assembly, svelte/sapper...so much fun, on the other side I burned through my finances a little too fast so I might need a job soon.
Ory will probably offer a cloud service in the near future but I'm just scratching an itch for now.
It's so simple I wrote (and abandoned) a golang library that implements v1[2]. I didn't need the proxy abilities in v2 (and doubt most orgs actually do) and I use JSON in some places before it was in the standard but it was very easy to implement and thus I can say it's easy to understand. I've meant to convert the project to Rust for a long time but at this point I'll probably never get to it.
[0]: https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Spe...
[1]: https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol.htm...
It's an old protocol to do single sign on within a company. It worked well and I've seen it used in large companies circa 2010, allowing to support sso in their internal web applications, for employees.
CAS is irrelevant now. The world has standardized on OpenID Connect (and SAML as second choice). Anything that's on CAS was migrated or is pending migration to OIDC.
As a developer you will have to deal with OIDC (and maybe SAML) for integrations with google auth, facebook auth, microsoft active directory. You really don't want to go for a dying ecosystem (CAS), that's a dead end for your career.
I say this as someone who thought JWT was a core part of OAuth and it only added to the perceived complexity of the implementation.
JWTs are a part of the OIDC standard; from the standard itself[1],
> The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT) [JWT].
But your comment sounds like you're conflating OAuth & OIDC. (It is true for OAuth that you're not required to use JWTs.)
[1]: https://openid.net/specs/openid-connect-core-1_0.html#IDToke...
In many apps, these login redirects happen inside the app window, hiding the url. And even if the URL isn’t hidden, there’s suddenly a browser window inside my app and many unconscious “security checks” fail to load.
I’d much rather have the OAuth provider send me an email or get a notification that can be actioned within the OAuth providers app so that I know I’m not giving my credentials to something that looks like the OAuth providers sign in page.
My advice is to just always use the auth code grant with the PKCE extension. TLDR of that extension:
1) client generates a “secret key” that it sends with the authorization request. 2) server associates that key with the authorization code it returns to the authorized client 3) client must present that key again in order to exchange the authorization code for the access token.
Prevents the authorization code from being intercepted and abused.
Splitting hairs but no, Oauth has nothing to do with authentication. An introductory article like this should address the distinction between authentication and authorization in the first section IMO.
Distinction which is totally useless in practice as you certainly won’t have authorization without authentication.
At that point, the separation is more about capabilities/responsibilities than "does it happen?"
(This is what I do in my day job.)
Note that there's older OpenID (without "Connect"), which, to my knowledge, is more or less dead nowadays, and OpenID Connect, which is indeed built on top of OAuth. Both are indeed SSO, though.