How does one use Kafka with OpenID-Connect? - apache-kafka

I'm starting out with Kafka.
I see that I'm able to pass headers when producing messages.
Traditionally one would have a web client (single page app) where to user logs in via some remote oidc idp and receives a token. That token is then sent via Authentication: Bearer token-here header to some RESTful backend where the token is checked for validity and the payload is processed, saved to database or other and something is returned or not.
Now there's Apache Kafka. It has a REST proxy. I can pass headers to the REST proxy and produce messages, or consume them, but I'm interested in the "secure my RESTful JSON API" part.
Currently, without Kafka, I have either a oidc proxy (using keycloak, that's keycloak-gatekeeper) that does the filtering of which request makes it to the backend, or I have a oidc client that does token validation as some middleware function inside the backend. In any case invalid requests doesn't get "logged" as they would in Kafka, I assume.
Where does oidc token validation and request filtering fit in the Kafka/Confluent ecosystem?
Assume we have a SPA that talks to the Confluent REST Proxy. Some logged in user wants to post messages and some non-logged in user should not be able to.
How does Kafka and/or its tools deal with that scenario?

Kafka commonly uses SASL and other Authorization plugins to prevent access.
Certificates would be distributed amongst clients (here, that is the REST Proxy). You would need other proxies or plugins around that to prevent further access or audit the requests, as with any other web server.
HTTPS certificates would be used to secure traffic to the REST proxy, but seems you're asking about something more specific.
There is no reference to OpenID in the documentation, only LDAP RBAC, as a commercial offering

Related

Server to Server API Authentication + Authorization

I'm designing a Web API that will be consumed by external web server.
Only the external web server must be authorized to access the internal API.
The end user will be authenticated against external web server, but the username must be forwarded to Internal API when requesting data, because there is some data filtering based on the username.
What authentication mechanism should in the internal web api server?
I started with X-API-Key header, but then how should I provide username? I would like to avoid passing username in querystrings
I was thinking about basic authentication, where password would be the X-API-Key
bearer token could theoretically work as well, but bearer tokens are usually generated by authorization server, which is not an option in this case.
EDIT:
Note, that the end user does not make any API calls. It simply access a website build using some CMS and the CMS internally fetches the data and generates HTML response.

keycloak bearer-only clients: why do they exist?

I am trying to wrap my head around the concept of bearer-only clients in Keycloak.
I understand the concept of public vs confidential and the concept of service accounts and the grant_type=client_credentials stuff. But with bearer-only, I'm stuck.
Googling only reveals fragments of discussions saying:
You cannot obtain a token from keycloak with a bearer-only client.
The docs are unclear as well. All they say is:
Bearer-only access type means that the application only allows bearer token requests.
Ok, if my app only allows bearer token requests, how do I obtain this token if I cannot get it from Keycloak using client id / client secret?
And if you can't obtain a token, what can you at all? Why do these clients exist? Can somebody please provide an example of using this type of client?
Bearer-only access type meaning
Bearer-only access type means that the application only allows bearer
token requests. If this is turned on, this application cannot
participate in browser logins.
So if you select your client as bearer-only then in that case keycloak adapter will not attempt to authenticate users, but only verify bearer tokens. That why keycloak documentation also mentioned bearer-only application will not allow the login from browser.
And if you can't obtain a token, what can you at all? Why do these clients exist?
Your client can't be set as bearer-only on Keycloak Server. You can
still use bearer-only on the adapter configuration though. Keycloak
doesn't allow "bearer only" clients (when setting up your client on
the server) to obtain tokens from the server. Try to change your
client to "confidential" on the server and set bearer-only on your
adapter configuration (keycloak.json).
So if you understand above statement then if you have two microservice which are talking to each other in the case, caller will be confidential and callee will be bearer-only
And Keycloak also mentioned
Bearer only client are web service that never initiate a login .It’s typically used for securing the back-end.
So if you want to use any adapter you can use bearer-only depend on the need
EDIT-
Lets go in more details ..Let see one example i have a web-app and one rest-api for web-app i am using React/Angular/JSF any front end technology and for back-end i am using Java based rest-api OR Nodejs.
Now for above requirement i have to secure both the products(web-app,rest-api) so what will be my work of action? How will I secure both the apps through Keycloak?
So here is details explanation
I have to create two client inside a realm in keycloak
Client A will be use by web-app
Client B will be used by rest-api
So now question will be why two client?
For web-app we want to force user to login via GUI then only generate the token
For rest-api we dont want GUI based api as these api consume by web-app but still secure the access to rest-api.
Now Go to Client A and make its Access Type public client so web-app will ask to login via keycloak GUI or your login page then generate the token
So same token which generated in above step used by rest-api and according to user role and other information data will fetch. So Access Type of Client B will be bearer-only so web-app generated token is passed to rest-api and it is then used to authorize the user .
Hope it will help. Someone want to add more he/she free to add.
Short answer: you can't obtain an access token using a bearer-only client, so authentication flow configuration is irrelevant, but keycloak may still need to know such a bearer only client to manage role / or audience
More details
bearer-only clients usefully represents back-end applications, like web service, called by front application and secured by the authorization server (= keycloak)
Backend / Web service application are not called directly by user, so they can't play in the Oauth2.0 user interactive flow. Setting "bearer-only" document this fact to keycloak server, allowing administrator to configure client without otherwise mandatory values (example redirect uri…) and allowing usefull error messages if someone trying to obtain a token for such a client
However, this doesn't mean you cannot configure specific roles for this client: so it need to appear in keycloak realm.
In addition bearer-only client need to verify the received access token, especially, if this (recommenden) adapter feature "verify-token-audience" is activated, bearer-only client need to verify that the access token has been issued for it: the bearer-only client must be in the audience attribute of the access token:
see https://www.keycloak.org/docs/latest/server_admin/index.html#_audience
for audience managing by keycloak, bearer-only clients needs to be registered in keycloak realm.
In my understanding, it is used when you have some internal service.
Let's say you have ServiceA and ServiceB. A user calls ServiceA which in hand calls ServiceB. ServiceB is never called by the user directly, only by other services. ServiceA will get a token using the user's credentials. And then will use this token to call ServiceB. ServiceB will never initiate a login. It will just use the token to verify permissions.
In this case, ServiceA will be confidential and ServiceB will be bearer-only clients.
An other idea why bearer only clients exist could be that client are misused for role containers sometimes, see the following discussion on the Keycloak User mailing list https://lists.jboss.org/pipermail/keycloak-user/2016-April/005731.html
E. g. the default client "realm-management" is a bearer only client, that contains roles to manage things in a realm. There is no need to invoke a login on a client like this, so public and confidential doesn't make any sense.

