Skip to content

Commit

Permalink
Fix CI
Browse files Browse the repository at this point in the history
  • Loading branch information
ch4mpy committed Oct 30, 2024
1 parent 9395a6b commit c94b39a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 126 deletions.
4 changes: 0 additions & 4 deletions samples/tutorials/resource-server_with_ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<!-- tools -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.c4soft.springaddons.tutorials.ui;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
Expand All @@ -10,10 +9,8 @@
public class RestClientsConfig {

@Bean
GreetApi greetApi(
@Qualifier("greetApiFactoryBean") HttpExchangeProxyFactoryBean<GreetApi> greetApiFactoryBean,
RestClient greetClient) throws Exception {
return greetApiFactoryBean.setClient(greetClient).getObject();
HttpExchangeProxyFactoryBean<GreetApi> greetApi(RestClient greetClient) throws Exception {
return new HttpExchangeProxyFactoryBean<>(GreetApi.class, greetClient);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.StreamSupport;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
Expand All @@ -23,11 +22,9 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.util.UriComponentsBuilder;

import com.c4_soft.springaddons.security.oidc.starter.LogoutRequestUriBuilder;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.client.MultiTenantOAuth2PrincipalSupport;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
Expand All @@ -41,111 +38,115 @@
@RequiredArgsConstructor
@Slf4j
public class UiController {
private final GreetApi api;
private final InMemoryClientRegistrationRepository clientRegistrationRepository;
private final OAuth2AuthorizedClientRepository authorizedClientRepo;
private final SpringAddonsOidcProperties addonsClientProps;
private final LogoutRequestUriBuilder logoutRequestUriBuilder;
private final GreetApi greetApi;
private final InMemoryClientRegistrationRepository clientRegistrationRepository;
private final OAuth2AuthorizedClientRepository authorizedClientRepo;
private final SpringAddonsOidcProperties addonsClientProps;
private final LogoutRequestUriBuilder logoutRequestUriBuilder;

@GetMapping("/")
public String getIndex(Model model, Authentication auth) {
model.addAttribute("isAuthenticated", auth != null && auth.isAuthenticated());
return "index";
}
@GetMapping("/")
public String getIndex(Model model, Authentication auth) {
model.addAttribute("isAuthenticated", auth != null && auth.isAuthenticated());
return "index";
}

@GetMapping("/greet")
@PreAuthorize("isAuthenticated()")
public String getGreeting(HttpServletRequest request, Authentication auth, Model model) throws URISyntaxException {
final var unauthorizedClients = new ArrayList<UnauthorizedClientDto>();
final var authorizedClients = new ArrayList<AuthorizedClientDto>();
StreamSupport
.stream(this.clientRegistrationRepository.spliterator(), false)
.filter(registration -> AuthorizationGrantType.AUTHORIZATION_CODE.equals(registration.getAuthorizationGrantType()))
.forEach(registration -> {
final var authorizedClient = auth == null ? null : authorizedClientRepo.loadAuthorizedClient(registration.getRegistrationId(), auth, request);
if (authorizedClient == null) {
unauthorizedClients.add(new UnauthorizedClientDto(registration.getClientName(), registration.getRegistrationId()));
} else {
SecurityContextHolder
.getContext()
.setAuthentication(
MultiTenantOAuth2PrincipalSupport.getAuthentication(request.getSession(), registration.getRegistrationId()).orElse(auth));
final var greeting = api.getGreeting();
@GetMapping("/greet")
@PreAuthorize("isAuthenticated()")
public String getGreeting(HttpServletRequest request, Authentication auth, Model model)
throws URISyntaxException {
final var unauthorizedClients = new ArrayList<UnauthorizedClientDto>();
final var authorizedClients = new ArrayList<AuthorizedClientDto>();
StreamSupport.stream(this.clientRegistrationRepository.spliterator(), false)
.filter(registration -> AuthorizationGrantType.AUTHORIZATION_CODE
.equals(registration.getAuthorizationGrantType()))
.forEach(registration -> {
final var authorizedClient = auth == null ? null
: authorizedClientRepo.loadAuthorizedClient(registration.getRegistrationId(), auth,
request);
if (authorizedClient == null) {
unauthorizedClients.add(new UnauthorizedClientDto(registration.getClientName(),
registration.getRegistrationId()));
} else {
SecurityContextHolder.getContext()
.setAuthentication(MultiTenantOAuth2PrincipalSupport
.getAuthentication(request.getSession(), registration.getRegistrationId())
.orElse(auth));
final var greeting = greetApi.getGreeting();

authorizedClients
.add(
new AuthorizedClientDto(
registration.getClientName(),
greeting,
"/ui/logout-idp?clientRegistrationId=%s".formatted(registration.getRegistrationId())));
}
});
model.addAttribute("unauthorizedClients", unauthorizedClients);
model.addAttribute("authorizedClients", authorizedClients);
return "greet";
}
authorizedClients.add(new AuthorizedClientDto(registration.getClientName(), greeting,
"/ui/logout-idp?clientRegistrationId=%s"
.formatted(registration.getRegistrationId())));
}
});
model.addAttribute("unauthorizedClients", unauthorizedClients);
model.addAttribute("authorizedClients", authorizedClients);
return "greet";
}

@PostMapping("/logout-idp")
@PreAuthorize("isAuthenticated()")
public RedirectView logout(
@RequestParam("clientRegistrationId") String clientRegistrationId,
@RequestParam(name = "redirectTo", required = false) Optional<String> redirectTo,
HttpServletRequest request,
HttpServletResponse response) {
final var postLogoutUri = UriComponentsBuilder
.fromUri(addonsClientProps.getClient().getClientUri())
.path(redirectTo.orElse("/ui/greet"))
.encode(StandardCharsets.UTF_8)
.build()
.toUriString();
final var authentication = MultiTenantOAuth2PrincipalSupport.getAuthentication(request.getSession(), clientRegistrationId).orElse(null);
final var authorizedClient = authorizedClientRepo.loadAuthorizedClient(clientRegistrationId, authentication, request);
final var idToken = authentication.getPrincipal() instanceof OidcUser oidcUser ? oidcUser.getIdToken().getTokenValue() : null;
String logoutUri = logoutRequestUriBuilder
.getLogoutRequestUri(authorizedClient.getClientRegistration(), idToken, Optional.of(URI.create(postLogoutUri)))
.orElse("");
@PostMapping("/logout-idp")
@PreAuthorize("isAuthenticated()")
public RedirectView logout(@RequestParam("clientRegistrationId") String clientRegistrationId,
@RequestParam(name = "redirectTo", required = false) Optional<String> redirectTo,
HttpServletRequest request, HttpServletResponse response) {
final var postLogoutUri = UriComponentsBuilder
.fromUri(addonsClientProps.getClient().getClientUri()).path(redirectTo.orElse("/ui/greet"))
.encode(StandardCharsets.UTF_8).build().toUriString();
final var authentication = MultiTenantOAuth2PrincipalSupport
.getAuthentication(request.getSession(), clientRegistrationId).orElse(null);
final var authorizedClient =
authorizedClientRepo.loadAuthorizedClient(clientRegistrationId, authentication, request);
final var idToken = authentication.getPrincipal() instanceof OidcUser oidcUser
? oidcUser.getIdToken().getTokenValue()
: null;
String logoutUri =
logoutRequestUriBuilder.getLogoutRequestUri(authorizedClient.getClientRegistration(),
idToken, Optional.of(URI.create(postLogoutUri))).orElse("");

log.info("Remove authorized client with ID {} for {}", clientRegistrationId, authentication.getName());
this.authorizedClientRepo.removeAuthorizedClient(clientRegistrationId, authentication, request, response);
final var authorizedClientIds = MultiTenantOAuth2PrincipalSupport.getAuthenticationsByClientRegistrationId(request.getSession());
if (authorizedClientIds.isEmpty()) {
request.getSession().invalidate();
}

log.info("Redirecting {} to {} for logout", authentication.getName(), logoutUri);
return new RedirectView(logoutUri);
log.info("Remove authorized client with ID {} for {}", clientRegistrationId,
authentication.getName());
this.authorizedClientRepo.removeAuthorizedClient(clientRegistrationId, authentication, request,
response);
final var authorizedClientIds = MultiTenantOAuth2PrincipalSupport
.getAuthenticationsByClientRegistrationId(request.getSession());
if (authorizedClientIds.isEmpty()) {
request.getSession().invalidate();
}

@PostMapping("/bulk-logout-idps")
@PreAuthorize("isAuthenticated()")
public RedirectView bulkLogout(HttpServletRequest request) {
final var authorizedClientIds = MultiTenantOAuth2PrincipalSupport.getAuthenticationsByClientRegistrationId(request.getSession()).entrySet().iterator();
if (authorizedClientIds.hasNext()) {
final var id = authorizedClientIds.next();
final var builder = UriComponentsBuilder.fromPath("/ui/logout-idp");
builder.queryParam("clientRegistrationId", id.getKey());
builder.queryParam("redirectTo", "/ui/bulk-logout-idps");
return new RedirectView(builder.encode(StandardCharsets.UTF_8).build().toUriString());
}
return new RedirectView(addonsClientProps.getClient().getPostLogoutRedirectUri().toString());
log.info("Redirecting {} to {} for logout", authentication.getName(), logoutUri);
return new RedirectView(logoutUri);
}

@PostMapping("/bulk-logout-idps")
@PreAuthorize("isAuthenticated()")
public RedirectView bulkLogout(HttpServletRequest request) {
final var authorizedClientIds = MultiTenantOAuth2PrincipalSupport
.getAuthenticationsByClientRegistrationId(request.getSession()).entrySet().iterator();
if (authorizedClientIds.hasNext()) {
final var id = authorizedClientIds.next();
final var builder = UriComponentsBuilder.fromPath("/ui/logout-idp");
builder.queryParam("clientRegistrationId", id.getKey());
builder.queryParam("redirectTo", "/ui/bulk-logout-idps");
return new RedirectView(builder.encode(StandardCharsets.UTF_8).build().toUriString());
}
return new RedirectView(addonsClientProps.getClient().getPostLogoutRedirectUri().toString());
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class AuthorizedClientDto implements Serializable {
private static final long serialVersionUID = -6623594577844506618L;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class AuthorizedClientDto implements Serializable {
private static final long serialVersionUID = -6623594577844506618L;

private String label;
private String message;
private String logoutUri;
}
private String label;
private String message;
private String logoutUri;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UnauthorizedClientDto {
private String label;
private String registrationId;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UnauthorizedClientDto {
private String label;
private String registrationId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
import com.c4_soft.springaddons.rest.SpringAddonsRestProperties.RestClientProperties;
import com.c4_soft.springaddons.rest.SpringAddonsRestProperties.RestClientProperties.AuthorizationProperties;
import com.c4_soft.springaddons.rest.SpringAddonsRestProperties.RestClientProperties.ClientType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Setter;

@ConditionalOnWebApplication(type = Type.SERVLET)
Expand Down Expand Up @@ -88,22 +89,22 @@ public void postProcessBeanDefinitionRegistry(@NonNull BeanDefinitionRegistry re
builder.getBeanDefinition());
});

restProperties.getService().entrySet().stream().forEach(e -> {
final var builder =
BeanDefinitionBuilder.genericBeanDefinition(HttpExchangeProxyFactoryBean.class);
try {
builder.addPropertyValue("httpExchangeClass",
Class.forName(e.getValue().getHttpExchangeClass()));
} catch (ClassNotFoundException e1) {
throw new RestMisconfigurationConfigurationException(
"Unknown class %s for REST service to auto-configure"
.formatted(e.getValue().getHttpExchangeClass()));
}
// FIXME:
// builder.addPropertyReference("client", e.getValue().getClientBeanName());
final var beanName = e.getValue().getBeanName().orElse(toCamelCase(e.getKey()));
registry.registerBeanDefinition(beanName + "FactoryBean", builder.getBeanDefinition());
});
// restProperties.getService().entrySet().stream().forEach(e -> {
// final var builder =
// BeanDefinitionBuilder.genericBeanDefinition(HttpExchangeProxyFactoryBean.class);
// try {
// builder.addPropertyValue("httpExchangeClass",
// Class.forName(e.getValue().getHttpExchangeClass()));
// } catch (ClassNotFoundException e1) {
// throw new RestMisconfigurationConfigurationException(
// "Unknown class %s for REST service to auto-configure"
// .formatted(e.getValue().getHttpExchangeClass()));
// }
// // FIXME:
// builder.addPropertyReference("client", e.getValue().getClientBeanName());
// final var beanName = e.getValue().getBeanName().orElse(toCamelCase(e.getKey()));
// registry.registerBeanDefinition(beanName + "FactoryBean", builder.getBeanDefinition());
// });

}

Expand Down Expand Up @@ -136,8 +137,9 @@ private static String toCamelCase(String in) {
}
}

@RequiredArgsConstructor
@Component
@NoArgsConstructor
@AllArgsConstructor
public static class HttpExchangeProxyFactoryBean<T> implements FactoryBean<T> {
private Class<T> httpExchangeClass;
private RestClient client;
Expand Down

0 comments on commit c94b39a

Please sign in to comment.