From a59d438dbb40a37549f4d8607109cf9b269e40f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awek=20Zatorski?= Date: Mon, 18 Nov 2024 16:26:53 +0100 Subject: [PATCH] authentication --- .../event/config/SecurityConfiguration.java | 157 ++++++++++++++++-- .../event/domain/CurrentUserHolder.java | 41 +++++ .../sasiedzi/event/service/EventService.java | 50 ++++-- .../sasiedzi/event/service/UserService.java | 52 ++++++ .../event/service/dto/AdminUserDTO.java | 4 + .../event/web/rest/AccountResource.java | 9 +- .../event/web/rest/LogoutResource.java | 47 +++++- .../event/web/rest/UserAccountResource.java | 7 +- 8 files changed, 327 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/sasiedzi/event/domain/CurrentUserHolder.java diff --git a/src/main/java/com/sasiedzi/event/config/SecurityConfiguration.java b/src/main/java/com/sasiedzi/event/config/SecurityConfiguration.java index 665b85d..cadc2ab 100644 --- a/src/main/java/com/sasiedzi/event/config/SecurityConfiguration.java +++ b/src/main/java/com/sasiedzi/event/config/SecurityConfiguration.java @@ -3,15 +3,25 @@ package com.sasiedzi.event.config; import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.oauth2.core.oidc.StandardClaimNames.PREFERRED_USERNAME; +import com.sasiedzi.event.domain.CurrentUserHolder; +import com.sasiedzi.event.repository.UserRepository; import com.sasiedzi.event.security.*; import com.sasiedzi.event.security.SecurityUtils; import com.sasiedzi.event.security.oauth2.AudienceValidator; import com.sasiedzi.event.security.oauth2.CustomClaimConverter; +import com.sasiedzi.event.service.EventService; +import com.sasiedzi.event.service.UserService; +import com.sasiedzi.event.service.dto.AdminUserDTO; import com.sasiedzi.event.web.filter.SpaWebFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.*; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; @@ -21,8 +31,15 @@ import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig; +import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; @@ -35,11 +52,14 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; import org.springframework.security.oauth2.jwt.*; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.RememberMeServices; +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.*; import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; import org.springframework.util.StringUtils; +import org.springframework.web.context.annotation.RequestScope; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import tech.jhipster.config.JHipsterProperties; import tech.jhipster.web.filter.CookieCsrfFilter; @@ -82,27 +102,140 @@ public class SecurityConfiguration { .authorizeHttpRequests(authz -> // prettier-ignore authz - .requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll() - .requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll() - .requestMatchers(mvc.pattern("/assets/**")).permitAll() - .requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll() - .requestMatchers(mvc.pattern("/api/authenticate")).permitAll() - .requestMatchers(mvc.pattern("/api/auth-info")).permitAll() +// .requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll() +// .requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll() +// .requestMatchers(mvc.pattern("/assets/**")).permitAll() +// .requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll() +// .requestMatchers(mvc.pattern("/api/authenticate")).permitAll() +// .requestMatchers(mvc.pattern("/api/auth-info")).permitAll() + .requestMatchers(mvc.pattern("/logout")).permitAll() .requestMatchers(mvc.pattern("/api/admin/**")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(mvc.pattern("/api/**")).authenticated() +// .requestMatchers(mvc.pattern("/api/**")).authenticated() + .requestMatchers(mvc.pattern("/**")).authenticated() .requestMatchers(mvc.pattern("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(mvc.pattern("/management/health")).permitAll() - .requestMatchers(mvc.pattern("/management/health/**")).permitAll() - .requestMatchers(mvc.pattern("/management/info")).permitAll() - .requestMatchers(mvc.pattern("/management/prometheus")).permitAll() +// .requestMatchers(mvc.pattern("/management/health")).permitAll() +// .requestMatchers(mvc.pattern("/management/health/**")).permitAll() +// .requestMatchers(mvc.pattern("/management/info")).permitAll() +// .requestMatchers(mvc.pattern("/management/prometheus")).permitAll() .requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN) ) - .oauth2Login(oauth2 -> oauth2.loginPage("/").userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService()))) + .rememberMe( + rememberMe -> rememberMe.rememberMeServices(rememberMeServices()) + // .key("remember-me-cookie-key32342") // Klucz do szyfrowania tokenu + // .tokenValiditySeconds(60 * 60 * 24 * 7) // 7 dni + ) + .oauth2Login(oauth2 -> + oauth2 + .defaultSuccessUrl("/", true) + /*.loginPage("/")*/.userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService())) + ) .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter()))) .oauth2Client(withDefaults()); return http.build(); } + @Bean + public RememberMeServices rememberMeServices() { + TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("remember-me-key", userDetailsService()); + rememberMeServices.setTokenValiditySeconds(60 * 60 * 24 * 7); + rememberMeServices.setAlwaysRemember(true); + // Ustawienie czasu ważności tokenu na 7 dni + return rememberMeServices; + } + + @Autowired + UserRepository userRepository; + + @Bean + public UserDetailsService userDetailsService() { + // Jeśli korzystasz z in-memory użytkowników lub innego źródła, skonfiguruj tutaj. + return new UserDetailsService() { + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + String login = extractUsername(username); + // String[] authorities = extractGrantedAuthorities(username); + Map attributes = extractUserAttributes(username); + Optional one = userRepository.findOneByLogin(login); + + if (one.isPresent()) { + // return new User(one.get().getLogin(), "somepassword", one.get().getAuthorities().stream().map(authority-> new SimpleGrantedAuthority(authority.getName())).collect(Collectors.toSet())); + // return new User(login, "somepassword", Arrays.stream(authorities).map(authority-> new SimpleGrantedAuthority(authority)).collect(Collectors.toSet())); + return new User(username, "somepassword", extractRoles(username)); + } else { + throw new UsernameNotFoundException("User not found"); + } + } + + private static String extractUsername(String input) { + Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + return matcher.group(1); + } + return null; + } + + private static String[] extractGrantedAuthorities(String input) { + Pattern pattern = Pattern.compile("Granted Authorities:\\s+\\[([^]]+)]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + return matcher.group(1).split(", "); + } + return new String[0]; + } + + private static Set extractRoles(String input) { + Set roles = new HashSet<>(); + Pattern pattern = Pattern.compile("https://www\\.jhipster\\.tech/roles=\\[([^]]+)]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + String rolesString = matcher.group(1); + String[] rolesArray = rolesString.split(",\\s*"); + for (String role : rolesArray) { + roles.add(new SimpleGrantedAuthority(role)); + } + } + return roles; + } + + private static Map extractUserAttributes(String input) { + Map attributes = new HashMap<>(); + Pattern pattern = Pattern.compile("User Attributes:\\s+\\[\\{([^}]+)\\}\\]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + String attributesString = matcher.group(1); + String[] attributePairs = attributesString.split(",\\s*"); + for (String pair : attributePairs) { + String[] keyValue = pair.split("="); + if (keyValue.length == 2) { + String key = keyValue[0]; + String value = keyValue[1]; + // Tutaj wartość jest zawsze String, ale można by to rozszerzyć by obsługiwało różne typy + attributes.put(key, value); + } + } + } + return attributes; + } + }; + } + + @Bean + @RequestScope + public CurrentUserHolder currentUser(UserService userService, EventService eventService) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication instanceof AbstractAuthenticationToken) { + AbstractAuthenticationToken authToken = (AbstractAuthenticationToken) authentication; + AdminUserDTO userFromAuthentication = userService.getUserFromAuthentication(authToken); + return new CurrentUserHolder( + userFromAuthentication, + eventService.getOrCreateUserAccountForLogin(userFromAuthentication.getLogin()), + authentication + ); + } + return new CurrentUserHolder(); + } + @Bean MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { return new MvcRequestMatcher.Builder(introspector); diff --git a/src/main/java/com/sasiedzi/event/domain/CurrentUserHolder.java b/src/main/java/com/sasiedzi/event/domain/CurrentUserHolder.java new file mode 100644 index 0000000..e0574dc --- /dev/null +++ b/src/main/java/com/sasiedzi/event/domain/CurrentUserHolder.java @@ -0,0 +1,41 @@ +package com.sasiedzi.event.domain; + +import com.sasiedzi.event.service.dto.AdminUserDTO; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@Component +@RequestScope +public class CurrentUserHolder { + + AdminUserDTO adminUser; + UserAccount userAccount; + + Authentication authentication; + + public CurrentUserHolder() {} + + public AdminUserDTO getAdminUser() { + return adminUser; + } + + public UserAccount getUserAccount() { + return userAccount; + } + + public Authentication getAuthentication() { + return authentication; + } + + public String getLogin() { + if (adminUser == null) return null; + return adminUser.getLogin(); + } + + public CurrentUserHolder(AdminUserDTO adminUser, UserAccount userAccount, Authentication authentication) { + this.adminUser = adminUser; + this.userAccount = userAccount; + this.authentication = authentication; + } +} diff --git a/src/main/java/com/sasiedzi/event/service/EventService.java b/src/main/java/com/sasiedzi/event/service/EventService.java index 90018c8..d3dc55b 100644 --- a/src/main/java/com/sasiedzi/event/service/EventService.java +++ b/src/main/java/com/sasiedzi/event/service/EventService.java @@ -3,6 +3,7 @@ package com.sasiedzi.event.service; import com.sasiedzi.event.domain.*; import com.sasiedzi.event.domain.enumeration.TransactionType; import com.sasiedzi.event.repository.*; +import com.sasiedzi.event.service.dto.AdminUserDTO; import com.sasiedzi.event.web.rest.AccountResource; import jakarta.validation.Valid; import java.math.BigDecimal; @@ -10,12 +11,16 @@ import java.math.RoundingMode; import java.time.LocalDate; import java.util.*; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.AuthenticatedPrincipal; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -235,20 +240,35 @@ public class EventService { return eventRepository.findById(event.getId()); } - public String getCurrentAuthenticatedUserAsDTO() { - if (SecurityContextHolder.getContext().getAuthentication() == null) { - return null; - } - if (SecurityContextHolder.getContext() == null) { - return null; - } - Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - if (principal instanceof AuthenticatedPrincipal) { - return ((AuthenticatedPrincipal) principal).getName(); - // return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal); - } else { - throw new RuntimeException("User could not be found"); + @Autowired + AdminUserDTO currentUser; + + // public String getCurrentAuthenticatedUserAsDTO() { + // if (SecurityContextHolder.getContext().getAuthentication() == null) { + // return null; + // } + // if (SecurityContextHolder.getContext() == null) { + // return null; + // } + // Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + // if (principal instanceof AuthenticatedPrincipal) { + // return extractUsername((AuthenticatedPrincipal) principal).getName(); + // // return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal); + // } else if (principal instanceof UserDetails) { + // return asdf((UserDetails) principal).getUsername(); + // // return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal); + // } else { + // throw new RuntimeException("User could not be found"); + // } + // } + + private static String extractUsername(String input) { + Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + return matcher.group(1); } + return null; } public UserAccount createNewAccountForLogin(String login) { @@ -264,9 +284,7 @@ public class EventService { } } - public UserAccount getOrCreateForCurrentUser() { - // if (true) return new UserAccount(); - String username = getCurrentAuthenticatedUserAsDTO(); + public UserAccount getOrCreateUserAccountForLogin(String username) { if (username != null) { // List userAccounts = userAccountRepository.findByUserLogin(currentAuthenticatedUserAsDTO.getLogin()); List userAccounts = userAccountRepository diff --git a/src/main/java/com/sasiedzi/event/service/UserService.java b/src/main/java/com/sasiedzi/event/service/UserService.java index e8aceb7..2482c92 100644 --- a/src/main/java/com/sasiedzi/event/service/UserService.java +++ b/src/main/java/com/sasiedzi/event/service/UserService.java @@ -8,14 +8,20 @@ import com.sasiedzi.event.repository.UserRepository; import com.sasiedzi.event.security.SecurityUtils; import com.sasiedzi.event.service.dto.AdminUserDTO; import com.sasiedzi.event.service.dto.UserDTO; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; @@ -129,6 +135,48 @@ public class UserService { return user; } + private static Map extractUserAttributes(String input) { + Map attributes = new HashMap<>(); + Pattern pattern = Pattern.compile("User Attributes:\\s+\\[\\{([^}]+)\\}\\]"); + Matcher matcher = pattern.matcher(input); + if (matcher.find()) { + String attributesString = matcher.group(1); + String[] attributePairs = attributesString.split(",\\s*"); + for (String pair : attributePairs) { + String[] keyValue = pair.split("="); + if (keyValue.length == 2) { + String key = keyValue[0]; + String value = keyValue[1]; + + // Konwersja wartości "true" i "false" na typ Boolean + if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) { + attributes.put(key, Boolean.parseBoolean(value)); + } else { + // Próba sparsowania jako Instant + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"); + Instant instant = Instant.from(formatter.parse(value)); + attributes.put(key, instant); + } catch (Exception e) { + // Jeśli nie jest datą, zostawiamy jako String + attributes.put(key, value); + } + } + } + } + } + return attributes; + } + + // private static String extractUsername(String input) { + // Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]"); + // Matcher matcher = pattern.matcher(input); + // if (matcher.find()) { + // return matcher.group(1); + // } + // return null; + // } + /** * Returns the user from an OAuth 2.0 login or resource server with JWT. * Synchronizes the user in the local repository. @@ -143,6 +191,10 @@ public class UserService { attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes(); } else if (authToken instanceof JwtAuthenticationToken) { attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes(); + } else if (authToken instanceof RememberMeAuthenticationToken) { + attributes = extractUserAttributes(authToken.getName()); + // attributes = new HashMap<>(); + // attributes = ((RememberMeAuthenticationToken) authToken).getTokenAttributes(); } else { throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!"); } diff --git a/src/main/java/com/sasiedzi/event/service/dto/AdminUserDTO.java b/src/main/java/com/sasiedzi/event/service/dto/AdminUserDTO.java index f6cf086..e68fdd4 100644 --- a/src/main/java/com/sasiedzi/event/service/dto/AdminUserDTO.java +++ b/src/main/java/com/sasiedzi/event/service/dto/AdminUserDTO.java @@ -8,10 +8,14 @@ import java.io.Serializable; import java.time.Instant; import java.util.Set; import java.util.stream.Collectors; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; /** * A DTO representing a user, with his authorities. */ +@Component +@RequestScope public class AdminUserDTO implements Serializable { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/sasiedzi/event/web/rest/AccountResource.java b/src/main/java/com/sasiedzi/event/web/rest/AccountResource.java index cfa2aca..fcc46c0 100644 --- a/src/main/java/com/sasiedzi/event/web/rest/AccountResource.java +++ b/src/main/java/com/sasiedzi/event/web/rest/AccountResource.java @@ -1,10 +1,12 @@ package com.sasiedzi.event.web.rest; +import com.sasiedzi.event.domain.CurrentUserHolder; import com.sasiedzi.event.service.UserService; import com.sasiedzi.event.service.dto.AdminUserDTO; import java.security.Principal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.web.bind.annotation.GetMapping; @@ -44,13 +46,16 @@ public class AccountResource { */ @GetMapping("/account") public AdminUserDTO getAccount(Principal principal) { - if (principal instanceof AbstractAuthenticationToken) { - return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal); + if (currentUser != null) { + return currentUser.getAdminUser(); } else { throw new AccountResourceException("User could not be found"); } } + @Autowired + CurrentUserHolder currentUser; + /** * {@code GET /authenticate} : check if the user is authenticated, and return its login. * diff --git a/src/main/java/com/sasiedzi/event/web/rest/LogoutResource.java b/src/main/java/com/sasiedzi/event/web/rest/LogoutResource.java index d21fde0..e155cc2 100644 --- a/src/main/java/com/sasiedzi/event/web/rest/LogoutResource.java +++ b/src/main/java/com/sasiedzi/event/web/rest/LogoutResource.java @@ -1,13 +1,21 @@ package com.sasiedzi.event.web.rest; +import com.sasiedzi.event.domain.CurrentUserHolder; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.oidc.OidcIdToken; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @@ -23,24 +31,47 @@ public class LogoutResource { this.registration = registrations.findByRegistrationId("oidc"); } + @Autowired + CurrentUserHolder currentUser; + /** * {@code POST /api/logout} : logout the current user. * * @param request the {@link HttpServletRequest}. - * @param idToken the ID token. + * @param principal principal with the ID token. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL. */ @PostMapping("/api/logout") - public ResponseEntity logout(HttpServletRequest request, @AuthenticationPrincipal(expression = "idToken") OidcIdToken idToken) { + public ResponseEntity logout(HttpServletRequest request, HttpServletResponse response) { + OidcIdToken idToken = null; + Authentication authentication = currentUser.getAuthentication(); StringBuilder logoutUrl = new StringBuilder(); - - logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString()); - String originUrl = request.getHeader(HttpHeaders.ORIGIN); + if (authentication != null && authentication.getPrincipal() instanceof DefaultOAuth2User) { + idToken = ((DefaultOidcUser) authentication.getPrincipal()).getIdToken(); - logoutUrl.append("?id_token_hint=").append(idToken.getTokenValue()).append("&post_logout_redirect_uri=").append(originUrl); + logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString()); + + if (idToken != null) { + logoutUrl.append("?id_token_hint=").append(idToken.getTokenValue()).append("&post_logout_redirect_uri=").append(originUrl); + } + } else { + logoutUrl.append(originUrl); + } + + new SecurityContextLogoutHandler().logout(request, response, null); + + // Ręczne usuwanie ciasteczka 'remember-me' + Cookie cookie = new Cookie("remember-me", null); + cookie.setPath("/"); + cookie.setMaxAge(0); + response.addCookie(cookie); + + HttpSession existingSession = request.getSession(); + if (existingSession != null) { + existingSession.invalidate(); + } - request.getSession().invalidate(); return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl.toString())); } } diff --git a/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java b/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java index 4b70ff7..cf27f67 100644 --- a/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java +++ b/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java @@ -1,5 +1,6 @@ package com.sasiedzi.event.web.rest; +import com.sasiedzi.event.domain.CurrentUserHolder; import com.sasiedzi.event.domain.User; import com.sasiedzi.event.domain.UserAccount; import com.sasiedzi.event.repository.UserAccountRepository; @@ -174,10 +175,12 @@ public class UserAccountResource { @GetMapping("/currentUser") public UserAccount getCurrentUserAccount() { - UserAccount userAccount = eventService.getOrCreateForCurrentUser(); - return userAccount; + return currentUser.getUserAccount(); } + @Autowired + CurrentUserHolder currentUser; + /** * {@code DELETE /user-accounts/:id} : delete the "id" userAccount. *