I have a backend API server which was initially bearer-only mode which is accepting token from FE. Now, there's a need for the server to call another service in the same keycloak realm which grant type is usually client_credentials.
User -> FE server --(bearer only)--> BE server --(client credential)--> Other service
The question is, how to combine bearer-only and client credential in the BE server? Do I have to define 2 clients in the Keycloak realm for the same BE (one is bearer only, the other one is client credentials).
We have solved this with two separate clients in Keycloak
Client #1 (token is generated from SPA client and used for Bearer Auth)
Access Type: Public
Client #2 (for server to server)
Access Type: Confidential
Service Accounts: On
On the Service Account Roles Tab: define which roles that token will get
EDIT:
On the spring side, you just need to reference Client #2 when setting up your keycloak AdapterDeploymentContext in your security config class. That is because any token generated by Client #1 or Client #2 will be a SSO token and your spring backend will point back to the realm for token verification.
Related
There are two spring-boot apps.
client
resource-sever
there is dev okta account that is used as auth server
(those 2 apps are standard Spring Boot client -> resource-server, almost out of the box with okta setup for them, should not be problem there)
client - securely sends messages to--> secure-sever (passing the access token in the header as prove that it's authorized to call it and get data back)
(it works as expected)
But I am trying to figure out what's going on between all them, traffic wise
I'm trying to spot that moment when resource-server checks the token it got from the client that got it from the auth server.
Here is a sequence diagram of standard oauth 2.0 flow and that part that I want to debug (arrow)
auth server
And there is a communications between client, resource-sever:
There seems I can not confirm that Resource Server (from the right) does any token validation with the auth-server (okta)..?
Question: is why? From my understanding it is supposed to validate it (somehow).
I was expecting to see a call from resource-server to auth-server (otka) with the token-validation-request (ETF RFC 7662 in October 2015) like this:
How to validate an OAuth 2.0 access token for a resource server?
I was expecting, lets say, tat for every client call, resource server would check if that token the client passes is valid. Yet I do not see any calls from resource service to okta that would use the token in its requests to okta.
This comes down to the difference between JWTs and opaque tokens.
It looks like your application is using JWTs, based on the calls I'm seeing to /keys.
When using JWT authentication the resource server will query the jwks_url (in this case /keys) on startup to retrieve a set of public keys that it can use to validate the JWT-encoded bearer tokens.
Then, when the resource server receives a bearer token in a request from the client it will validate its signature against a public key obtained from the jwks_url endpoint.
This means the resource server doesn't have to query the authorization server on every request.
You can read more about this process in the OAuth 2.0 Resource Server JWT section of the Spring Security reference documentation.
The question that you linked to refers to opaque tokens.
In this setup, the resource server must call the authorization server introspection endpoint to validate the token every time.
You can read more about this process in the OAuth 2.0 Resource Server Opaque Token section of the Spring Security reference documentation.
I am working on a microservices project involving 4 services - Auth Service, Service-A, Service-B and Service-C.
All the services are implemented using Spring Boot. The Auth Service is responsible for authenticating logged in user and generating a JWT bearer token. Each of Service-A/B/C has JWT filters which checks for validity of token and then provide access to the Rest APIs.
Now I want to implement logout feature. The logout request goes to Auth Service. The Auth Service uses Redis. The token is added to list of invalid tokens with ttl set so that after the expiry the token is removed automatically.
Now how can JWT filters in Service-A/B/C access the blacklisted token so that Rest API access is approved/disapproved? If all the services are deployed in same system the services can access Redis easily. If the services are deployed in different systems, how can they access the invalid tokens?
Should I implement pub/sub messaging and each service will listen for logout event and update their blacklisted tokens
Or is there a better approach in microservices environment?
One possible solution is to implement filter at API gateway level. See below link ... https://softwareengineering.stackexchange.com/a/430024/395671
In a context with the following services:
API Gateway/OIDC client: connect to an external OpenId Connect Provider (to get access, refresh and id tokens) and act as proxy to forward requests to other services with the access token (Authorization code flow)
Several resource servers, incoming requests are handled by the API Gateway and include the access token (for validation, using the keys exposed by the OIDC provider)
I am using the Spring Security 5.2 Oauth2 client/resource server libraries.
What will be the recommended secure way to make all the resource servers services aware of the user information (included in the API Token).
I am evaluating several options:
Include the id_token in the request sent to the services. Each
service can then validate the token (in a filter).
Make the API Gateway act as a token issuer to make a new enhanced token based.
The resources servers will have to validate the token received with
a new key exposed by the API Gateway/Token issuer. With this
solution a custom AuthenticationManager has to be implemented.
I think option 2 is the more secure and future proof, is there any downsides I should consider? Also there are maybe other alternatives.
You should be able to achieve your goals without issuing a second level of token or sending id tokens to APIs. A common gateway solution is as follows:
Open Id Connect Provider (OICP) issues tokens to the client and does all the deep stuff like auditing of tokens issued + UIs for managing them
Client sends access token to resource server via API Gateway
API Gateway validates the access token, which can involve an introspection call to the OICP
API Gateway can send the access token to the user info endpoint of the OICP to get user info, then forward this to resource servers - perhaps via headers
API Gateway can be configured to cache claims (token + user info details) for subsequent calls with the same access token
Resource servers sometimes run in a locked down Virtual Private Cloud and don't need to revalidate the access token (if you are sure this is safe)
AWS API Gateway works like this when calling lambda functions. I actually like the pattern in terms of extensibility and it can also be used in standalone APIs.
My write up may give you some ideas, along with some sample authorizer code and a class that does the OAuth work.
Given separate spring-security-oauth2 authorization and resource servers:
I expected the authorization server's /oauth/check_token endpoint to accept a Bearer token from a resource server in the Authorization header but it only accepts Basic auth. Note: I'm referring to the request auth token, not the token to be checked.
I think OAuth2AuthenticationProcessingFilter is responsible for extracting and validating Authorization: Bearer ..., but based on the javadoc it appears to be used only by resource servers to validate requests from users or other clients.
Should resource servers always provide Basic auth when communicating with the authorization server? What's the best practice? If Bearer tokens are acceptable, does the authorization server need to be configured as a resource server via #EnableResourceServer in order to get this functionality?
Note from the Javadoc for CheckTokenEndpoint:
Controller which decodes access tokens for clients who are not able to do so (or where opaque token values are used).
Since the client authenticates with the authorization server with Basic auth to grant access, it makes sense for the /oauth/check_token endpoint to require Basic auth as well.
Usually, the tokens the resource server receives are self-encoding (or backed by a token store), so it doesn't need to check the token by directly communicating with the authorization server anyway. Communication between the resource server and authorization server is not necessary.
If it does need to interact with the authorization server, it might be to obtain its public key if you're using JWTs. But there would be no real use in securing this endpoint, since it's a public key for a reason. Again, this would happen when the resource server starts up, and certainly not for every token it receives.
I am doing an in-depth study of Spring OAuth, and I found some conflicting information.
Specifically, this tutorial states that the /oauth/token endpoint handles the username and password before granting a refresh token to the client app. By contrast, the Spring OAuth Developer Guide mentions the /oauth/authorize and /oauth/token endpoints, but yet does not get specific about how they work.
Does the /oauth/authorize do 100% of the username/password/nOtherFactors check and then signal the /oauth/token endpoint to send a refresh token to the client, so that the client then sends the refresh token to the /oauth/token endpoint?
Or is all of it handled by the /oauth/token endpoint?
Is the relationship between /oauth/authorize and /oauth/token different for different grant types? How?
Per the OAuth 2.0 specification the authorize and token endpoints have different purposes.
Authorization endpoint is where the resource owner (user) logs in and grants authorization to the client (ex: web application running in the browser or an app running on a mobile device). This is typically used in scenarios where the resource owner's user agent (ex: browser) is redirected to the identity server (authorization server) for authentication. The resource owner's user agent will have direct access to the access token.
Token endpoint is where the client (ex: Server side API or mobile app) calls to exchange the Authorization Code, Client Id and Client Secret for an access token. In this scenario, the user agent is provided with an Authorization code only, no direct access to the access token. The client is a trusted party with access to client Id and Client secret from the authorization server (That is why I mentioned Server side API as the client).
Please read this article that has even better explanation.