Chaining OpenID tokens - authentication

I'm working in microservices environment, where each service authenticates using OpenID Connect to an authentication service (local IdP), based on Users I keep locally on my Database.
Now, I want these services to be able to authenticate using Azure, Google, etc.
Can (and should) I modify my authentication service to allow redirection to another IdP, and replace or chain the token to my proprietary token for my services?
Is there a simpler way?
How can I allow users to login both using name / password OR external IdP?

I'm doing some research on the topic by myself as well and from what I've found until now, it seems that there is a urn:ietf:params:oauth:grant-type:token-exchange grant type that should allow exchanging external idp token to an internal one as described in some spec.
It should be supported as part of the openid connect /token endpoint so as long as the local idp supports it, I guess that this should be the best practice to achieve what you are looking for.
I'm currently looking into mitreid-connect idp implementation as local idp and some of my requirements is to also allow SSO with third parties while being able to issue a local token from the external user identity.
Will update as it goes...

If you manage all the SP (your microservices) it's definitely easier to implement it on your common IDP.
But if the SP are external ones (like existing services you just installed) and they already implements the public IDP you want to use, it was be a bit harder to pass through your current IDP without problem.
I'm guessing you are in the first case (you made all your SP) so I will elaborate it:
When your current IDP will authenticate user on others public IDP, it will get some information (email, name, etc.) and you can normalize those in your answer, to be sure your SP are completely agnostic of which original IDP was used. It will be better for you if the future to debug this setup. And of course to add a new public IDP...
But if you need to use some specific call to original IDP, (let says Youtube API for example) you could have a agnostic API on your common IDP which will forward to the appropriate proprietary API of original IDP, or deny the request if the IDP does not have a video system.
Or you could give original token to your SP, in a custom field or scope of your oidc token, so for example an SP dedicated to video could directly call Youtube API with the google user token.

I recently did a similar setup for my company. I would like to share the overall structure to give an idea about our solution. Hope it helps:
Our authentication server is an node express server with following properties:
Hosts static login screens to allow authentication against local database via email + password, as well as provides links to authenticate with external OAuth2 providers.
Both local and external authentication requests are forwarded to Passport.js Authentication strategies
After successful login, both local and external Passport.js strategies respond to a callback. Upon this response, a session object is created via express-session and a cookie is sent.
At this point, cookies can be used to exchange JWT's, so that authentication against stateless API's can be possible with Bearer Access Tokens.

Related

When to create backend application in keycloak

I see that in most of the keycloak tutorials it is suggested to create two client in keycloak i.e. frontend, backend. But I don't understand the need for this since I can validated the JWT token provided by frontend using public key even without creating separate client.
So my question is, is the approach of not creating the backend app the wrong approach? Also when & why should we create a backend client in keycloak.
Ref - https://medium.com/devops-dudes/secure-front-end-react-js-and-back-end-node-js-express-rest-api-with-keycloak-daf159f0a94e
I see most of the tutorial of keycloak suggest to create two client in
keycloak i.e. frontend, backend. But I don't understand the need of
this as I can validated JWT token provided by frontend using public
key even without creating separate client.
Typically, such tutorials are created to showcase the authentication and authorization capabilities of Keycloak.
The authentication part is showcased by the user authenticating via the browser (using the frontend client), whereas the authorization part is showcased by the application sending an access token to the Keycloak server where the claims on the access token (e.g., roles) can then be used to infer if the user has the permissions to perform the desire action (i.e., authorization).
So my question is, is approach of not creating backend app is not
right approach?
Depends on your specific use case. Alternatively to the approach that I have previously mentioned, one could have had a single client (i.e, the frontend client), and after the user has successfully authenticated, the application would pass the access token to the backend. The backend could then perform the authorization by directly checking, for instance, the roles in the access token, instead of relying on the Keycloak server to do so. There are pros and cons to both approaches.
Also when & why should we create backend client in keycloak.
A typical example would be if the backend would be a separated micro-service that triggers some maintenance task for example. Assuming that task is not related at all to the user authentication process, it would make more sense to then have a separate client (in this case a confidential one) that would rely on the client credentials flow which is typically used for machine-to-machine use-cases.

What is the way to set up an authentication mechanism using keycloak initial access token?

