Grafana : How to use JWT authentication? - jwt

I want to use JWT for Grafana login authentication, Grafana docs dictate some steps for the same but [auth.jwt] default is not provided in sample.ini, and can you clarify what it means by header name that contains a token in the step mentioned for enabling JWT ?

This is the header providing a jwt payload from the proxy in front of grafana - in the case of IAP(https://cloud.google.com/iap/docs/signed-headers-howto) for example: x-goog-iap-jwt-assertion. The contents of this header is validated by the use of either source speficied i jwk_set_url, jwk_set_file or key_file, after which the claims for example for username and email can be fetched. Examples on IAP for this also available in the url above:
auth.jwt:
enabled: true
header_name: x-goog-iap-jwt-assertion
username_claim: sub
email_claim: email
jwk_set_url: https://www.gstatic.com/iap/verify/public_key-jwk
Note however - auth.jwt currently "broken by design" as mentioned in:
Authentication Grafana via JWT

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

Authentication Grafana via JWT

i am new to grafana and i want to use a JWT authentication as described in grafana docs : https://grafana.com/docs/grafana/latest/auth/jwt/ how can i use generally the JWK to authenticate with external Identity provider ?
specifically, which jwts endpoint i have to use, is it my main base url for my provider? and then the provided http auth header?
my grafana.ini configuration file :
[auth.jwt]
enabled = true
header_name = X-JWT-HEADER
cache_ttl = 60m
jwk_set_url = https://$AUTH-PROVIDER-URL/
username_claim = user
email_claim = email
after restarting the grafana server i see no changes for my grafana login page and i can still login only with the admin user. should this works with such configuration or I have missed something?
Note that the auth.jwt is currently broken by design:
https://github.com/grafana/grafana/issues/8198
Even if you get everything else right it requires you to have prepopulated all accounts in grafana. It should provide similar functionality to auto-sign-up provided in auth.proxy The whole argument for auth.jwt is to provide something similar to, but safer to auth.proxy:
https://cloud.google.com/iap/docs/identity-howto
#Ying.Zhao
the authentication with JWT didn't work due to missing some claim properties in the json web endpoint (JWKs url)..
alternatively you can use the "auth generic" or proxy-auth for your OAuth Login.
[auth.proxy]
enabled = true
# HTTP Header name that will contain the username or email
header_name = X_HEADER_NAME
header_property = username

Multiple authentications (Basic Auth + 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

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)

Nexus OSS Remote User Token (RUT) for SSO

Hello I am using Nexus OSS, and wanted to simulate SSO, using Remote User Token. Currently the Nexus is configured to LDAP authentication, and is working fine.
As per the instructions found here https://books.sonatype.com/nexus-book/reference/rutauth.html
Basically enabled Remote User Token and added header field Name "REMOTE_USER". This user is ldap and has access.
This instance is behind apache, so from apache, To test this RUT, I can set the header value REMOTE_USER, whoever, I don't see passed in user getting logged nor I see cookie being generated. I even tried firefox rest api client and set header, but with the same results. I can see that HTTP header is being set right.
Am I missing something?
Is there a way to debug that? Appreciate any help.
Thanks
S
RUT handles authentication, but the authenticated user still needs to be authorized to access the web UI. What this means is that you need an LDAP user or group mapping in Nexus which assigns the necessary roles and privileges to the user.
I had a similar issue with Nginx, the header was not set using the correct value.
This can be quite confusing, as the reverse proxy does not complain and simply sends a blank request header to Nexus.
Using Keycloak and Nginx (Lua), instead of a preferred_username field in the IdP response:
-- set headers with user info: this will overwrite any existing headers
-- but also scrub(!) them in case no value is provided in the token
ngx.req.set_header("X-Proxy-REMOTE-USER", res.preferred_username)
I had to use the preferred_username field returned in the response's id_token element:
-- set headers with user info: this will overwrite any existing headers
-- but also scrub(!) them in case no value is provided in the token
ngx.req.set_header("X-Proxy-REMOTE-USER", res.id_token.preferred_username)