Exposing OAuth secured REST service as non secured using WSO2 ESB - security

I have an OAuth secured REST service "Oservice". The client (who wants to access OService) is not able to request a token at the service's token generator. I would like the WSO2 ESB to handle this for the client:
1) The ESB should have an API, which receives the request from the client, adds the name + password and sends this request to the token generator.
2) The ESB should receive the token and add the token to the message from the client and forwards it to the Oservice.
3) The Oservice receives message from ESB, validates the token and replies with correct content to ESB and ESB will forward the reply to the client.
I was trying to find out whether OAuth mediator does this, but wasn't successful, since documentation is rather short for the OAuth mediator.
Does anyone have an idea how to deal with this scenario?
Thanks a lot!
EDIT:
The goal is to use the ESB to expose a secured service as not secured to clients. I hope this clarifies a bit.

OAuth mediator can only be used to validate the OAuth access token which comes with the request. In your use case the back-end REST service is secured with OAuth and the request which comes via the ESB should have the access token. In this case OAuth mediator is of no use since token validation happens at the backend, not at ESB. This article explains how OAuth works. In step 2 and 3 you will anyway need human intervention to authenticate the resource owner which is not designed to be done programmatically. So your complete requirement does not seem to be valid because the final resource is accessed by the application, not the resource owner.
However I think some part of your requirement can be fulfilled. Say you have two REST APIs API1 and API2 in ESB.
Client sends a request to API1 just to trigger the API.
API1 sends a request to IDP with Client ID, scope of authorization and callback URL which is URL of API2.
IDP will redirect the client to the authentication page where he will authenticate himself. At this point clients HTTP request is fulfilled.
IDP will send the Authorization code to API2.
API2 will use the Authorization code and client secrete to get the Access token from IDP.
Once the Access token is received, API2 can access your Oservice and get the response/resource.
API2 will have to store the response somewhere like a file.
The client can make another request to say API3 to retrieve it.
Hope this helps

In your case you may use OAuth2 resource owner credentials grant type which is used when there is a high trust with the application using the resource owner credentials.
Now you may expose the IDP OAuthService (which is a SOAP service) as REST say API1 at ESB.
IDP OAuth service takes input as client id,client secret, resource owner username, resource owner password and grant type (=password) and returns access token with validity period.
Now you may call API1 to get the access token and then use that token while calling other OAuth protected APIs.
Hope it helps.

Related

How does OpenID Connect deal with service chains?

Background
Say I have an application to create shipments. A user sits down in front of that application and loads the page. They are then redirected to the IDP to login. The flow I use is the Authorization Code flow. This involves a Client ID and Client Secret. The IDP can take those values along with the User's Credentials and do the login.
After the login, the application gets an id_token that lets the application know who the user is (authentication).
The application then needs to call a service (we can call it Service 1). The application can pass the id_token to Service 1 as a JWT bearer token.
Service 1 gets the JWT and can use the signature on it (with the IDP's public key) to verify that the JWT in fact came from an IDP that it trusts.
Problem
This is all great and works just fine. But now Service 1 needs to call Service 2 to fulfill the Shipment Application's request.
This is where things get confusing for me. Service 1 has its own Client ID and Client Secret. And it can get a "Client Credentials" token. But Service 2 needs to know the user that is making the request and a Client Credentials token does not have any user information in it.
The Authorization: Bearer header only allows for one token. But I need space for two:
If I only pass the User's JWT, my JWT looks like the call came directly from the Shipment Application to service 2. (It may be that Service 2 should not even be called directly from the Shipment Application.)
But if I pass only the Client Credentials token of Service 1, then Service 2 is not going to get the user's information.
Either way Service 2 is not going to be happy.
Question
Does OpenID Connect have a way to merge two tokens? Or some other way to allow for chains of service calls to work?
NOTE: I currently am passing both. One in the Authorization: Bearer header and one in a custom header. But because this is not part of the OpenID Connect protocol, it is causing issues when working with 3rd party tools (like OpenAPI (aka Swagger)).
You can look at delegated tokens pattern to issue a new token for Service1 to Service communication.
See:
https://auth0.com/docs/tokens/delegation-tokens
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20

SPA + API + OIDC: How to authenticate an API caller when it's only providing an ACCESS token?

Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).
Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.
Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?
But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??
I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.
Short answer/suggestion
Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.
Explanation
ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.
But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.
Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!

Should my app issue it's own access tokens, when using external oauth2 provider (facebook)?

