How to use service name instead of External IP/domain name for "security.oauth2.resource.tokenInfoUri" - spring-boot

I am using Spring cloud with OAuth2. I have 4 applications as mentioned below:
1) Eureka server : Service Registery.
2) zuul as Api Gateway
3) Auth server - which is returning the access_token to client after successful authentication.
4) Resource server - wants to validate token before giving access to resource.
I used the below configuration in application.properties:
security.oauth2.resource.tokenInfoUri=http://localhost:9600/oauth/check_token
security.oauth2.client.client-id=resourceServer-client
security.oauth2.client.client-secret=secret
I dont want to give hard coded ipaddress / hostname for "tokenInfoUri" in application.properties.
I want to access the auth server by its service name as there can be multiple instances of Auth server.
How can i do that ?
I checked the code how tokenInfoUri works in spring boot using oauth2 and found that
ResourceServerTokenServicesConfiguration -> RemoteTokenServicesConfiguration -> remoteTokenServices()
method where tokenInfoUri us retrieved from ResourceServerProperties.java as #ConfigurationProperties.
I dont want to use JWT token for token verification. I want to verify using remote call from Resource Server to AuthServer.

Related

JWT Authentication From Ingress in OpenShift

So I'm migrating some Spring Boot microservices from Kubernetes to OpenShift. Below is the simplified situation:
Service 1: Spring Boot application that handles, exposes 2 endpoints (login and authenticate). The authenticate service accepts the Authorization header containing a JWT token and validates that token. It returns 400 if the token doesn't exist and 403 is the user isn't authorized or the token is invalid and 200 if everything is valid.
Service 2: Spring Boot for some business service, exposes many endpoints and contains the annotation below in the Kubernetes Ingress so that all traffic is routed to the Service 1 for authentication before actually reaching Service 2
nginx.ingress.kubernetes.io/auth-url: "http://service1/authenticate?url=$request_uri&method=$request_method"
The problem is that when I migrated to OpenShift, all applications are working fine but the annotation that should route traffic to Service 1 doesn't seem to be working, since the authenticate service is never called.
I have searched the OpenShift documentation for days with no success, so any help would be much appreciated.
Probably this could help https://docs.openshift.com/container-platform/4.5/serverless/networking/serverless-ossm-jwt.html, Openshift ServiceMesh include Istio. Here is how to configure Istio JWT https://istio.io/latest/docs/tasks/security/authorization/authz-jwt/. So there you could configure the Service 1 authenticate.

Spring cloud oauth 2 with ingress kubernetes

Is it possible to use spring cloud oauth 2 server with kubernetes api gateway ingress.
I have used it with zuul to authenticate user before making a call. Can I do similar with ingress?
Edit 1:
To explain it more clearly, what I am trying to achieve
I am using token based oAuth2 implementation given by the spring cloud.
oauth is running as one of the service behind the zuul.
zuul has routes mapped for the oauth server and resource server
client call the auth server via zuul and gets the token.
client call resource server via zuul with token passed
zuul is configured to validate the token before making a call to resource server.
In this way we can stop any downstream traffic to go without a valid token.
can we do token validation in ingress with auth server running with in a cluster?
I have not used Spring Cloud OAuth 2 but as OAuth is a standard I believe you can set it up if you are using Nginx Ingress as the ingress controller, you can specify and external Oauth Provider (As OAuth generally has the same flow) like this on your ingress:
...
metadata:
name: application
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
...
You can find more information here with an example of using GitHub as an OAuth provider
There are currently three different nginx-ingress-controllers (see here), which differ in functionality. I believe that none of these ingress controllers themselves can perform an oauth token introspection. However, requests can be routed to the authorization server's introspection interface using the auth_request module.
Specifically for your case, you can use the auth-url annotation (see) in the ingress controller to direct the requests to the introspection interface of the spring cloud oauth2 server (see). The introspection interface is available under /oaut/check_token by default when #EnableAuthorizationServer is used. If the introspection interface returns a 2XX, the ingress will forward the request. This functionality is based on the auth_request module, which expects a 2xx response code from the external service if the access is allowed and 401 or 403 if denied.
If you use JWTs and want to validate the request by only checking the signature, this can in some cases actually be done by the ingress itself. To my knowledge, only the nginx plus ingress controller (paid) can validate JWTs. But there is also the nginx-based kong-ingress controller, which you can equip with pulgins (see here). There is e.g. promoted with oauth2 integration and JWT validation.
Did you find out more than me?

