Is Basic Authorization fine in machine to machine communication compared to OAuth2 - oauth

Introduction
So in my developer team, we need two server-based applications one located in my company architecture let's call it company server (i.e. resource and authorization server in OAuth2 terminology) and the second one in customer architecture let's call it customer server (i.e client and resource owner). The customer server is loading data from the company server so my company server needs to authenticate it somehow.
My team decides to apply OAuth2 standard with authorization and resource server in a single monolith application, without even thinking of benefits. This would, of course, take more time to implement than a simple constant key stored in the header. So I wonder what are benefits of that solution.
I know that Basic Authentication needs user:password base64-encoded in every request but the customer server is a single user so token would be in fact constant key stored in the header and I will use that terminology in terms of simplicity.
Argument - Microservices
In M2M (machine-to-machine) communication according to this article, customer server should obtain the token by providing client_id and client_secret from authorization server then you can use with multiple resource servers. The first argument I see is that OAuth2 pattern allows us to use multiple resource servers without additionally reimplementing authorization in each of them (because token is JWT or resource server is checking token against authorization) but in our case we have only one monolithic company server that is responsible for being resource and authorization so I see no benefits of that.
Argument - Man-in-the-middle protection
The other argument of using OAuth2 is protection against man-in-the-middle attack if someone intercepts token. The authorization server can invalidate token (directly in storage or in case of signed JWT by short expiry time) and prevent using compromised token. But...
Connection between servers is SSL secured
There's no way to steal token from storage like in a web-based or mobile-based application because key is located on the server-side itself.
Summary
So I can't think of any security benefits using OAuth2 compared to using the constant key in every request in this situation.

Security is mostly a chicken-egg problem. You encrypt secrets with encryption key and then again you think how do we handle the encryption key in a secured way. Don't assume here that TLS/SSL is infallible. But the core objective has always been to reduce the attack surface and make it more difficult for malicious users to break the system.
Even when there is no "Man in the Middle", when you send the password with every request, both the receiving side and the sending side keep the password in memory. It leaves more opportunity for an attacker to get hold of the password. A simple memory dump can expose the password.
In case of tokens, you don't always need the private key in memory to verify the token signature. You can cache the valid tokens at the server end and simply do a string match. Or you can use a public private key pair.
So, it's okay not to use OAuth2, if the security requirements are not stringent enough to justify the development effort required for a more secured solution. But it is better to use proven best practices and solutions.

Related

How does WebAuthn allow dependent web API's to access public key for decrypting credential without having to send the key?

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. 😬

spring oauth2: resource server without authorization server

I need some lights about convenience of using an autheorizarion server in my project scope.
We're realising and deploying our services into customer environment.
Customer infrastructure already provides an authentication mechanism in order to authenticate users.
This mechanism intercepts all comunications and redirects user to a "login" form.
After that, user is redirected to our service and we've to handle and digest it and respond with an JWT token.
Here is where I'm feeling lost:
I'm thinking about:
using spring-oauth2 in order to request a JWT token to an authorization server, or
using spring-oauth2 in order to auto-generate an JWT token and validate it. I don't know if it's possible.
My question is, since user is already authenticated, have it sense to use an oauth2 authorization server, using client-credentials in order to authentication client against our resource services?
Short question would be, could I use spring-oauth2 librearies in order to generate a JWT without an authorization server?
You technically can do it, but I would discourage you from doing that. Access tokens in a system should be issued centrally, by a dedicated service. Otherwise, it will be hard to maintain the infrastructure. If your services will start to issue JWTs, then they will also have to provide the public keys for others to validate these JWTs. Keys management, access token contents management, and any rules of mapping user information into claims - will now become part of your service and it will unnecessarily complicate its implementation.
If the customer's authentication mechanism issues a JWT, why not use that one for request authorization? If that one is insufficient, I would recommend having an Authorization Server (or a dedicated service), that can perform Token Exchange and exchange the original JWT for a new one.

How can I restrict access to my rest API?

I'm developing my very first mobile application and I need advice. I created REST API in spring boot and it works great but I want to restrict access. It should be used only by my app. There is no user login it only gets data from the server.
Would be some API token enough or is there any other way how can I do this?
maybe it's a stupid question but I really need advice.
thanks
You can use these pointers -
Least Privilege:
An entity should only have the required set of permissions to perform the actions for which they are authorized, and no more. Permissions can be added as needed and should be revoked when no longer in use.
Fail-Safe Defaults:
A user’s default access level to any resource in the system should be “denied” unless they’ve been granted a “permit” explicitly.
Economy of Mechanism:
The design should be as simple as possible. All the component interfaces and the interactions between them should be simple enough to understand.
Complete Mediation:
A system should validate access rights to all its resources to ensure that they’re allowed and should not rely on the cached permission matrix. If the access level to a given resource is being revoked, but that isn’t reflected in the permission matrix, it would violate the security.
Open Design:
This principle highlights the importance of building a system in an open manner—with no secret, confidential algorithms.
Separation of Privilege:
Granting permissions to an entity should not be purely based on a single condition, a combination of conditions based on the type of resource is a better idea.
Least Common Mechanism:
It concerns the risk of sharing state among different components. If one can corrupt the shared state, it can then corrupt all the other components that depend on it.
Psychological Acceptability:
It states that security mechanisms should not make the resource more difficult to access than if the security mechanisms were not present. In short, security should not make worse the user experience.
Always Use HTTPS (This is hard)
By always using SSL, the authentication credentials can be simplified to a randomly generated access token that is delivered in the username field of HTTP Basic Auth. It’s relatively simple to use, and you get a lot of security features for free.
If you use HTTP 2, to improve performance – you can even send multiple requests over a single connection, that way you avoid the complete TCP and SSL handshake overhead on later requests.
Use Password Hash
Passwords must always be hashed to protect the system (or minimize the damage) even if it is compromised in some hacking attempts. There are many such hashing algorithms which can prove really effective for password security e.g. PBKDF2, bcrypt and scrypt algorithms.
Never expose information on URLs
Usernames, passwords, session tokens, and API keys should not appear in the URL, as this can be captured in web server logs, which makes them easily exploitable.
https://api.domain.com/user-management/users/{id}/someAction?apiKey=abcd123456789 //Very BAD !!
The above URL exposes the API key. So, never use this form of security.
Consider OAuth
Though basic auth is good enough for most of the APIs and if implemented correctly, it’s secure as well – yet you may want to consider OAuth as well. The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
Consider Adding Timestamp in Request
Along with other request parameters, you may add a request timestamp as an HTTP custom header in API requests. The server will compare the current timestamp to the request timestamp and only accepts the request if it is within a reasonable timeframe (1-2 minutes, perhaps).
This will prevent very basic replay attacks from people who are trying to brute force your system without changing this timestamp.
Input Parameter Validation
Validate request parameters on the very first step, before it reaches to application logic. Put strong validation checks and reject the request immediately if validation fails. In API response, send relevant error messages and examples of correct input format to improve user experience.
You can use this as a checklist while making a rest API

