Skip to content

Commit

Permalink
feat: multitenancy for token exchange
Browse files Browse the repository at this point in the history
  • Loading branch information
mghilardelli committed Jul 15, 2024
1 parent 555e14b commit b5e32b2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ch.sbb.playgroundbackend.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimNames;

@Configuration
public class DynamicClientRegistrationRepository implements ClientRegistrationRepository {

@Value("${auth.exchange.client-id}")
private String clientId;

@Value("${auth.exchange.client-secret}")
private String clientSecret;

@Value("${auth.exchange.scope}")
private String scope;

@Override
public ClientRegistration findByRegistrationId(String registrationId) {
String issuerUri = (String) ((Jwt) (SecurityContextHolder.getContext().getAuthentication().getPrincipal())).getClaims().get(JwtClaimNames.ISS);
return ClientRegistrations.fromIssuerLocation(issuerUri)
.authorizationGrantType(AuthorizationGrantType.JWT_BEARER)
.clientId(clientId)
.clientSecret(clientSecret)
.scope(scope)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,35 @@
import ch.sbb.playgroundbackend.model.azure.TokenIssuanceStartRequest;
import ch.sbb.playgroundbackend.model.azure.TokenIssuanceStartResponse;
import ch.sbb.playgroundbackend.model.azure.TokenIssuanceStartResponseData;
import lombok.RequiredArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("customClaim")
@RequiredArgsConstructor
public class CustomClaimController {

private static final Logger log = LoggerFactory.getLogger(CustomClaimController.class);
private final Map<String, Claims> tokenClaimDataMap = new HashMap<>();

private final OAuth2AuthorizedClientManager manager;
private final ClientRegistrationRepository clientRegistrationRepository;
public static final String SFERA_TOKEN_REGISTRATION = "sfera-token";

private final Map<String, Claims> tokenClaimDataMap = new HashMap<>();
public CustomClaimController(@Qualifier("authorizedClientManager") OAuth2AuthorizedClientManager manager) {
this.manager = manager;
}

@GetMapping("requestToken")
String tokenRequest(Authentication authentication, String ru, String train, String role) {
Expand All @@ -48,17 +43,14 @@ String tokenRequest(Authentication authentication, String ru, String train, Stri

tokenClaimDataMap.put(userId, new Claims(ru, train, role));

var clientRegistration = clientRegistrationRepository.findByRegistrationId(SFERA_TOKEN_REGISTRATION);

OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(
clientRegistration.getRegistrationId())
.principal(authentication)
.build();
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("exchange")
.principal(authentication)
.build();

OAuth2AuthorizedClient client = manager.authorize(oAuth2AuthorizeRequest);
if (client == null) {
throw new IllegalStateException(
"failed to retrieve sfera-token failed, client is null");
"failed to retrieve sfera-token failed, client is null");
}
return client.getAccessToken().getTokenValue();
}
Expand Down
15 changes: 4 additions & 11 deletions playground-backend/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ spring:
security:
oauth2:
authorizationUrl: https://login.microsoftonline.com/common/oauth2/v2.0
client:
provider:
azure-active-directory:
issuer-uri: https://login.microsoftonline.com/2cda5d11-f0ac-46b3-967d-af1b2e1bd01a/v2.0
registration:
sfera-token:
provider: azure-active-directory
client-id: ${CLIENT_ID}
client-secret: ${CLIENT_SECRET}
authorization-grant-type: urn:ietf:params:oauth:grant-type:jwt-bearer
scope: api://${SFERA_CLIENT_ID}/.default
resourceserver:
jwt:
jwk-set-uri: https://login.microsoftonline.com/2cda5d11-f0ac-46b3-967d-af1b2e1bd01a/discovery/v2.0/keys
Expand Down Expand Up @@ -78,3 +67,7 @@ auth:
- name:
issuer-uri:
jwk-set-uri:
exchange:
client-id: ${CLIENT_ID}
client-secret: ${CLIENT_SECRET}
scope: api://${SFERA_CLIENT_ID}/.default

0 comments on commit b5e32b2

Please sign in to comment.