spring-cloud / spring-cloud/spring-cloud-gateway
TokenRelay bug when using different oauth2 client registration
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
spring-cloud-starter-gateway v4.1.5
When using a different client registration for the TokenRelay filter (like TokenRelay=someClientRegistrationId and not the one used for logging in the user), the Bearer auth header is not set. I think this is because the client used for the TokenRelay does not get an authorizedClient.
Example application security config:
security:
oauth2:
client:
provider:
myAuthProvider:
issuer-uri: ${issuerUri}
user-name-attribute: name
registration:
loginClient:
provider: myAuthProvider
authorization-grant-type: authorization_code
client-id: ${clientId}
client-secret: ${clientSecret}
scope: openid,profile,email,offline_access
resourceClient:
provider: myAuthProvider
authorization-grant-type: client_credentials
client-id: ${clientId}
client-secret: ${clientSecret}
scope: /.default
cloud:
gateway:
routes:
- id: resourceServerRoute
uri: ${resouceServerUri}
predicates:
- Path=/resource/**
filters:
- TokenRelay=resourceClient
Suggested solution (inspired by https://docs.spring.io/spring-security/reference/reactive/oauth2/client/authorization-grants.html#_using_the_access_token):
In function TokenRelayGatewayFilterFactory.authorizationRequest add .attribute(ServerWebExchange.class.getName(), exchange) to the builder like so:
private Mono<OAuth2AuthorizeRequest> authorizationRequest(String defaultClientRegistrationId,
Authentication principal,
ServerWebExchange exchange) {
String clientRegistrationId = defaultClientRegistrationId;
if (clientRegistrationId == null && principal instanceof OAuth2AuthenticationToken) {
clientRegistrationId = ((OAuth2AuthenticationToken) principal).getAuthorizedClientRegistrationId();
}
return Mono.justOrEmpty(clientRegistrationId).map(OAuth2AuthorizeRequest::withClientRegistrationId)
.map(builder -> builder.principal(principal).attribute(ServerWebExchange.class.getName(), exchange).build());
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at TokenRelayGatewayFilterFactory.authorizationRequest and compare the OAuth2AuthorizeRequest builder with the Spring Security authorization-grants guidance linked in the issue. Reproduce the configuration using separate loginClient and resourceClient registrations, then verify that the resource route receives the expected Bearer authorization header.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, authentication
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100