How does the authorization rules are validated by keycloak authorization server using spring rest adapter

I have set up the keycloak server and created the spring rest application with keycloak rest adapters. The Authorizations rules are working fine.
I would like to know about the internal working of the keycloak spring boot rest adapter. How the logged in user's token is validated against policy and permission set in keycloak admin client.
You are correct, access token does not contain all these details.
In Keycloak when you are using server side adapters the client will be configured to use the standard flow and not the implicit flow of OIDC.
In standard flow when you login using keycloak IDP your front-end redirects to Keycloak IDP and asks for you credentials. If you have the right credentials login is successful and you are redirected back to your app. In this redirect your app gets a code which it then sends to the back-end rest call. This code is used by spring adapter in the spring boot app to make a call to Keycloak IDP server and it is this call in which the boot application will get the user context to take all the authorization decisions as a response from the Keycloak server.
Hope this makes sense.

Keycloak two Frontend Clients and one Backend Client

i've got following setup:
Frontends are Angular1 Frontends. Backend is Spring Boot in use with the Keycloak Sring Boot Adapter in Combination of Spring Security.
The process is the standard OAUTH2:
Frontend sends credentials to Keycloak
If valid Keycloak sends Token to Frontend
Frontend sends requests with this token to backend
Backend sends token to keycloak for validation
keycloak accepts token after validation
backend is responding to frontend
This is working fine with one Frontend. You have to config the Keycloak Adapter of the Spring Backend via "keycloak.auth-server-url" in application.properties. My keycloak.auth-server-url of the Keycloak Adapter is pointing to an WebServer which is delivering the Frontend1 and is configured as reverse proxy. So it is forwarding in step 3 to the keycloak server with this config:
keycloak.auth-server-url=www.UrlOfFrontend1.com/auth
'/auth' is the forwarding path to keycloak. It is working fine for one frontend.
My problem is step 4 with two frontends. Every Frontend is delivered by a own WebServer which is configured as reverse proxy. If i deliver a second frontend with a second reverse proxy which delivers Frontend2 keycloak is throwing the error:
[org.keycloak.adapters.BearerTokenRequestAuthenticator] (default
task-39) Failed to verify token:
org.keycloak.common.VerificationException: Invalid token issuer.
Expected 'http://www.UrlOfFrontend1.com/auth/realms/myrealm', but was 'http://www.UrlOfFrontend2.com/auth/realms/myrealm'
at org.keycloak.TokenVerifier.verify(TokenVerifier.java:156)
at org.keycloak.RSATokenVerifier.verify(RSATokenVerifier.java:89)
I need the Spring Boot Keycloak Adapter configuration for both frontends. I have got two public Frontend Clients in Keycloak configured. What am I missing?

Getting HTTP 401 with Spring Boot custom authorization server when accessing spring client

Hi everyone i am not able to proceed with following settings. your small pointers are appreciated.
problem statement
i am trying to use custom authorization server provided by spring cloud security and OAuth2 with my web application so that it can propagate access token to micro services in back end.
i can able to see my authorization server can able to provide access token and when try to ingest access token for invoking endpoints for for back end micro service it work as per expectation
problem faced
when i provide following configuration in spring boot web client(which will call my back end micro service)
in application.properties
security.oauth2.client.clientId=myclient
security.oauth2.client.clientSecret=abcsecret
security.oauth2.client.access-token-uri=http://localhost:9000/services/oauth/token
security.oauth2.client.user-authorization-uri=http://localhost:9000/services/oauth/authorize
security.oauth2.client.clientAuthenticationScheme=form
security.oauth2.resource.user-info-uri=http://localhost:9000/services/user
security.oauth2.resource.prefer-token-info=true
and i provide
http://localhost:8080
in my browser. it asks for credentials. i provide credentials as present with authorization server.
once valid credentials provided authorization server asks for valid scopes.
but one important thing i observe when my web client routed to authorization server it has redirect_uri
http://localhost:8080/login
(not ok since initially i entered http://localhost:8080)
i am also getting HTTP 401 error

Resources