What is the difference between the two use cases of using OpenID Connect in Keycloak? (Client vs Application) - authentication

I am very new to the concepts of SSO and Keycloak. I am trying to read the official documentation of Keycloak. In the "Supported Protocols" part (https://www.keycloak.org/docs/latest/securing_apps/index.html), the documentation talks about the two use cases of using OIDC like this:
"The first is an application that asks the Keycloak server to authenticate a user for them. After a successful login, the application will receive an identity token and an access token. The identity token contains information about the user such as username, email, and other profile information. The access token is digitally signed by the realm and contains access information (like user role mappings) that the application can use to determine what resources the user is allowed to access on the application.
The second type of use cases is that of a client that wants to gain access to remote services. In this case, the client asks Keycloak to obtain an access token it can use to invoke on other remote services on behalf of the user. Keycloak authenticates the user then asks the user for consent to grant access to the client requesting it. The client then receives the access token. This access token is digitally signed by the realm. The client can make REST invocations on remote services using this access token. The REST service extracts the access token, verifies the signature of the token, then decides based on access information within the token whether or not to process the request."
What I do not understand is this: In the first paragraph it talks about an application making a request and in the second one it talks about a client. But aren't applications counted as clients? Why the specific differentiation? And can anyone given an example of the remote services that is talked about in the second part?
Thank you.

But aren't applications counted as clients? Why the specific differentiation? And can anyone given an example of the remote services that is talked about in the second part?
Yes exactly it. The reason for the differentiation is because there could be many applications more than just this one client. And the client, that the user is authed against may want to access all those other applications' data.
For example take the google ecosystem. Does google email have access to drive, and photos, etc... While it could out the box, it doesn't. You need to explicitly allow email "offline access" to those other applications, even though they are all part of the same platform.
Keycloak understands this and provides that terminology. But it is a bit confusing because this isn't the best way to think about it. Instead a better explanation is that there is just the user and service clients. The service clients all talk to each other and ask for a user's data. While a user may want their data by going straight to one application, other applications may want that user's data too.
Assuming you want to actually allow one service to ask for user data from another service, you want to be using something that supports authorization as a service and not just authentication. There are some examples of this, such as PolicyServer and Authress.

Related

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.

Securely using JSON web tokens to programmatically authenticate a user from one system into another

My team and I have been working on a web application for our clients that uses JSON web tokens for authentication and authorization. Using Azure AD as our identity provider, we verify a user's identity and generate a signed JWT with the user's permissions in it. The JWT then gets included in the authorization header of all subsequent requests to the APIs. Pretty standard stuff as far as JWTs go.
We're now being asked to provide the capability to link directly into our system from another third-party web application without forcing the user to reauthenticate. I'm trying to figure out if there's a way to do so without creating a massive security loophole.
The way I picture this working would be to implement an endpoint for programmatic authentication in our system that accepts a cryptographically signed payload with an API key and the user's ID or email address. The third-party system would have a private key with which to sign the payload, and we'd have a public one to verify the signature. If the request is legitimate, we'd issue a token for the specified user, and they could use that to link to whatever they like.
I'm already getting yelled at by at least one person that this is a complete joke from a security standpoint because, among other things, it completely bypasses AAD authentication. I believe the third-party system in question does use AAD for authentication, but that's not really relevant either way because we're trusting them implicitly whether they've authenticated their users or not. Either way I take his point.
I'm not a security expert and I don't claim to know whether there even is a proper way to do this kind of thing, but from my vantage it doesn't really seem all that much less secure than any other mechanism of authentication and authorization using JWTs. Is that true? Are we nuts for even trying? Is there a way to do it that's more secure? What should I know about this that I demonstrably don't already?
Thanks in advance for the help. At the very least I hope this spurs some helpful conversation.
Single Sign-On (SSO) enables users to enter their credentials once to sign in and establish a session which can be reused across multiple applications without requiring to authenticate again. This provides a seamless experience to the user and reduces the repeated prompts for credentials.
Azure AD provides SSO capabilities to applications by setting a session cookie when the user authenticates the first time. The MSAL.js library allows applications to leverage this in a few ways.
MSAL relies on the session cookie to provide SSO for the user between different applications.
Read more in this documentation.

Is OAuth 2.0 redundant/unnecessary if the client is the same as the resource owner?

In section 1.1 of RFC 6749, there are four roles: resource owner, resource server, client, and authorization server.
Does OAuth become redundant or unnecessary if the client and the resource owner are the same entity?
For example, I have a closed API and a front-facing web server. (The front-facing web server would be both the client and the resource owner.) I am trying to decide whether to switch to OAuth 2 authentication instead of using the current username/password authentication method. Is there any added security for moving to OAuth 2 if the API remains closed to third-party applications? (That is, no third-parties will ever have access to the API.)
Thanks!
In the case where the Resource Owner and Client/Resource Server roles coincide OAuth 2.0 may become less relevant from a security point of view, since one of the primary objectives of OAuth not to expose primary credentials of the user to the client becomes moot. That is also the reason why the so-called Resource Owner Password Credentials grant is considered to be a legacy/deprecated flow.
However, it may still make sense to follow the OAuth 2.0 pattern for a number of reasons:
the ability to leverage a standardized protocol through stock libraries and
frameworks without relying on custom code
the fact that in your case the Resource Server is still made strictly OAuth 2.0 compliant, dealing with Clients presenting access tokens, irrespective of what the Client/Resource Owner relationship/implementation is; this would make it easier to allow for 3rd-party client access in a future scenario
the fact that you concentrate verification of user credentials on a single path between Client and Authorization Server so each of your Resource Servers don't need to be bothered by checking user credentials individually, possibly dealing with different authentication mechanisms
and perhaps most importantly, also security-wise: once the user has authenticated through the Client using his primary credentials, the Authorization Server can issue a refresh token as well as an access token; the Client can store and use the refresh token to a new access token when the old one expires; this frees the Client from storing the primary user credentials if it wants to keep accessing the API for a long period of time without requiring explicit user interaction and authentication and makes the resulting system less vulnerable for leakage/loss of user credentials since the user credentials (password) are not stored in the Clients
If you have the following issue then you should use OAuth;
Let's say you a Gmail like web mail provider. Some of your users are using a third party app which logs in into your user's account and auto replies certain emails for you. Or you are Facebook like social network web site where some of your users use a third party app which analyzes your friend networks and prints a 2D graph for you. In this case your users are giving away their usernames and passwords. How would they prevent a certain third party app accessing their account after they gave away their username and password? Simply by changing their password. Now you have another problem; other third party apps won't be able to access the user's account. Then the user have to re-give away his password to other apps he trusts. Now this is problem too because it is not user friendly. OAuth is simply a temporary password that your user gives away to a third party app developer. He can revoke it whenever he wants without changing his own password.
Other than that OAuth is unnecessary. Just use a session cookie if you are not going to have third party app developers. It is a random string stored in user side. And on the server side will have whatever you want. Just look how PHP sessions are used and stored on server side. You can define their lifespan and refresh time automatically from php.ini.

Can I use extension to pass login and password to OpenID provider?

There will be login page via OpenID controlled by an extension. Can I ask for URL and pass in the extension and then pass it OP by use of extension? If no what kind of data can be transferred to OP from RP by an extension? If yes, how scalable it is, do I have to write separate code of each OP, or will the standard help me?
Also in unlikely case of XY problem - I need some sort of data that will allow me to authenticate OpenID user offline (after at least one successful online login). So if I was the one to provide login and password text fields I would be able to use user's password hash it and use for offline auth. And yes I need to use OpenID rather that other system, because this is the requirement. Sorry, It's kind of ugly problem.
I don't think you're supposed to pass a user id/password to the OpenID provider (or at least not password). The idea behind OpenID is that the provider takes care of the login, thus the web application utilizing OpenID will have no knowledge of the login credentials. OpenID provides you with some authorization information, such as the nickname, fullname, email, etc. This information, coupled with the OpenID of the user itself, should be enough provide you with unique authentication for that user without the need to have a password.
Your application needs to allow the user to go to the OpenID provider's page, enter their credentials there, and once authenticated you will get a response from OpenID indicating whether the authentication is successful and subsequently providing you with the user's information.
Update
Like I mentioned in my comments: the OpenID standard does not define a way in which you can send a password to an OpenID provider. So you can't use the OpenID standard in the manner you're envisioning it.
Update 2.0
Let's take myOpenID for example: in order to use myOpenID as an OpenID provider you have to register your domain with OpenID. Alternately, you can enable OpenID for your website by contacting Janrian (the owners of myOpenID), but I'm going to say you're still going to have to register a website with them. In either case, you must have a landing page on your domain, or on your website, which accepts an authentication response from the OpenID provider (in this case myOpenID). So let's look at what's required:
You must spoof a web browser when you're making the web request to the myOpenID provider.
In that web request, you have fill in the form which takes in the client's password (again, you have to spoof the client doing that).
You have to have a service of some sort running on a website registered with an OpenID provider (such as myOpenID).
You will have to send a message (HTTP) to the service that you're expecting an authentication response for a specific user (and provide it with a way to call you back when the user is authenticated).
That service will take any incoming authentication response from the OpenID provider.
The service will match that authentication with the user ID that you told it to expect in step 4.
The service will send your application the authentication response (callback).
You must accept the authentication response from that service.
The hardest part will probably be step 1 and 2, but there should be plenty of tutorials online that can show you how to do this (sorry I didn't have time to look up specific ones).
In any case, that's how I would imagine you may be able to do this, but it's far from trivial and I've never seen it done before.
Part of the reason why OpenID is so popular is exactly because people don't have to share their credentials with the service provider (i.e. your app), they only share it with the OpenID provider. The other thing you should think about is whether or not users will agree to use the OpenID in the manner that you want them to use it. In other words, one of the main reasons why people use OpenID providers is so that they avoid doing exactly what you're asking them to do: give you their password!
Update 3.0
You can register your domain with myOpenID by going to the new domain registration page: https://www.myopenid.com/new_domain

Best way for a remote web app to authenticate users in my current web app?

So a bit of background, I'm working on an existing web application which has a set of users, who are able to log in via a traditional login screen with a user name and password, etc.
Recently we've managed to score a client (who have their own Intranet site), who are wanting to be able to have their users log into their Intranet site, and then have their users click a link on their Intranet which redirects to our application and logs them into it automatically.
I've had two suggestions on how to implement this so far:
Create a URL which takes 2 parameters (which are "username" and "password") and have the Intranet site pass those parameters to us (our connection is via SSL/TLS so it's all encrypted). This would work fine, but it seems a little "hacky", and also means that the logins and passwords have to be the same on both systems (and having to write some kind of web service which can update the passwords for users - which also seems a bit insecure)
Provide a token to the Intranet, so when the client clicks on a link on the Intranet, it sends the token to us, along with the user name (and no password) which means they're authenticated. Again, this sounds a bit hacky as isn't that essentially the same as providing everyone with the same password to log in?
So to summarise, I'm after the following things:
A way for the users who are already authenticated on the Intranet to log into our system without too much messing around, and without using an external system to authenticate, i.e. LDAP / Kerberos
Something which isn't too specific to this client, and can easily be implemented by other Intranets to log in
Both of your suggested options are insecure, even if you use SSL. Never pass credentials on a URL, put them in the HTTP request by using POST.
There is a standard called SAML and this can be used to solve your problem. The challenge is choosing which version to implement. I would choose SAML 2.0.
Google Apps implements a flavor of SAML 2.0 and allow you to authenticate using your intranet credentials. In the case of your application, you would be the service provider and your client would be the identity provider. As long as you implement the standard correctly you should be able to support any new client (identity provider). Here is a list of SAML implementations you might want to take a look at. If you need the client to pass over information in addition to the authentication information then SAML can facilitate this with metadata.
You will still need to implement SSL to encrypt network traffic.
I hate to answer my own question, but I hate even more a question with no answer. In the end we went with a very similar implementation of SalesForce's delegated authentication SSO implementation.
http://wiki.developerforce.com/page/How_to_Implement_Single_Sign-On_with_Force.com
Essentially the solution has a trusted site, known as the delegated authentication authority, who has a list of users who are logged into the company intranet.
When the user logs into the company intranet, and they click a link to our application, the company intranet will pass the user name and a generated token (which expires after a set amount of time) to our application.
Our application will then check if the user name is on our site, and if so, send the username / token (along with the source IP and a few other parameters) to the delegated authentication authority. If all those items match on the delegated authentication authority, it returns true and the user can log in. If it returns false the user is denied access.
We've found this system to work quite well, and even implemented a couple of extra security features like SSL, client side certificates, VPN tunnel, and even restricting the IP addresses which can access the site and the delegated authentication authority.
I know it's bad form to answer your own question but I hope this helps someone else who might be having the same problem ...