One of JWT benefits is to avoid managing/storing a session at the server side. However, in JWT the server needs to know the secret to corroborate that the incoming message is valid.
My question is: doesn't the server need to store the secret somewhere to validate the JWT token coming from the browser?
Yes, it does need to store the secret. If your server back-end is also issuing the tokens, you'll already have the secret used to sign the tokens available to verify the tokens. If you have some sort of auth server issuing the tokens, you'll need a shared secret to validate them.
Related
Many of my (confidential) apps are talking to each other via the client credential flow.
They request a token from the Azure Identity platform and use this token to authenticate against another app.
A while ago I used client secrets to do so, but later I read that this is not recommended for production environments.
For this reason I changed to self-signed certificates that are valid a longer time.
Those certificates are generated by myself with Azure Keyvault.
However, also this is not recommended.
Microsoft states that that in production environments you should use certificates that are signed by an official CA.
If I now use Lets encrypt, this will expire all three months what is also not such a nice solution.
My questions:
Why is the client secret not recommended in production environments?
Why is the self-signed certificate a problem? I do understand this in matters of HTTPS, but where is the security breach if its used for client credential flow? In my case I am the owner of the app and the app registration.
Do I need to buy a certificate that is one-year valid to do it "the right way"?
Do you have any source of best practices here?
• Client secrets include application credentials, SSH keys, API keys, database passwords, encryption keys, connection strings and so on to connect various resources and access the data or functionality for achieving the designated purpose of that application. Thus, if these are breached, they can put your application at great risk of compromise. Also, the client secret generated in Azure AD and used in APIs for connecting to Azure AD for authentication and authorization purpose is listed and mentioned in unencrypted form in the API code itself. Though, we have an option to store that secret in a key vault and refer to that secret through either managed identity or RBAC assignments, but their credentials too can fall in wrong hands and let the application be vulnerable if the managed identity is a user assigned or even if then access scope of the secret is not well defined according to the required specific need. Thus, client secret is not recommended to be used in a production API.
• In client credentials flow, applications are directly granted permissions by an administrator to perform a certain action regarding the API to be called through it via certificate or federated credentials. Thus, when using a self-signed certificate in client credentials grant scenario, the administrator has granted the daemon app requesting access to other API all the required privileges regarding accessibility of code, API, permissions, data, etc. which can result in poor validation and misuse as the it is very easy to generate a certificate’s key pair without reasonable entropy. Also, protecting the private key of the key pair appropriately to its use and strong validation of the same is not promised in a self-signed certificate due to which it is not recommended in client credentials flow.
• For best practices regarding web app service deployment, please refer to the documentation link below: -
https://learn.microsoft.com/en-us/azure/app-service/security-recommendations#general
It explains the best security recommendations for deploying a web app service.
I have a query about how keycloak is supposed to be working with client without GUI access.
Basically I have:
A keycloak server configured with a realm, clients(Access type confidential) and Users
A server application with a GUI that also provide API, secure with keycloak (client, user, blablabla)
This is kind of working already as I am able to log on the GUI, have the redirect, etc..
Even accessing the APIs works well, when I have access to a GUI: I log on my UI, follow the redirect and get my UI to display the token. The the human (to differentiate the user from an application), can use the token in any API client.
In this context the user never sees the client secret, which is instinctively the right way. (note that I am very opened to people telling me my instinct is wrong!)
What I am NOT able to do so far is to find the way a server application (without GUI) can get a valid token?
The authorization_endpoint, as far as I understand it, requires both the client id and the client secret) to get a token, which I would rather avoid: I don't think giving my client secret to all my "customers" is the proper way to do it.
Alternatively I could create an API on my client that woudl ask for user credential and ask for the token in its behalf, but that would expose the clients credentials to my application, which is against the whole concept!
I tried setting my client Access type as public, but when I use the API call below I also get a error:
POST /auth/realms/realmname/protocol/openid-connect/tokenAPI
'grant_type=client_credentials'
'client_id=client_id'
'username=username'
'password=password'
{
"error": "unauthorized_client",
"error_description": "Public client not allowed to retrieve service account"
}
Would anyone know how this is supposed to be done ?
Thanks in advance.
Max
(...) A server application (without GUI) can get a valid token... typically using the Client Credentials flow.
But we would define in this case a dedicated Client for your server (client?) application to authenticate against. The returned token (not bound to a specific user) will serve for authorizations on allowed applications (i.e. your classic GUI or API clients).
So, basically you should (in very short):
define a specific confidential Client in your Keycloak
add the desired applications (or other Clients) to the Client Scope(s). Those you want to authorize transitively from this Client.
authenticate against this Client with Client Credentials flow (given the token endpoint, client id, credentials, scope)
ensure that you are authenticating through TLS and that parameters are included in request body (and not in headers - for enhanced privacy)
further harden security of your Client(s)
When you do not want anymore this particular server (client?) application to access your applications, you can change the corresponding "authentication" Client's secret/credentials or simply delete it.
"I don't think giving my client secret to all my "customers" is the proper way to do it."
You are right and the proposed method above strictly avoids that. Each customer would have its own credentials.
EDIT
(adding more details)
By performing as above, you would end up with the following scheme:
Flow Keycloak Server
C/S app. or Customer X <--- Client Creds ---> Auth. Client X
--- Access Token ---> Appl. Client <--> Appl. Server
C/S app. or Customer Y <--- Client Creds ---> Auth. Client Y
--- Access Token ---> Appl. Client <--> Appl. Server
Browser users <--- Standard ------> Appl. Client <--> Appl. Server
Note: this is not a detailed flow chart. Arrows mostly show relationships here.
Finally, please note that the terminology may differ a little here, but the proposed method is basically the same that Google uses. So you may aswell take some inpiration from there:
https://developers.google.com/identity/protocols/oauth2
I just had the same problem some weeks ago
In my case, I have a backend API and a frontend application that the users can use.
Eventually, I can't share the client_secret to the frontend application.
So here is my solution:
On keycloak, create a client (ex front_end_client) with grant type public
This client is going to be used by the frontend application to authenticate users using implicit flow (with PKCE will be more secure)
On keycloak, create a second client (On the same REALM as the first client) with grant type confidential, this client is going to be used by the backend API
Now, this is how it works:
Frontend app authenticate users and get the access token (Using the font_end_client)
The frontend app sends this token for every request to the backend
Backend app verify this token, and can retrieve permissions from it
due to the lack of INTROSPECT_ENDPOINT in azure AD, I am unable to validate the token.
How to validate the Azure Access token in Java?
Usually, the ADAL or the MSAL SDK will take care of it. But, you can still manually validate the access token you get. Here is the official tutorial: Validating tokens.
In summary, there would be 3 steps:
Get the kid in token header, and the tid in token payload.
Get all sign keys from https://login.microsoftonline.com/{tid_here}/discovery/v2.0/keys, and find the key with kid
x5c in the key is the public certificate. You can use it to verify the signature of a token.
When a request with the bearer token hits a microservice, does microservice talk to keycloak to validate the token for each request?
Is traffic "Step 5" configurable via keycloak adapter?
No, that would make too many requests. In initialization phase microservice loads public key and signing algorithm from Keycloak’s well known config page. On each request microservice checks the signature of the bearer token.
Access token lifespan should not be too long and that is how you force your frontend to periodically go to Keycloak and refresh the bearer.
If you run your microservice, every time you send a request to an api after adding the token in the logs you will see "Loaded URLs from http://localhost:8080/auth/realms/{realm-name}/.well-known/openid-configuration". Upon clicking this link you will see that there are a set of URLs present here, endpoints for token generation, userinfo etc.,there are endpoints for getting the certs and signing keys as well via which the signing key of the token is verified.
(This will only happen if keycloak properties are defined in application.properties/application.yml)
Step 5 will happen on using Keycloak adapter (Choice of adapter given in keycloak documentation)
I'm implementing an Ouath2 authentication with Spring for our mobile API. So far it works but I don't know how I should keep the resource server separate. So I have an auth server which gives out tokens and refresh tokens using the password grant-type. Meaning the user would log into the mobile app, which sends the auth server the client id/client secret along with the user's
credentials, which results in an access token and a refresh token for the user with the appropriate (ROLE_USER) privileges. Another web based client is for the admins who do the same and get the ROLE_ADMIN privilege etc.
This works well so far.
Now if any client sends a request to the resource server what should happen? Should the resource server check the token's validity? If so in what way? Or should the auth server copy the token into the resource-server's database?
If you #EnableResourceServer you get a filter that checks access tokens. It needs to share a TokenStore with the auth server. That's about it to get something working.