Multiple authentications (Basic Auth + Keycloak) - keycloak

I have 2 different rest endpoints in my Quarkus project:
/api/ws/...
/api/web/...
according to my understanding, it is so with Keycloak that I get a bearer token before and with this token I can access the endpoints.
But how do I do that if I want to secure the "ws" endpoint only with basic auth (Username + Password)?
So that I have then also the user in the SecurityIdentity (Principal) contained ?
the current "application.properties" looks like this:
# AUTH
quarkus.http.auth.basic=true
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.auth.permission.web.paths=/*
quarkus.http.auth.permission.web.policy=authenticated
quarkus.oidc.tenant-id=RealmResolver
quarkus.oidc.enabled=true
quarkus.oidc.auth-server-url=${keycloak.url}/auth/realms/${keycloak.realm}
quarkus.oidc.client-id=${keycloak.client_id}
quarkus.oidc.token-path=${keycloak.url}/auth/realms/${keycloak.realm}/protocol/openid-connect/token
quarkus.oidc.token.refresh-expired=true
quarkus.oidc.application-type=WEB_APP
## WS
quarkus.http.auth.ws.basic=true
quarkus.oidc.ws.auth-server-url=${keycloak.url}/auth/realms/${keycloak.realm}
quarkus.oidc.ws.client-id=${keycloak.client_id}
quarkus.oidc.ws.application-type=hybrid
quarkus.http.auth.permission.ws.paths=/api/ws/*
quarkus.http.auth.permission.ws.policy=authenticated

Quarkus can support several authentication mechanisms at the same time - but at the moment it can not apply only one mechanism for a specific request path. Please watch https://github.com/quarkusio/quarkus/issues/11886
thanks

Related

kubeconfig - oidc based authentication

Below is my kubeconfig file for accessing kubernetes clusters:
kind: ClientConfig
apiVersion: authentication.gke.io/v2alpha1
spec:
name: dev-corp
server: https://10.x.x.x:443
certificateAuthorityData: ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
authentication:
- name: oidc
oidc:
clientID: aaaaad3-9aa1-33c8-dd0-ddddd6b5bf5
clientSecret: ccccccccccccccccc-
issuerURI: https://login.microsoftonline.com/aaaa92-aab7-bbfa-cccf-ddaaaaaaaa/v2.0
kubectlRedirectURI: http://localhost:12345/callback
cloudConsoleRedirectURI: http://console.cloud.google.com/kubernetes/oidc
scopes: offline_access,profile
userClaim: upn
userPrefix: '-'
groupsClaim: groups
preferredAuthentication: oidc
There are different OAuth grant types.
My understanding is, above OAuth grant type is client credential grant type, that requires client_id, client_secret, token URL(issuerURI), scope
What is the significance of fields kubectlRedirectURI, cloudConsoleRedirectURI, userClaim, userPrefix?
How OIDC different from OAuth2?
oauth2.Config does not store userClaim & userPrefix, groupsClaim information
, as shown here.... https://github.com/golang/oauth2/blob/master/oauth2.go#L41
How to store kind:ClientConfig with oidc based authentication into cache? for example api.Config can be stored with an API from client-go to write api.Config as shown here.
KUBECTL_REDIRECT_URL: the redirect URL that kubectl oidc login uses for authorization. This is typically of the format http://localhost:PORT/callback, where PORT is any port above 1024 that will be available on developer workstations, for example http://localhost:10000/callback. You must register the URL with your OIDC provider as an authorized redirect URL for the client application.
USER_PREFIX: prefix prepended to user claims to prevent conflicts with existing names. By default, an issuer prefix is appended to the userID given to the Kubernetes API server (unless the user claim is email). The resulting user identifier is ISSUER_URI#USER. We recommend using a prefix, but you can disable the prefix by setting USER_PREFIX to -.
userClaim: the user identifier in the token under the claim name configured in spec.authentication.oidc.userClaim in the client configuration file.
cloudConsoleRedirectURI the name tell the story, the cloud redirect URL for OIDC, for example in case of google https://console.cloud.google.com/kubernetes/oidc
OIDC vs OAuth2
What's the difference between OpenID and OAuth?
The file in the question from OIDC and you are comparing the value with Oauth, both handling at different way, better to update the question again with Oauth config file.
api-server-authentication
you can check kubeconfig builder
kubernetes-engine-oidc
How to store kind:ClientConfig with oidc based authentication into cache?
you can write to a file and then read, or somewhere in the cloud storage as well

K8S Dashboard login with url

I'm running an eks cluster, installed k8s dashboard etc. All works fine, I can login in the UI in
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
Is there a way for me to pass the token via the url so I won't need a human to do this?
Thanks!
Based on official documentation it is impossible to put your authentication token in URL.
As of release 1.7 Dashboard supports user authentication based on:
Authorization: Bearer <token> header passed in every request to Dashboard. Supported from release 1.6. Has the highest priority. If present, login view will not be shown.
Bearer Token that can be used on Dashboard login view.
Username/password that can be used on Dashboard login view.
Kubeconfig file that can be used on Dashboard login view.
As you can see, only the first option bypasses the Dashboard login view. So, what is Bearer Authentication?
Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The name “Bearer authentication” can be understood as “give access to the bearer of this token.” The bearer token is a cryptic string, usually generated by the server in response to a login request. The client must send this token in the Authorization header when making requests to protected resources:
You can find more information about Baerer Authentication here.
The question now is how you can include the authentication header in your request. There are many ways to achieve this:
curl command - example:
curl -H "Authorization: Bearer <TOKEN_VALUE>" <https://address-your-dashboard>
Postman application - here is good answer to set up authorization header with screenshots.
reverse proxy - you can be achieve this i.e. by configuring reverse proxy in front of Dashboard. Proxy will be responsible for authentication with identity provider and will pass generated token in request header to Dashboard. Note that Kubernetes API server needs to be configured properly to accept these tokens. You can read more about it here. You should know, that this method is potentially insecure due to Man In The Middle Attack when you are using http.
You can also read very good answers to the question how to sign in kubernetes dashboard.

Keycloak REST API 401 when using custom client with service account

we want to access the Keycloak (Version 10) REST API from one of our backend services. To authenticate, we have setup the followings:
new clients within our realm
enabled service account for that client
assigned all [1] roles of “realm-management” to the services account
Accessing the API, e.g. fetching a selected user always results in a 401 response.
Steps to make the requests are:
Retrieve access_token from https://my-keycloak.com/auth/realms/my-realm/protocol/openid-connect/token using grant_type=client_credentials + Client ID + Client Secret
Fetch user from https://my-keycloak.com/auth/realms/my-realm/users/some-user-id-4711
using the Authorization: Bearer $ACCESS_TOKEN with the Token from step 1.
My Question: Is it even possible to use a custom client or do we have to stick to login via admin-cli? How would we need to configure the custom client, to grant access to the REST API.
Thanks,
Martin
[1] Simply setting all roles for the sake of testing, regardless that we only want to read data in the end.

How to get Keycloak user information via REST without admin role

I'm using keycloak as authorization server. The users send own username/password to MyWebApp and MyWebApp with grant_type: password get the token and then response token to the user. Now I want to my users be able to get their information, change their password and everything related to themselves RESTFUL. When I send a rest request to /{realm}/users/{id} to get user information, The keycloak get 403 error response. How can I get user information without admin access from keyclaok?
Note: I've seen this question, But I want to give the user edit profile too.
I think you are using Oauth with Grant type=password. If the token you mentioned is generate by Keycloak. You can request user information to Keycloak using /userinfo endpoint.
This is example of endpoint:
"http://localhost:8080/auth/realms/demo/protocol/openid-connect/userinfo"
This is how to send the parameters:
https://connect2id.com/products/server/docs/api/userinfo
GET /userinfo HTTP/1.1
Host: c2id.com
Authorization: Bearer Gp7b5hiURKpWzEXgMJP38EnYimgxlBC1PpS2zGXUqe
As far as i know in new versions of Keycloak, Account application (~/auth/realms/{realm}/account) will be implemented as REST backend so your users will be able to work with their profile data in RESTful way (check out keycloak blog).
If you can't wait too long for such feature, you could implement your own REST backend for user profile operations. It mean that you have to implement REST endpoint Service Provider, and integrate to that API your custom set of Keycloak Roles (Your also may to implement endpoint without checks for any roles, so only bearer authentication required). Check Keycloak development docs, also you could use Keycloak sources, especially org.keycloak.services.resources.admin package as implementation example.
PS. For viewing user info, consider using User Info OIDC endpoint (See Hlex answer). It also could be customized via OIDC mappers (Clients -> {client Id} -> Mappers tab)

JWT and KONG with custom authrizations

I went through this tutorial on KONG
https://getkong.org/plugins/jwt/
I have an understanding of JWT and authorization concepts. I have prototyped JWT with Spring Boot where I could put my own key value like this {"authorizations":"role_admin, role_user"}.
It is easy to do that in Spring Boot but I am not able to find information on how to do this with KONG. Anyone has any info about it?
Kong community edition can handle only the authentication process, (give or deny access to a customer).
Authorization process (what a given customer can do in your application) is handled by your application or by https://getkong.org/plugins/ee-oauth2-introspection/ oauth2 introspection plugin which is enterprise edition only
you can write your own authorization server based on X-Consumer-Username request header if user passed authentication or original token header proxied by kong
hope helps
The kong jwt plugin does not support sending custom payload parameters to the upstream api. It does however seem like you can use this plugin (I have not tested it):
https://github.com/wshirey/kong-plugin-jwt-claims-headers
Update:
If you set Kong to forward all headers you'll get the raw Authorization header with the jwt token. So you could base64 decode the jwt token and pull out the claims/payload parameters you need manually in your service.