Is it OK for an OAuth client to determine the access_token server side and then pass the token to the browser?

I can find plenty of example of single page apps (which can't manage a client secret) and plenty of examples of old-school server-side apps (which can manage a client secret) using OAuth.
But for us and, I suspect, the majority of enterprisey systems, a system is both server-based and client-based.
We can easily (and securely) identify the client server-side, and we could then make the resulting (user) access_token available browser-side.
The question is, does doing this introduce a risk?
The client-server (the server-side component of the client) cannot guarantee that the browser is running its code - but it can guarantee that all access to the resource owner's data on the client has been approved by the resource owner.
Thanks.
The principle itself does not introduce a risk but of course you need to take care of the method used to expose the access token to the browser. One such approach is documented here: https://hanszandbelt.wordpress.com/2017/02/24/openid-connect-for-single-page-applications/
It suggests to expose a server-side endpoint that can be called with a cookie which will then return session information that may include the access token.

Does an OAuth Consumer validate a bearer token with the OAuth provider on each request

To learn more about OAuth, I'm trying to write an OAuth 2.0 provider and also a consumer.
I'm kind of using the Doorkeeper Gem as a reference for my provider, but I'd like to write my own.
My question is about the last bullet in Section 1.3 of the spec regarding bearer tokens.
(F) The resource server validates the access token, and if valid,
serves the request.
In this scenario, does The resource server validates the access token mean that it:
checks the access token against its own locally stored copy of the access token and its expiry
makes a request to the provider server, which returns a response of valid/not valid?
does something else entirely
The specification does not answer that question, because it is an implementation detail that has no effect on the working of the protocol. Nevertheless, it is a good question that can have an impact on security.
First of all, you have to realize that in some implementations, the resource server and the authorization server are just two roles of one single entity.
As the OAuth 2.0 specification (RFC 6749) puts it:
The interaction between the authorization server and resource server
is beyond the scope of this specification. The authorization server
may be the same server as the resource server or a separate entity.
They may both be present in a single web site. Maybe they are two different web sites, but they both do have a connection to the same database. The resource server can then lookup the token in the database, just as well as the authorization server can.
If the resource server cannot read the authorization server's database, than it has to talk to the authorization server (and even if it can, it would probably be a good idea to not read the database directly).
How exactly you establish and secure that communication is up to you, but an HTTPS REST request makes a lot of sense. Many implementation have different mechanisms. For examples, see OAuth-2.0 resource servers token validation in distributed environment.
UPDATE: the standard way for a resource server to validate a token is now OAuth 2.0 Token Introspection (RFC 7662).
Obviously, when an access token is presented to a resource server for the first time, the resource server does not know about it, and has to access the authorization server to check for validity. The interesting question now is: can the resource server cache this response, or does it have to make the call on every request?
That is a design decision to be made by the resource server, and it may be influenced by many different factors. For example:
If the authorization server responds very quickly, there may be no need for the resource server to cache the response. In fact, a badly designed cache may be slower than not caching.
The need to design and implement a cache with a good cache policy may be prohibitive for implementing a good cache in the resource server.
Depending on the nature and the scale of the resource server, the cost of allocating RAM or storage on disk to a cache may be prohibitive for implementing a good cache in the resource server. This is especially true when the number of access tokens out there is very high, and a lot of storage is required to obtain a sensible cache hit ratio.
Is the resource server prepared to accept an access token, even if it has been revoked in the authorization server?
That last point deserves some further explanation. The authorization server typically has several mechanisms to revoke tokens. If a resource owner revokes an authorization through the UI, the authorization server has to invalidate all tokens obtained through that authorization (access tokens and refresh tokens). The resource server may also implement a token revoke endpoint (often used for a "log-out" mechanism in public clients that use the implicit grant).
Is the resource server prepared to take the risk of accepting a token, even after it has been revoked? And if so, for how long? If it is, then it can cache the token, otherwise it can not. At first sight, you would of course say that a resource server SHOULD NOT use cached token validation responses. But in some cases there might be performance advantages that outweigh the risk. It obviously also depends on the nature of the resources stored by the resource server, and the real risks associated with them.
Again, this is a design decision we can not make for you. From a security perspective, you should not cache validation responses in the resource server.

Resources