Access tokens and 2-legged OAuth2 - oauth

I am learning oAuth2 for the first time. I am going to use it to provide authentication for some simple web services using a two-legged approach.
According to what I have read, the flow should go like this: the web service client supplies some kind of credential to the oAuth server (I'm thinking of using JWT). If the credentials are valid, the oAuth server returns an access token. The web service client then supplies the access token when attempting to use the web service end point.
Here is my question, why not just supply the JWT when making a request to the end point? Why is oAuth's flow conceived this way. Why not just supply to JTW to the end point and use that for authentication? What is the advantage of having the extra step of getting an access token?
Thanks!

You can certainly supply the JWT directly to the web service. The questions is how do you generate it in a way that the service trusts.
A JWT is and access_token, but not all access_tokens are JWTs.
Your client can issue a JWT, sign it with a key (or a cert) and then send it to the API. The advantage of having a 3rd party (an Issuer) is that you can separate authentication from issuing tokens. Clients can authenticate in multiple ways (e.g. usr/pwd, certs, keys, whatever) and then use the JWT to call your API.
The additional abstraction gives you more flexibility and management scalability. For example: if you have 1 consumer of your API, then you are probably ok with a single credential (or JWT, or whatever). If you plan your APIs to be consumed by many clients, then handing that responsibility to a specialized component (e.g. the the issuer) makes more sense.
OAuth BTW, was designed for a specific use case: delegate access to an API to another system on your behalf. You grant access to system-A to access resources on system-B on your behalf with a permission scope.

Related

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.

OAuth2.0 without OIDC (Plain OAuth2.0)

As far as I understand, applications that we can login with our different accounts use OpenID Connect(A profile of OAuth2.0).
OAuth is for Authorization and OIDC is for authentication(It has ID Token-User Info Endpoint).
So, was it not possible to login to an application from another application account using OAuth before OIDC? (If possible, how?)
If plain OAuth can't be used for authentication, what is/was it used for?
I mean what does it do with 'authorization' exactly?
What does it get from the resource service with the access token?
I have always found the jargon around this unhelpful so I understand your confusion. Here is a plain English summary:
OAuth 2.0
Before OIDC apps used OAuth 2.0 to get tokens, and this involved optional user consent. The process of getting tokens was termed 'delegation'.
In practical terms though all real world OAuth 2.0 providers also included authentication in order for their system to be secure. How authentication was done is not defined in OAuth specifications.
OAuth is primarily about protecting data, where scopes and claims are the mechanisms. These links provide further info:
IAM Primer
Scope Best Practices
Claims Best Practices
OIDC
This just adds some clearer definition around how authentication messages before and after authentication should work:
A client simply includes an openid scope to use OpenID Connect
A client may force a login during a redirect via a prompt=login parameter
A client may request an authentication method via an acr_values parameter
The client receives an ID token (assertion) once authentication is complete, can digitally verify it if required, then use the information in it (eg a user name)
OIDC still does not define how the actual authentication works though.
Use them together
Pretty much all OAuth secured apps (and libraries) these days use both together, so that the authentication and delegation both use standards based solutions. It gives you the best application features and design patterns for doing the security well.

What is the correct grant type for browserless connections like calling a REST API from a server?

I am trying to understand OAuth2 and its grand types. I just want to know what is the propper grant type flow for authorize a browserless application (a job for example) with a REST API.
authorization_code and implicit flow require user interaction (writing the username and password in the browser), hence both are not suitable for browserless authorization.
client_credentials could work, but there is no user in the authorization process, so what happend if the REST API needs to know the user to check for permission/roles/scopes? Maybe creating a client for each user could work, but sound like a bad thing.
passwordgrant type will be deprecated in the OAuth2.1 specification, so this is not an option.
You may thing that OAuth2 is not the framework to use in this case, because you don't need authorization delegation, but what about if you have both (it is so common), a single page application where you could delegate authorization and also a REST API. What is the propper way to authorize a REST API using Oauth2?
Given that this is a background job, Client Credentials Grant is the best OAuth 2.0 related approach. And, it does not use any end user credential (End users and clients are two different entities with respect to OAuth 2.0). Hence you simply need a credential for the given client application.
Other approach is to enable API tokens. But this will require a manual step where you will insert the token to the background job. Again, this is independent from any end users.
p.s - Read about roles (i.e - client vs end-user/resource owner) - OAuth 2.0 roles

How Identity server 4 implements Json Web Tokens

I am very confused about the difference between oauth2 tokens and json web tokens.
I have searched about these technologies and the result is ;
Open Id is a protocol and It uses JSON Web tokens to ensure the requests are coming from a trusted user.
A Json web token contains a few user information ( claims ) as encrypted with a private key of sts.
Oauth2 is a framework and we can manage the login operations between our users , clients and resources and third-party applications.
Identity Framework 4 is an Open Id connect implementations .net MVC library. The library has written with oauth2 specs and it implements Open Id.
This is the point I didn't understand. The Oauth2 framework already has its token implementation.
Where is the place of JSON web tokens in this scenario?
For example, we have a simple web application and a server which implements identity server 4.
When a user requested a page from web application user will be redirected to our identity server to login operation.
After successful login Identity server adds a cookie to our response and these cookıe contains a token.
We wıll use that token when requests the other secure resources .
These steps are clear for me. Where is the Jason Web token in this schenio ?
How can I use JSON web tokens in my client app?
Where can I reach my user claims?
The reason for JWT is given in the specs of OAuth2
Since OAuth 2.0 does not define a protocol for the resource server to
learn meta-information about a token that it has received from an
authorization server, several different approaches have been
developed to bridge this gap. These include using structured token
formats such as JWT [RFC7519] or proprietary inter-service
communication mechanisms (such as shared databases and protected
enterprise service buses) that convey token information.
Being an open-standard JWT has been largely adopted in security-related technology and protocols. It defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed
Let's explain some concepts of this definition further.
Compact: Because of their smaller size, JWTs can be sent through a URL, POST parameter, or inside an HTTP header. Additionally, the smaller size means transmission is fast.
Self-contained: The payload contains all the required information about the user, avoiding the need to query the database more than once.
There are a lot of sites explaining these things as well as numerous technology providers.
https://jwt.io/introduction/ for providing tutorials and free e-book
https://oauth.net/2/ for in-depth stuff
https://openid.net/connect/ for the new kid on the block
To answer your IdentityServer related questions. Authentication & authorization related information are usually encoded
access token
identity token
The application-specific information/payload in these tokens is encoded using JWT. JWT is mostly transparent to application developers if good libraries are provided - as is the case for IdentityServer. You will find answers to your questions in the excellent documentation for IdentityServer. How to extract user claims is covered as well. The project provides numerous client examples that cover typical AuthX setups out there. It takes time and commitment to get through it.
JSON Web Token (JWT) (RFC 7519) itself is independent of OAuth 2.0 and OpenID Connect. You can use JWT wherever you like.
OAuth 2.0 is a specification as to how to request and issue access tokens. The specification does not say anything about how access tokens should be represented. Therefore, access tokens may be random strings or may be JWTs. Some authorization server implementations generate random strings and issue them as access tokens, and other implementations generate JWTs and issue them as access tokens. See “7. Access Token” in “Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings” for further discussion.
OpenID Connect is a specification as to how to request and issue ID tokens. The specification says an ID token is a kind of JWT. In addition, JWT is used in other places in the specification. Responses from UserInfo Endpoint are either plain JSON or JWT. Request Objects are JWT.
In normal cases, a server which supports OpenID Connect can issue both ID tokens (which are JWTs) and access tokens (which are either random strings or JWTs). This may be making you confused. Reading the following articles may be of help.
Diagrams of All The OpenID Connect Flows
Diagrams And Movies Of All The OAuth 2.0 Flows

Access Token/Authorization Between Microservices

I'm creating an online store REST API that will mainly be used by a mobile app. The plan is for a microservices architecture using the Spring Cloud framework and Spring Cloud OAuth for security.
My question is really on best practices for communication between microservices: Should I have each service register for their own token, or should they just pass the user's token around?
For example, I have 3 services: user-service, account-service, order-service.
I've been able to implement two procedures for creating an order: One passes the user's token around, and in the other each service gets their own token. I use Feign for both approaches.
So for option 1: order-service -> GET account-service/account/current
order-service calls the account-service which returns the account based on a userId in the token. Then the order-service creates an order for the account.
Or for option 2: order-service -> GET account-service/account/user-id/{userId}
order-service gets the userId from the sent token, calls the account-service with it's own token, then creates the order with the retrieved account.
I'm really not sure which option is best to use. One better separates information but then requires two Feign Clients. However the other doesn't require the 2 clients and it becomes easier to block off end certain endpoints to outside clients, however it requires extra endpoints to be created and almost every service to go digging into the Authentication object.
What are all your thoughts? Has anyone implemented their system in one way or another way entirely? Or perhaps I've got the completely wrong idea.
Any help is appreciated.
I have found below 3 options:
If each microservice is verifying the token then we can pass the same token. But the problem is - in between same token can be expired.
If we use client_credentials grant then there we are having two issues: one is, we need to send the username/id in next microservice. Another one is, we need to request two times - first for getting the access token, next for actual call.
If we do the token verification in API gateway only (not in microservices) then from the API gateway we need to send the username in every microservices. And microservices implementation needs to be changed to accept that param/header.
When you do server to server communication, you're not really acting on behalf of a user, but you're acting on behalf of the server itself. For that client credentials are used.
Using curl for exemple :
curl acme:acmesecret#localhost:9999/oauth/token -d grant_type=client_credentials
You should do the same with your http client and you will get the access token. use it to call other services.
You should use client tokens using the client_credentials flow for interservice communication. This flow is exposed by default on the /oauth/token endpoint in spring security oauth.
In addition to this, you could use private apis that are not exposed to the internet and are secured with a role that can only be given to oauth clients. This way, you can expose privileged apis that are maybe less restrictive and have less validation since you control the data passed to it.
In your example, you could expose an public endpoint GET account-service/account/current (no harm in getting information about yourself) and a private api GET account-service/internal/account/user-id/{userId} that could be used exclusively by oauth clients to query any existing user.

Resources