I want to develop an authentication mechanism for 3rd party applications using keycloak initial access tokens. But I want to do this only by using the access tokens that I have generated in the keycloak. For example, I will give a generated token to the user and allow him to log into the application. Is this possible? How can i do that?
Initial Access Token
First, I'm not sure it is a good idea to use "initial access token" for authorizing requests to your own resources. It might even not be allowed. As per the doc:
An initial access token can only be used to create clients
Second, don't use keycloak libs for Spring as suggested in other answer. It is very deprecated.
Last, a REST API secured with Oauth2 is a resource-server (and not a client). As so, the dependency should be spring-boot-starter-oauth2-resource-server. Spring doc is pretty extensive on the subject. You can also have a look at those tutorials for resource-server configuration (and OAuth2 definitions).
Once the resource-server (Spring REST API) is configured, clients will have to authorize their requests as normal for OAuth2: provide with an Authorization header containing a Bearer access-token (a JWT issued by Keycloak to the client with one of standard flows: client-credentials or authorization-code depending you need to authorize the client itself or a user behind it).
Edit
I might have misunderstood your need. If what you want is having new clients register themself programmatically on your Keycloak instance, then those clients will just issue a REST request to Keycloak server API with the "initial access token" in Authorization header as normal.
Once registered, those clients will be able to call you resource-servers as described in my initial answer.

API server access to third party mobile applications along with User identification

I have to design an IAM solution for a NodeJS microservice using Auth0. Objective is to allow third party mobile application users to access this microservice.
I understand OAuth and OpenID connect solution and one simple solution is third party application accesses APIs as a client using client credentials workflow.
Solution I have to design is allowing users to login and authenticate using their Enterprise IdP connected to our Auth0 Server. So that we can implement authorization and access control at user level.
At the same time customer application needs to be kept agnostic of Auth0 service.
What I mean by it is client should not be required to add any logic in their application for accommodating our Auth0 domain like we have in first party React application. user once logged in to customer application should get access to our API also by using SSO capability. I have read some documents about configuring customer IdP with our Auth0 server acting as a SAML SP. Still I could not understand hows of it and will Auth0 create an OAuth access token in this scenario.
I realise this requires an app to intermediate between customer's mobile app and our API service. Still, I am not able to understand data flow and communication between various components.
Also, I am not sure it is a common situation or requirement? If it is is there any technical term for it? This not seem like a standard B2B scenario.
have to design an IAM solution .. , I am not able to understand data flow and communication between various components ..
Before answering, the answer will points the asked specific questions, may not fit al your needs. SO is not really intended for writing tutorials or searching the documentation. Implementing an IdP (effecively a security module), one needs to do his homework and learn the details.
Maybe using an ready / out of box solution could be interesting. Using an open source IAM such as KeyCloak, WSO2IS could be a quick start. Or cloud services such as AWS Cognito, IBM AppId, Azure AD, .. could be a feasible solution too
a client using client credentials workflow .. access toked received by our API should be for user logged in
The client credentials grant is intended to authenticate only applications. That's it.
To authenticate users, other grant type is needed. For the user authentication the most common option is the authorization code or the implicit grant. The implicit grant is has its weaknesses and is being replaced by the code grant with PKCE (just search it).
End requirement is users of 3rd-party application not required to login again while 3rd-party application fetches data from our API .. Configuring their IdP (most probably Active directory) and our Auth0 servers for the same is all I need to understand
I see most common two options in use:
1. federated SSO authentication
This is the most commonly used option. The external (3rd party) IdP is configured as a "trusted" federated IdP. You often see the scenario when you have a service provider allowing to login with other IdP, often social networks (FB, Google, ...)
The login flow is as follows:
The client authorizes with the provider's (yours) IdP (let's call it IdP1).
IdP1 now acts as as Service Provider with IdP2 (IdP of the partner) and asks for the authorization (redirects the user to the IdP2).
User is authenticated and authorized with IdP2. If the user is already authenticated, the IdP2 doesn't need to ask the user's credentials again, this is how SSO works on this level
IdP2 returns to IdP1 (acting as a service provider).
IdP1 reads the user information (using the id_token, userinfo service - assuming using the OAuth2/OIDC protocol all the time there are other protocols too) and builds its own the user-level token. It may or may not create a local user (it is called user provisioning).
IdP1 returns to the client and the client can request a user-level token.
Then the client can call the API services with the token trusted by the API provider.
2. Assertion Framework for OAuth Authorization Grants
This option is built on top of the Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants, it is an optional extension of the OAuth2 protocol. I call this a token swap service
Basically the token service could validate the access or ID token of a trusted (partner) IdP and issue its own token based on the provided user information.
As you see there are a lot of information and to build a secure solution you ned to make sure that all steps are properly secured (signature, expiration, issuer, validity, audience, subject domain, .. are validated). Disclaimer - as my job we implement IAM/IDM solutions and a lot can get wrong if shortcuts are taken. So you may really consider using an out of box and proven solution.

SSO with JWT and multiple user accounts + SPA