Keycloak client vs user

I understand that keycloak has built-in clients and we add the users later on.
But in general, what is the difference between a client and a user in Keycloak?
According to the Keycloak documentation
User - Users are entities that are able to log into your system
Client - Clients are entities that can request Keycloak to authenticate a user. Most
often, clients are applications and services that want to use Keycloak to secure
themselves and provide a single sign-on solution. Clients can also be entities that
just want to request identity information or an access token so that they can
securely invoke other services on the network that are secured by Keycloak
In short words, not only for keycloak but for OAuth and OpenId Connect too, a client represents a resource which some users can access. The built-in clients for keycloak represent some resources for keycloak itself.
Clients and users are two completely different constructs in keycloak.
In plain English, client is an application. Example for an application could be a e.g. yelp.com or any mobile application. Client can be a simple REST API. Keycloak's built in clients are for keycloak internal use, But any user-defined application has to be registered as a client in keycloak.
Users are the one which authenticate via keycloak to gain access to these applications/clients. Users are stored in keycloak DB or any externally hosted LDAP but synced with keycloak.

Stand alone OAUTH2 server communication with resource API servers

Given that I would create an OAUTH2 authentication server.
Given that I would to have separate resource servers, exposing REST APIs.
What are the best communication practies between the authentication server and the API servers?
To explain OAUTH2 server would be a proxy authenticating the user and forwarding requests to different API servers, that are not third party, but under the hood of the OAUTH2 proxy, relying on it to know the agent (user) requesting for the given command\query.
The simplest would be that the authentication server will forward the user id (that is stored with ACL rules also on each API server) under a secure connection, and that access would be restricted to request forwarded from authetication server to resource API servers.
The auth server would in this case forward the user id, but this seems suceptible to mand in the middle attack (altought firewall on API servers would be configured to accept requests only from the authentication server).
Another problem would be compromission of the OAUTH proxy, giving automaticly grant to any request coming from it.
Are there ready solution and patterns to deal with this scenario?
Thanks!
Check the User Account and Authentication Service (UAA) from CloudFoundry. Maybe will help you. It is also available as a stand-alone OAuth2 server.
API Documentation, GitHub

Authentication system for a REST service?

I'm designing a REST service in Node, and I have a plan for authentication and authorization -- but I'm not certain whether there's an unforeseen flaw in the design.
I have a central API server exposed to the Internet. The server also hosts a manager application (which communicates via AJAX), but is authenticated separately from the API, per requirement.
My initial thoughts are to have the server authenticate the user with a login form, then send the user a token (all over HTTPS, of course) that can be sent with each request to the API server for authentication and authorization.
Are there any flaws with this methodology?