@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final XsuaaServiceConfiguration xsuaaServiceConfiguration;
@Autowired
public SecurityConfiguration(XsuaaServiceConfiguration xsuaaServiceConfiguration) {
this.xsuaaServiceConfiguration = xsuaaServiceConfiguration;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(authz ->
authz
.requestMatchers("/hello").hasAuthority("Read"))
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(new TokenAuthenticationConverter(xsuaaServiceConfiguration));
}
}
@Component
public class SfRoleProvider implements Converter<Jwt, AbstractAuthenticationToken> {
private final SfRolesRetriever sfRolesRetriever;
@Autowired
public SfRoleProvider(SfRolesRetriever sfRolesRetriever) {
this.sfRolesRetriever = sfRolesRetriever;
}
@Override
public AbstractAuthenticationToken convert(Jwt jwt) {
return new AuthenticationToken(jwt, getSuccessFactorsAuthorities(jwt));
}
private Collection getSuccessFactorsAuthorities(Jwt jwt) {
return sfRolesRetriever.getRoles(jwt)
.stream()
.map(role -> new SimpleGrantedAuthority(role))
.collect(Collectors.toSet());
}
}
@Component
public class SfRolesRetriever {
private static final String DESTINATION_NAME = "{destination-name}";
private final DestinationServiceConfiguration destinationServiceConfiguration;
private final DestinationServiceAuthorizationHeaderRetriever destinationServiceAuthorizationHeaderRetriever;
private final HttpClient httpClient;
@Autowired
public SfRolesRetriever(DestinationServiceConfiguration destinationServiceConfiguration,
DestinationServiceAuthorizationHeaderRetriever destinationServiceAuthorizationHeaderRetriever) {
this.httpClient = HttpClient.newHttpClient();
this.destinationServiceConfiguration = destinationServiceConfiguration;
this.destinationServiceAuthorizationHeaderRetriever = destinationServiceAuthorizationHeaderRetriever;
}
public Collection getRoles(Jwt jwt) {
JSONObject destination = getDestination(jwt);
String successFactorsURL = destination.getJSONObject("destinationConfiguration").getString("URL");
String successFactorsAccessToken = destination.getJSONArray("authTokens").getJSONObject(0).getString("value");
return getRolesFromSuccessFactors(jwt, successFactorsURL, successFactorsAccessToken);
}
private JSONObject getDestination(Jwt jwt) {
String destinationServiceURL = destinationServiceConfiguration.getUri()
+ "/destination-configuration/v1/destinations/"
+ DESTINATION_NAME;
String authorizationHeader = destinationServiceAuthorizationHeaderRetriever.getAuthorizationHeader();
HttpRequest getDestinationRequest = HttpRequest.newBuilder()
.uri(URI.create(destinationServiceURL))
.header("X-user-token", jwt.getTokenValue())
.header(HttpHeaders.AUTHORIZATION, authorizationHeader)
.GET()
.build();
HttpResponse destinationServiceResponse = null;
try {
destinationServiceResponse = httpClient.send(getDestinationRequest, BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new SfRolesRetrieverException("Failed to retrieve destination", e);
}
return new JSONObject(destinationServiceResponse.body());
}
private Collection getRolesFromSuccessFactors(Jwt jwt, String successFactorsURL,
String successFactorsAccessToken) {
String username = jwt.getClaimAsString(TokenClaims.USER_NAME);
HttpRequest getRolesRequest = HttpRequest.newBuilder()
.uri(URI.create(successFactorsURL + "/odata/v2/getUserRolesByUserId?userId=" + username))
.header(HttpHeaders.AUTHORIZATION, "Bearer " + successFactorsAccessToken)
.header(HttpHeaders.ACCEPT, "application/json")
.GET()
.build();
HttpResponse successFactorsResponse = null;
try {
successFactorsResponse = httpClient.send(getRolesRequest, BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new SfRolesRetrieverException("Failed to retrieve roles from SuccessFactors", e);
}
return parseRolesFromSuccessFactorsResponse(successFactorsResponse.body());
}
private Collection parseRolesFromSuccessFactorsResponse(String successFactorsResponseJSON) {
JSONArray rolesJSONArray = new JSONObject(successFactorsResponseJSON)
.getJSONObject("d")
.getJSONArray("results");
Set roles = new HashSet<>();
for (int i = 0; i < rolesJSONArray.length(); i++) {
String roleName = rolesJSONArray.getJSONObject(i)
.getString("roleName");
roles.add(roleName);
}
return roles;
}
}
@Component
public class DestinationServiceAuthorizationHeaderRetriever {
private final DestinationServiceConfiguration destinationServiceConfiguration;
private final UaaContextFactory uaaContextFactory;
@Autowired
public DestinationServiceAuthorizationHeaderRetriever(DestinationServiceConfiguration destinationServiceConfiguration,
UaaContextFactory uaaContextFactory) {
this.destinationServiceConfiguration = destinationServiceConfiguration;
this.uaaContextFactory = uaaContextFactory;
}
public String getAuthorizationHeader() {
String clientId = destinationServiceConfiguration.getClientId();
String clientSecret = destinationServiceConfiguration.getClientSecret();
TokenRequest tokenRequest = constructTokenRequest(clientId, clientSecret);
UaaContext xsuaaContext = uaaContextFactory.authenticate(tokenRequest);
return "Bearer " + xsuaaContext.getToken().getValue();
}
private TokenRequest constructTokenRequest(String clientId, String clientSecret) {
TokenRequest tokenRequest = uaaContextFactory.tokenRequest();
tokenRequest.setGrantType(GrantType.CLIENT_CREDENTIALS);
tokenRequest.setClientId(clientId);
tokenRequest.setClientSecret(clientSecret);
return tokenRequest;
}
}
@Configuration
class XsuaaConfiguration {
@Bean
@Primary
XsuaaServiceConfiguration getXSUAAConfig() {
OAuth2ServiceConfiguration config = Environments.getCurrent().getXsuaaConfiguration();
XsuaaServiceConfiguration xsuaaServiceConfiguration = new XsuaaServiceConfiguration();
xsuaaServiceConfiguration.setClientId(config.getClientId());
xsuaaServiceConfiguration.setClientSecret(config.getClientSecret());
xsuaaServiceConfiguration.setUaaDomain(config.getProperty(ServiceConstants.XSUAA.UAA_DOMAIN));
xsuaaServiceConfiguration.setXsAppName(config.getProperty(ServiceConstants.XSUAA.APP_ID));
xsuaaServiceConfiguration.setUrl(config.getUrl().toString());
return xsuaaServiceConfiguration;
}
@Bean
UaaContextFactory getUaaContextFactory(XsuaaServiceConfiguration xsuaaServiceConfiguration)
throws URISyntaxException {
URI xsuaaURI = xsuaaServiceConfiguration.getUrl();
return UaaContextFactory.factory(xsuaaURI);
}
}
@Configuration
@EnableWebSecurity
class SecurityConfiguration {
private final SfRoleProvider sfRoleProvider;
@Autowired
SecurityConfiguration(SfRoleProvider sfRoleProvider) {
this.sfRoleProvider = sfRoleProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(authz -> authz
.requestMatchers("/hello").hasAuthority("SfCustomRole"))
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(sfRoleProvider);
return http.build();
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
12 | |
11 | |
10 | |
10 | |
8 | |
7 | |
6 | |
6 | |
6 | |
5 |