Closed HJK181 closed 3 days ago
Maybe @sjohnr could comment?
@HJK181 it seems that you are asking a question. I'm not sure whether the Spring Cloud team typically answers questions via GitHub issues, but this question is actually Spring Security related, and this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements.
Having said that, I will comment on your last paragraph to try and give you some pointers in the right direction. However, I don't intend to fully answer your questions which would be best suited for Stack Overflow.
I need a configuration possibility on the TokenRelayGatewayFilterFactory to conditionally skip the authentication flow.
The gateway and specifically the token relay filter is not what's triggering the authentication flow. You are protecting the application with Spring Security. When an anonymous user accesses the application, the login flow with the provider (keycloak) is triggered via Spring Security's ServerAuthenticationEntryPoint
which you can read about in Spring Security's reference documentation.
If the request comes from the mobile app, the flow must not be triggered, if it comes from the web app, it must be triggered.
This comes down to how you set up and design the security for this application. As it stands, you seem to have a single SecurityWebFilterChain
bean attempting to provide two different types of protection. One using sessions and OAuth2, and another using bearer tokens. Each flow has completely different characteristics and behavior. Therefore, you would want to separate them into multiple filter chains.
However, my recommendation would be to make your mobile app work like your web app and use sessions, but I'm guessing you have strongly decided against doing so for your own reasons.
See above comment.
So the only thing I can think of is to add some header to the request, which the Gateway could use to decide whether to trigger the flow or not.
There are going to be many ways to split your configuration into two filter chains so you can provide different experiences for mobile and web. One would be to have two deployments and use Spring @Profile
s to provide two different configurations. Another would be to match on the User-Agent
header or similar.
Sadly I can't configure
pathMatches
topermitAll
access to the resources of the app, as both mobile and app share the same code base.
Yet another would be to simply match on the presence of a Bearer
token in the Authorization
header. In this scenario, you would need another filter chain (ordered earliest in the chain) just for anonymous resources that should be presented without authentication for users of both mobile and web platforms.
In summary, this does not feel to me like a Spring Cloud Gateway issue and is simply a question of setting up your application to meet your requirements. Hopefully this is helpful. I think this issue should be closed as answered. If you have any further questions, please consider asking on stack overflow and update this issue with a link to the re-posted question (so that other people can find it), and I'll be happy to take a look.
Enhancement
I'm running an Expo React Native application where I use
expo-auth-session
to authenticate the mobile version of the app with an OIDC Provider - Keycloak in my case. The mobile app stores the received tokens in the secure storage on the mobile and sends theaccessToken
as part of the Authorization header on every request. Every request goes to Spring Cloud Gateway which should route the request to the appropriate backend service.However, Expo also supports accessing the application via the Web. In this case, where no secure method exists to store tokens, I don't want to call the OIDC Provider from the web application but instead rely on Spring Cloud Gateway as an Oauth2 client. The gateway should redirect the user to the OIDC Provider's login page. That's why I configured the Gateway in this way:
application.yml
SecurityConfiguration
Actual state:
When accessing the mobile app via localhost:8080, Spring Cloud Gateway redirects users to Keycloak's login page. After I successfully logged in to Keycloak, I'm present with the login screen of my mobile application, where I need to login once again - because I'm using a different client than on the Gateway - which is a bad user experience.
Expected behavior:
I need a configuration possibility on the TokenRelayGatewayFilterFactory to conditionally skip the authentication flow. If the request comes from the mobile app, the flow must not be triggered, if it comes from the web app, it must be triggered. Sadly I can't configure
pathMatches
topermitAll
access to the resources of the app, as both mobile and app share the same code base. So the only thing I can think of is to add some header to the request, which the Gateway could use to decide whether to trigger the flow or not.