I have two web applications app.domain1.com which is a SPA with his own API on api.domain1.com and app.domain2.com) with each have their own authentication system and user accounts
and I need to authenticate the user from app.domain1.com from app.domain2.com. The goal is to simplify switching from one app to another without requiring the user to log into each application by re-entering their password. I'm the owner of one app only so It's not possible to put them behind a reverse proxy or so.
Example :
app.domain2.com redirect to app.domain1.com/connect/{JWT} -> app.domain1.com SPA extract the JWT and send it via ajax to api.domain1.com for validation and login.
I have looking for OAuth2 and OpenID Connect for these but OAuth2 is more about delegation of resource access than authentication and OpenID Connect needs an Identity Provider which seems incompatible with my use case where each app has his own authentication mecanism and where I could not add a central authentication server.
Ideally, I'd like to adhere to a standard protocol.
I thought I could expose an endpoint GET /connect/{JWT} on each app.
The JWT could contains an email which could identify the user account, app.domain1.com and app.domain2.com could then share the secret for validating the JWT has not be tampered
and could have a short validity duration.
This endpoint validate the JWT, verify if a user match the email inside the JWT and log the user in.
I'm not sure about the security considerations with these process and if there is any other options ?
Thx for your help.
In my opinion you should go with OIDC. That protocol is designed exactly for the feature you described here. You can have one of the apps act as the IdP, and the other will be a Relying Party. It depends on which technology you use for your apps, but in some languages there are libraries which will turn your app into an IdP.
You can think of some generic protocol to make that federated login work, but you will be better off using standards. This way you won't have to wonder what are the security implications for your solution - you have security considerations for OIDC described in the spec itself.

restful api authentication confusion with oauth2

I did some investigation about restful api authentication. Most people pointed to Oauth2 for restful api authentication. I looked into some of resouces, especially this link https://developers.google.com/accounts/docs/OAuth2.
It seems to me Oauth2 is for a third party app to access users' data in google/facebook(or other data provider).
Our problem is that we own the data, we don't need to access our client's any third party data and our clients don't have to any third party data. We want to protect our api with some sort of authentication.
For our case what is the convenient technologies for our restful api authentication ? We will expose our api like this
https://ourdomain.com/api/<endpoint>
Our clients can access a website first to register https://ourdomain.com and they should be able to get clientId and clientKey from our website for accessing apis. Our clients should be able to consume through some sort of authentication
In oAuth 2.0, there are several types of grant types. A grant type is just a way to exchange some sort of credentials for an access token. Typically oAuth refers to 3rd party usage with a Authorization Code Grant. This means redirecting the user to the resource owner's website for authentication, which will return back an Authorization Code.
This clearly doesn't make sense for 1st party oAuth use, since you ARE the resource owner. oAuth 2.0 has considered this and included the Resource Owner Password Credentials Grant for this purpose. In this case, you can exchange a username and password for an access token at the first party level.
See https://www.rfc-editor.org/rfc/rfc6749#section-4.3 for more details.
If I understand correctly, what you need it similar to OAuth in a way that you do the exact same thing minus granting a 3rd party app access to a user's resources.
In OAuth, there is a central system that manages authentication and authorization by checking an app's credentials + user's credentials and dishing out authorization tokens. There are multiple endpoints that will accept these authorization tokens.
The tokens are basically encrypted strings that contain info about the user's credentials and some other info that might be needed by your app.
What you need (i believe) is a similar authentication endpoint, that the client hits with its credentials and gets a token.
So,
i) Create a registration form/console where a client can register and get his credentials. Have a look at this.
ii) Define a HTTP endpoint where the user exchanges his credentials for an access token + refresh token.
iii) The client can hit the resource endpoint with the access tokens to make authenticated calls to any of your endpoint.
iv) At the back-end you'd need a common service that verifies the tokens and extracts info from it.
PS - This is just a minimal system, there would be a lot of security considerations like what if some unauthorized app gets access to some client's access tokens.
You can find much information about CSRF attacks, noonces, timestamps and other methods of mitigating security concerns.
Just to be clear with the original question:
OAuth2 needs at least a client and a server
OP was wondering how to secure a REST API, and why everyone is talking about third party authentication providers (Google, Facebook, ...)
There are 2 different needs here:
1 - Being able to secure a personal API (ourdomain.com)
Client Server
Consumers <----> Your API
2 - Being able to consume a public API (For example getting a user's Google contact list)
Client Server
You <----> Google APIs
OP actually needs the 1st: implement an OAuth2 server in front of its own API.
There are many existing implementations for all languages/frameworks on Github
Finally, here is one nice Oauth2 technical explanation, and I'm shamelessly taking one of its schemas here:
No I'm not working at Google, I'm just taking Google as a public API supplier example.