I have familiarity with OAuth 2.0 / OpenID Connect but am new to WebAuthn. I am trying to understand how a scenario using those OAuth flows and connections would work using WebAuthn. I thought by mapping concepts from oauth to webauthn I would be able better understand the concepts.
I think similar to how in OAuth implicit grant flow a client may receive an id_token and access_token, in WebAuthn a client may receive a credential object from the Authenticator using navigator.credential.create.
The part I do not understand is how this credential can reliably be consumed by downstream services. In OAuth a client or server may send "access_tokens" and the receiving servers may request the public keys from the authorities to validate that it hasn't been tampered, is not expired, has correct audience, etc. This relies on the authorities having a publicly available /.well-known endpoint with the public keys.
However, I think because the keys are specific to the authenticator instead of a single shared public key it is not possible to have these be discoverable.
This is where I don't understand how credentials could be consumed by services. I thought the client would have to send the public key WITH the authenticator and client data but this is 3 pieces of information and awkward. Sending a single access_token seems actually cleaner.
I created a graphic to explain visually.
(It may have technical inaccuracies, but hopefully the larger point is made clearer)
https://excalidraw.com/#json=fIacaTAOUQ9GVgsrJMOPr,yYDVJsmuXos0GfX_Y4fLRQ
Here are the 3 questions embedded in the image:
What data does the client need to send to the server in order for the server to use the data? (Similar to sending access_token)
How would sever get the public key to decrypt data?
Which piece of data is appropriate / standardized to use as the stable user id?
As someone else mentioned - where there are a lot of commonalities between how WebAuthn and something like OpenID Connect work, they aren't really useful for understanding how WebAuthn works - they are better to explore after you understand WebAuthn.
A WebAuthn relying party does not have its own cryptographic keys or secrets or persistent configuration - it just has a relying party identifier, which is typically the web origin. The client (browser and/or platform) mediate between the relying party and authenticators, mostly protecting user privacy, consent, and providing phishing protection.
The relying party will create a new credential (e.g. key pair) with the authenticator of a user's choosing, be it a cell phone or a physical security key fob in their pocket. The response is the public key of a newly created key pair on the authenticator. That public key is saved against the user account by the RP.
In a future authentication, the authentication request results in a response signed by that public key. The private portion is never meant to leave the authenticator - at least not without cryptographic protections.
This does pair well with something like OpenID Connect. The registration is normally by web domain, which means that there could be a lot of manual registrations necessary (and potentially management, and recovery, and other IAM type activities) necessary. With OpenID Connect, you can centralize the authentication of several applications at a single point, and with it centralize all WebAuthn credential management.
I thought by mapping concepts from oauth to webauthn I would be able better understand the concepts.
This seems to be working against you - you're trying to pattern match WebAuthn onto a solution for a different kind of problem (access delegation). Overloaded terminology around "authentication" doesn't help, but the WebAuthn specification does make things a bit more clear when it describes what it means with "Relying Party":
Note: While the term Relying Party is also often used in other contexts (e.g., X.509 and OAuth), an entity acting as a Relying Party in one context is not necessarily a Relying Party in other contexts. In this specification, the term WebAuthn Relying Party is often shortened to be just Relying Party, and explicitly refers to a Relying Party in the WebAuthn context. Note that in any concrete instantiation a WebAuthn context may be embedded in a broader overall context, e.g., one based on OAuth.
Concretely: in your OAuth 2.0 diagram WebAuthn is used during step 2 "User enters credentials", the rest of it doesn't change. Passing the WebAuthn credentials to other servers is not how it's meant to be used, that's what OAuth is for.
To clarify one other question "how would sever get the public key to decrypt data?" - understand that WebAuthn doesn't encrypt anything. Some data (JS ArrayBuffers) from the authenticator response is typically base64 encoded, but otherwise the response is often passed to the server unaltered as JSON. The server uses the public key to verify the signature, this is either seen for the first time during registration, or retrieved from the database (belonging to a user account) during authentication.
EDIT: Added picture for a clearer understanding of how webauthn works, since it has nothing to do with OAuth2 / OpenID.
(source: https://passwordless.id/protocols/webauthn/1_introduction)
Interestingly enough, what I aim to do with Passwordless.ID is a free public identity provider using webauthn and compatible with OAuth2/OpenID.
Here is the demo of such a "Sign in" button working with OAuth2/OpenID:
https://passwordless-id.github.io/demo/
Please note that this is an early preview, still in development and somewhat lacking regarding the documentation. Nevertheless, it might be useful as working example.
That said, I sense some confusion in the question. So please let me emphasize that OAuth2 and WebAuthN are two completely distinct and unrelated protocols.
WebAuthN is a protocol to authenticate a user device. It is "Hey user, please sign me this challenge with your device to prove it's you"
OAuth2 is a protocol to authorize access to [part of] an API. It is "Hey API, please grant me permission to do this and that on behalf of the user".
OpenID builds on OAuth2 to basically say "Hey API, please allow me to read the user's standardized profile!".
WebauthN is not a replacement for OAuth2, they are 100% independent things. OAuth2 is to authorize (grant permissions) and is unrelated to how the user actually authenticates on the given system. It could be with username/password, it could be with SMS OTP ...and it could be with WebauthN.
There is a lot of good information in the other answers and comments which I encourage you to read. Although I thought it would be better to consolidate it in a single post which directly responds to the question from OP.
How does WebAuthN allow dependent web API's to access public key for decrypting credential without having to send the key?
There were problems with the question:
I used the word "decrypt" but this was wrong. The data sent is signed not encrypted and so key is not used to decrypted but verify the signature.
I was asking how a part of OAuth process can be done using WebAuthN however, this was misunderstanding. WebAuthN is not intended to solve this part of process so the question is less relevant and doesn't make sense to be answered directly.
Others have posted that WebAuthN can be used WITH OAuth so downstream systems can still receive JWTs and verify signatures as normal. How these two protocols are paired is a out of scope.
What data does the client need to send to the server in order for the server to use the data?
#Rafe answered: "table with user_id, credential_id, public_key and signature_counter"
See: https://www.w3.org/TR/webauthn-2/#authenticatormakecredential
How would server get the public key to decrypt data?
Again, decrypt is wrong word. Server is not decrypting only verifying signature
Also, the word server has multiple meanings based on context and it wasn't clarified in the question.
WebAuthN: For the server which acts as Relying Party in WebAuthN context, it will verify signature during authentication requests. However, the server in question was intended to mean the downstream APIs would not be part of WebAuthN.
OAuth: As explained by others, theses API servers could still be using OAuth and request public key from provider for verification and token contains necessary IDs and scopes/permissions. (Likely means able to re-use existing JWT middlewares)
Which piece of data is appropriate / standardized to use as the stable user id?
For WebAuthN the user object requires { id, name, displayName }. However, it intentionally does not try to standardize how the ID may propagated to downstream systems. That is up to developer.
See: https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialuserentity
For OAuth
sub: REQUIRED. Subject Identifier. A locally unique and never reassigned identifier within the Issuer for the End-User
See: https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
Hopefully I didn't make too many technical inaccuracies. 😬
I understand that there is a bit of an overlap between OAuth, OIDC and SAML. Especially if I understand right, Authentication is provided by both OIDC and SAML to achieve SSO.
However, my question is from a developer's perspective.
Is OAuth relatively easier to develop and maintain than SAML? Both as Identity provider and as a consumer.
Is any one of them more prone to bugs or hazzles than the other one?
With respect to user experience which one is more easier to setup with your enterprise Identity provider, "in general" ?
Finally, is there a recommended option when you as a consumer want to provide SSO? OIDC or SAML?
Just so you do not confuse this question to be yet another "SAML vs OIDC" : Say you want to provide SSO to your product via Azure AD, G-Suite or Okta etc. All of which support both OIDC and SAML, then would you go with OIDC or SAML?
OAuth is for authorization. OIDC and SAML are for authentication.
Whichever you choose, I would strongly recommend not implementing this yourself. Instead, choose an open-source or commercial product with a good track record. You don't want to be responsible for security weaknesses etc.
The choice of OIDC vs SAML often comes down to what's supported by third party sites you wish to SSO to. If this is purely internal, you may decide to use OIDC. If this is for SSO to third parties, you may decide to use SAML as this is much more commonly used in the corporate world.
I am developing a WebAPI over my already existant MVC application, using the OAuth2 authorization system.
This API will allow my clients to request my users information. Currently, my users are stored in the Identity tables (ASPNetUsers). In my application, they are registering, logging in, etc... with the help of the Identity classes and methods.
The problem is here : I want to manage my API clients accounts, in an "Identity way", so I can authenticate them when they ask for Access Tokens. But I can't use the current users tables, as there is no common points between my clients and my users.
The perfect solution would be to have two Identity tables : one for my users, and one for my clients, but after my long-time searches, I figured it was not possible, or it would be a mess, at best.
I would not use ASP.NET Identity as a way to manage OAuth2 registered client applications. Even though some client applications (confidential) are indeed issued client credentials that's probably the only thing they share with a username/password user identity. It's a completely different thing and as such it should be managed and stored independently.
If you're thinking that this sounds like a lot of work, you're absolutely right. It isn't trivial to implement a custom username/password authentication that proves secure and implementing an OAuth2 authorization server is many times as complex.
If you really want/need to go that route then some mandatory reading:
The OAuth 2.0 Authorization Framework
OAuth 2.0 Threat Model and Security Considerations
JSON Web Token (JWT) (assuming you choose JWT as token format)
If you're still evaluating all your options I would also consider the possibility of delegating all the authentication/authorization work onto a third-party, Auth0 comes to mind, but I'm biased because I work there.
Are there any major security drawbacks to using Self-Issued Providers with OpenID Connect? (And the Implicit flow that those imply/require?)
As opposed to, say, using Dynamic Client Registration?
We're working on a project that requires decentralized cross-domain authentication, where server/client pre-registration is difficult or impossible. Which means we need to pick one of those two mechanisms, it sounds like? (Self-Issued Providers or Dynamic Client Registration). Which of those is more appropriate for what sort of situation?
Self-issued providers and Dynamic Client Registration are serving different purposes.
Self-issued providers are self-hosted or possibly in-browser OpenID Connect Providers that would not have a trust relationship with Relying Parties. They provide the equivalent of self-registration to RPs and provide "non-asserted" identity.
Dynamic Client Registration lets Clients/RPs register themselves with OpenID Connect Providers to dynamically create a trust relationship so that the Provider can provide 3rd-party asserted identity to the Client.
What is the difference between Claims based authentication vs What is provided by OAuth.
I am looking for conceptual difference and not technical difference. When do I choose Claims over OAuth and vice versa.
Claims based authentication is proposed by Microsoft and build on top of WS-Security. But OAuth is more a open source protocol that is being proposed to allow fetching resources from different portals based on a security token.
Claims also has this concept of token (SAML encoded or X509 certificates).
I am trying to understand when do I choose Claims over OAuth and vice versa.
Thanks
Claims-based identity is a way of decoupling your application code from the specifics of identity protocols (such as SAML, Kerberos, WS-Security, etc). It is not only for web applications and is implemented as a .NET library / framework called WIF.
OAuth is a specific protocol by which one web site can obtain user consent to access their private data on another web site.
It is not really the case that you would choose one or the other, in fact they are complementary. Potentially you could use both at once, if you were building a .NET web app that performed OAuth via the WIF.