I would like to give the users a possibility to login with some external oauth2 provider (facebook) in my app. The client's part is running on mobile device in a native app.
I am not sure which of the approaches below should I prefer ?
Should the client send the user's access token by facebook with each request ? At each request backend asks facebook to validate the access token. Based on the validation's result, backend performs authorization and return corresponding result to the client.
Should the backend ask facebook to validate the access token only at user logon, then issue its own access token, return the access token back to the client and client will use this access token at making requests to the server to avoid contacting facebook at each request ?
I have read some questions about how to implement the auth with facebook and most of the devs are using B, but I haven't seen any explanation why is it good/bad to use A ?
What I see as benefits of the solutions:
backend doesn't need to care about issuing, refreshing, validating access tokens since this is done only by facebook's authorization servers.
this solution seems to be more effective, since it does not require to connect to facebook at each request.
Security tokens issued by Facebook are signed with a digital signature. The API server only needs access to the public key to validate the signature. There's no need at all to contact Facebook after the user authenticates.
A reason to issue your own tokens after the user signed in with Facebook could be to add claims to the token. But obviously having your own authorization server comes at a cost. It's up to you to weigh the pros and cons.
If you do decide to have your own authorization server, make sure not to write your own! There are open source options like Thinktecture IdentityServer.
I will vote for option B and here is my explanation,
Your API must authorise the request every time with some auth token , which cannot be external provider token, in such case anyone with an access token (eg: other developers) of other provider can access your api, basically there is no auth here.
When your sever issue access token, it's easy to validate and when needed could be revoked easily (eg: on password reset)
While authenticating , your server has fully control over issuing access token , so the validation is made only once and doesn't have to do every time while calling the API.

Is OAuth 2.0 just for authorizing applications and not users?

When I first heard of OAuth was in ASP.NET Web API applications and I've used it as means of authorizing users to access resources on a RESTful API. By the time I felt I was using it right, but right now I think I got the idea wrong and this is the subject of this question.
At the time, I used OAuth in the following way: on the API there was a token endpoint to issue tokens. I created a login page in a SPA and posted the username and password to the token endpoint with a grant type password and the token that came back I started sending with each request.
When the request had the Authorization: Bearer [token] header with a token issued with some username on the login page I understood the request was being done "with the user logged in" and so I could authorize access to resources.
Studying OAuth deeper my conclusion is that my usage of OAuth was completely mistaken.
My understanding now is that OAuth is just for authorizing applications and not users. In that case when we make a request with the Authorization: Bearer [token] header we are saying identifiying to the resource server that the client making the request has been authorized to access the resource, but we are not saying anything about the user?
In that case, with OAuth we just can say what resources client applications can access but we have no information to decide whether the user is allowed or not to the resource? Because of that my initial usage is truly wrong right?
OAuth 2.0 can be used for authorizing a client (an application) to call an API. This authorization is done via an authorization grant.
The grant is given by the resource owner in the case of authorization code, implicit and resource owner password grant through authentication of the user with the authorization server and clicking accept on a consent screen.
The first two grant flows are interactive and require an agent that understands HTTP (redirection) responses.
Most authorization servers also support the client credentials grant. In this case, there's no user involved and a pre-registered client (application) uses its own client-id and secret to authenticate with the authorization server.
Which grant flow to use depends on the type of client you use and who owns the resource the client needs to access. I describe the differences in my answer here.

Using OAuth instead of Basic authentication?

We have a web service, which currently uses Basic Auth over https to authenticate user requests. We also have a website which uses the service, and a native Windows client, which also uses the web service. I've read about OAuth, and it seems like it's always used for giving or getting access to external resources, i.e. delegation, but I'm trying to understand if it's a replacement for Basic Auth.
I'm not quite sure how all the parts fit together. Do you use Basic over https to the website to retrieve a secret and then have the javascript which is making requests to the REST services authenticate to the web service using OAuth instead of Basic?
It seems that at some point the user needs to enter their username and password into a form. I'm not sure what typically happens next. Is this even a use case for OAuth?
If you have local database accounts for the users (Resource owners) then you can replace the basic authentication with the one of OAuth flow named "Resource Owner Password Credentials" flow.
It is very simple flow where you issue HTTP post to an end point specified in your HTTP server usually named /token The content-type for this HTTP Post action is x-www-form-urlencoded, so the post body will contain something like this grant_type=password&username=Taiseer&password=SuperPass
One the request is sent to the /token end point the server will validate the user credentials against your database store, and if all is valid it should generate a token (signed string) which contains all the claims for this resource owner (user). Then your client application should present this token in the Authorization header with each call to any protected end point using bearer scheme.
This token expires after certain period and you can configure this from the AuthZ server. You can read my detailed blog post Token Based Authentication to get more details.

Resources