We have implemented a RESTful API using RestEasy. Now we are planning to build our own OAuth implementation and will integrate it with our Rest API.
I do not fully understand how OAuth handles authorization of every request to the API. My understanding is as follows:
User is authenticated by the OAuth server before any REST API calls are made.
Every REST API call will contain a token. The REST API server validates this token with the OAuth server. If the token is valid then the server will return a response.
This should have an impact on performance as we are validating the token for each and every API request with the second server. Is this understanding correct?
This will depend on how you will define your REST API. Basically OAUTH call has following components.
User: Who makes a request.
Provider: Who holds user information and provide apis to access them.
Consumer: Who asks the user to authorize the consumer to make request to the apis.
The basic workflow is as follows,
User tries to access restricted resource from Consumer.
Consumer asks user to share some information about him.(scope)
User selects his identity provider.
Consumer should be known to the Provider.(Usually consumer register itself as an application/website in provider's portal)
Consumer redirects to the provider with his consumer_key and scopes.
User authorize the application and grants access to some of his resource.
Provider creates a token and redirects back to consumer.
Consumer exchanges this token and its identity to get a access_token for user.
Consumer uses the access_token to make authorize request to provider and asks few information about user.
Provider sends those information to consumer.
Consumer verifies the information and user is logged into the system.
Now each token is generated against the scope and will be valid for some days. Token validation will be part of response from Provider.
In your system, you can store user data against token, so that we need not request Provider to send those information. But if you dont want to store user information certainly there will be additional calls.
Related
We have a scenario where we have different apps in the backend that needs to do some operation between them. Those apps are registered in the Okta console and have their own workflow. They both allow access to users that authenticate through an access token that they will get through a process the widget on the web. The two services needs to perform operations between them. For example, on one service we need information about products on another service. But it's not a "user" request, it's a service to service.
As far as my understanding goes, we still need to send a request as it would a normal user, so we need a bearer token to authenticate the request.
I cannot find in the docs a way to request an access token on the backend. I only found some libraries that can help providing a callback uri and multiple step process where you need to have a window to pop up to interact to insert your Okta login.
Is there any way to request an access token as an API call? In the backend services we won't have windows to pop up and authenticate?
We tried to use Okta-auth-js but seems to be more "front-end" oriented as most of the methods are "browser-only".
Yes, you need to create OIDC application of type "OAuth service", which will created "client credential" flow app for you. It supports calls to /token endpoint using client_id and client_secret available after the creation of the app in Okta. As a result of your call to /token directly from the backend, you will obtain an access token for machine-to-machine communication (no user context)
It's clear for me about users authorization in microservice architecture (API Gateway for handling auth, SSO, authorization microservice and so on).
Now i'm thinking about authorization request between microservices.
And there is one question - which options i have in case when i have not got a user?
For example - analytics service, which requests data from billing and builds complex reports. There is no user, but do i need authorize request from analytics service to billing?
I know that there can be endless tokens, but i think its not good idea.
What another options for authorization request between services?
In OAuth2 specification there is such thing called machine-to-machine token. Which is different than password credentials flow which is refering to your user authorization.
To create a machine-to-machine token you should implement a flow called client credentials flow. In this flow basically all services have a specific client id and client secret and with those you are making a call to your central oauth-server to get a token. As it is also required to configure client details in the central service you will have the authorization in between client calls in terms of which client could call which others. There is also configurations for the time to live for each token.
If you already have the OAuth2 setup on your side it might be easy to introduce this new flow. But if you don't to implement such a thing on your side with your own setup could be tricky. Please check https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2#grant-type-client-credentials
In a context with the following services:
API Gateway/OIDC client: connect to an external OpenId Connect Provider (to get access, refresh and id tokens) and act as proxy to forward requests to other services with the access token (Authorization code flow)
Several resource servers, incoming requests are handled by the API Gateway and include the access token (for validation, using the keys exposed by the OIDC provider)
I am using the Spring Security 5.2 Oauth2 client/resource server libraries.
What will be the recommended secure way to make all the resource servers services aware of the user information (included in the API Token).
I am evaluating several options:
Include the id_token in the request sent to the services. Each
service can then validate the token (in a filter).
Make the API Gateway act as a token issuer to make a new enhanced token based.
The resources servers will have to validate the token received with
a new key exposed by the API Gateway/Token issuer. With this
solution a custom AuthenticationManager has to be implemented.
I think option 2 is the more secure and future proof, is there any downsides I should consider? Also there are maybe other alternatives.
You should be able to achieve your goals without issuing a second level of token or sending id tokens to APIs. A common gateway solution is as follows:
Open Id Connect Provider (OICP) issues tokens to the client and does all the deep stuff like auditing of tokens issued + UIs for managing them
Client sends access token to resource server via API Gateway
API Gateway validates the access token, which can involve an introspection call to the OICP
API Gateway can send the access token to the user info endpoint of the OICP to get user info, then forward this to resource servers - perhaps via headers
API Gateway can be configured to cache claims (token + user info details) for subsequent calls with the same access token
Resource servers sometimes run in a locked down Virtual Private Cloud and don't need to revalidate the access token (if you are sure this is safe)
AWS API Gateway works like this when calling lambda functions. I actually like the pattern in terms of extensibility and it can also be used in standalone APIs.
My write up may give you some ideas, along with some sample authorizer code and a class that does the OAuth work.
I'm writing an API back-end that I want to use OpenID Connect (OIDC) to secure. I've been reading the documentation but I'm still a bit confused what process applies to each and every API request. The Open ID Connect code flow appears to be:
Which I'm fine with, as a one-time process. My back-end API sees an authorization code in the HTTP headers, and sends a request to the authorization server to get the id token. Assuming this validates OK, the data requested is returned in the API response.
But assuming the same user will then be making lots of requests to this API, what happens in subsequent requests? Is there some sort of session created in this mechanism? Do I continue to receive the same authorization code? Do I have to keep sending these back channel requests to the authorization server?
Or should I even output the JWT id token as a cookie? In this way I get the self contained id token coming back in future requests, with no need of a server side session, or further round trips.
I've been reading the documentation but I'm still a bit confused what
process applies to each and every API request
It is not the API that should follow OpenID connect protocol. It's the client that should do it.
My back-end API sees an authorization code in the HTTP headers, and
sends a request to the authorization server to get the id token.
Assuming this validates OK, the data requested is returned in the API
response.
Authorization code must be used by client application and not by the API endpoint. Also, authorization code must never be exposed to other entities.
You should use id token sent with OpenID Connect to authenticate the end user from your client application. To access API, you should use access tokens.
What to do in API endpoint ?
I think this is where you struggle. Your client application should send a valid access token to get access to API endpoint. From API endpoint, you can use OAuth 2.0 introspection endpoint to validate the tokens.
RFC7662 - OAuth 2.0 Token Introspection
This specification defines a protocol that allows authorized
protected resources to query the authorization server to determine
the set of metadata for a given token that was presented to them by
an OAuth 2.0 client.
Note that, OpenID Connect is built on top of OAuth 2.0. This means you can use anything defined in OAuth 2.0, including introspection endpoint. Use this endpoint to verify the access token validity.
What if you want end user details ?
OpenID Connect defines a user info endpoint
User info endpoint
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. These Claims are normally represented by a JSON object that contains a collection of name and value pairs for the Claims.
Here also, you use access tokens to get user information from this endpoint. The response will let you know the end user to which this token was issued.
Depending on your specific API requirement, you can do a token introspection or obtain user information from user info endpoint. Once that is done you may go ahead and authenticate a session. You might use both endpoints if you need all available information.
Alternatively(instead of sessions) your API can maintain an access token cache. This will remove the need to validate tokens in each an every API call. But be aware that tokens have expiration time. You must consider about token expiration if you are choosing this solution.
p.s - Client vs Resource server
In OpenID Connect and OAuth 2.0 terms, a client could be a simple web page, desktop application or could be even server hosted application.
client
An application making protected resource requests on behalf of the
resource owner and with its authorization. The term "client" does
not imply any particular implementation characteristics (e.g.,
whether the application executes on a server, a desktop, or other
devices).
Obtaining tokens and using them is the duty of the client application.
On the other hand, resource server contains protected resources,
resource server
The server hosting the protected resources, capable of accepting
and responding to protected resource requests using access tokens.
Resource server exchange it's resources to access tokens. If we match the same scenario to basic authentication, access tokens replaces username/password sent with authentication headers.
Typically you'd secure a (pure) API with OAuth 2.0, not OpenID Connect. The Client accessing your API should obtain an OAuth 2.0 access token and in order to do that it may choose to use OpenID Connect to obtain that token. That is all independent of the API, which will only see the access token. The API (or Resource Server in OAuth 2.0 terminology) is not depicted in your diagram.
How API Gateway and Micro services works.
Could anyone explain the basic flow of Micro service architecture with Gateway. I couldn't find the proper answer.
Say we have auth server and customer micro service running on separate instances and in front of all the services we have an API gateway.
My question is.
when user try to log in using username and password, the API gateway call auth server and return the access token to user.
Then user trying to access the specific url (/customers - customer micro service) that is running on separate instance.
what API Gateway do ?
validate the token with auth server and get the user id and pass the request to customer service with the user id ?
OR
validate the token and pass the request to customer microservice with the access token ? and customer microservice responsible is to the check the user id (Make an HTTP call to auth server) ?
I think that the most common approach is to use API gateway also as a security gateway, which means that API gateway is responsible for SSL termination and token validation. If token validation is successfully you can put user ID or user API key as a header and forward the request to microservice. Moreover you may also decide to perform not only authentication but also authorisation on the API gateway (usually with help of API management solutions).
Regarding your option #2 - I see no point in validating token 2 times. Best practise is to perform security validations on the edge, because in case of failed validation you use less resources (reject earlier)
To Answer your question , it is close to option #2 that you have mentioned . The API gateway will generally check the validity of the authentication token and then pass over the request to your micro-service . However you need to decide at design time if your micro-service will also do another level of verification of the token.
Please do note that the API gateway will not be enforcing Authorization , the authorization is something that your micro-service will have to enforce.