authentication
This commit is contained in:
@@ -3,15 +3,25 @@ package com.sasiedzi.event.config;
|
|||||||
import static org.springframework.security.config.Customizer.withDefaults;
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
import static org.springframework.security.oauth2.core.oidc.StandardClaimNames.PREFERRED_USERNAME;
|
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.*;
|
||||||
import com.sasiedzi.event.security.SecurityUtils;
|
import com.sasiedzi.event.security.SecurityUtils;
|
||||||
import com.sasiedzi.event.security.oauth2.AudienceValidator;
|
import com.sasiedzi.event.security.oauth2.AudienceValidator;
|
||||||
import com.sasiedzi.event.security.oauth2.CustomClaimConverter;
|
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 com.sasiedzi.event.web.filter.SpaWebFilter;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Supplier;
|
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.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
import org.springframework.context.annotation.Bean;
|
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.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
|
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.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
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.OidcUserRequest;
|
||||||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
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.jwt.*;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
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.authentication.www.BasicAuthenticationFilter;
|
||||||
import org.springframework.security.web.csrf.*;
|
import org.springframework.security.web.csrf.*;
|
||||||
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
||||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.context.annotation.RequestScope;
|
||||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||||
import tech.jhipster.config.JHipsterProperties;
|
import tech.jhipster.config.JHipsterProperties;
|
||||||
import tech.jhipster.web.filter.CookieCsrfFilter;
|
import tech.jhipster.web.filter.CookieCsrfFilter;
|
||||||
@@ -82,27 +102,140 @@ public class SecurityConfiguration {
|
|||||||
.authorizeHttpRequests(authz ->
|
.authorizeHttpRequests(authz ->
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
authz
|
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("/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("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/assets/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/assets/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/api/authenticate")).permitAll()
|
// .requestMatchers(mvc.pattern("/api/authenticate")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/api/auth-info")).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/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("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
||||||
.requestMatchers(mvc.pattern("/management/health")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/health")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/health/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/health/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/info")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/info")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/prometheus")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/prometheus")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
.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())))
|
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter())))
|
||||||
.oauth2Client(withDefaults());
|
.oauth2Client(withDefaults());
|
||||||
return http.build();
|
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<String, Object> attributes = extractUserAttributes(username);
|
||||||
|
Optional<com.sasiedzi.event.domain.User> 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<GrantedAuthority> extractRoles(String input) {
|
||||||
|
Set<GrantedAuthority> 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<String, Object> extractUserAttributes(String input) {
|
||||||
|
Map<String, Object> 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
|
@Bean
|
||||||
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
||||||
return new MvcRequestMatcher.Builder(introspector);
|
return new MvcRequestMatcher.Builder(introspector);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.sasiedzi.event.service;
|
|||||||
import com.sasiedzi.event.domain.*;
|
import com.sasiedzi.event.domain.*;
|
||||||
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
||||||
import com.sasiedzi.event.repository.*;
|
import com.sasiedzi.event.repository.*;
|
||||||
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import com.sasiedzi.event.web.rest.AccountResource;
|
import com.sasiedzi.event.web.rest.AccountResource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -10,12 +11,16 @@ import java.math.RoundingMode;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.RememberMeAuthenticationToken;
|
||||||
import org.springframework.security.core.AuthenticatedPrincipal;
|
import org.springframework.security.core.AuthenticatedPrincipal;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -235,20 +240,35 @@ public class EventService {
|
|||||||
return eventRepository.findById(event.getId());
|
return eventRepository.findById(event.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrentAuthenticatedUserAsDTO() {
|
@Autowired
|
||||||
if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
AdminUserDTO currentUser;
|
||||||
return null;
|
|
||||||
}
|
// public String getCurrentAuthenticatedUserAsDTO() {
|
||||||
if (SecurityContextHolder.getContext() == null) {
|
// if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
// if (SecurityContextHolder.getContext() == null) {
|
||||||
if (principal instanceof AuthenticatedPrincipal) {
|
// return null;
|
||||||
return ((AuthenticatedPrincipal) principal).getName();
|
// }
|
||||||
// return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
|
// Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
} else {
|
// if (principal instanceof AuthenticatedPrincipal) {
|
||||||
throw new RuntimeException("User could not be found");
|
// 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) {
|
public UserAccount createNewAccountForLogin(String login) {
|
||||||
@@ -264,9 +284,7 @@ public class EventService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserAccount getOrCreateForCurrentUser() {
|
public UserAccount getOrCreateUserAccountForLogin(String username) {
|
||||||
// if (true) return new UserAccount();
|
|
||||||
String username = getCurrentAuthenticatedUserAsDTO();
|
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
// List<UserAccount> userAccounts = userAccountRepository.findByUserLogin(currentAuthenticatedUserAsDTO.getLogin());
|
// List<UserAccount> userAccounts = userAccountRepository.findByUserLogin(currentAuthenticatedUserAsDTO.getLogin());
|
||||||
List<UserAccount> userAccounts = userAccountRepository
|
List<UserAccount> userAccounts = userAccountRepository
|
||||||
|
|||||||
@@ -8,14 +8,20 @@ import com.sasiedzi.event.repository.UserRepository;
|
|||||||
import com.sasiedzi.event.security.SecurityUtils;
|
import com.sasiedzi.event.security.SecurityUtils;
|
||||||
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import com.sasiedzi.event.service.dto.UserDTO;
|
import com.sasiedzi.event.service.dto.UserDTO;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.RememberMeAuthenticationToken;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
@@ -129,6 +135,48 @@ public class UserService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> extractUserAttributes(String input) {
|
||||||
|
Map<String, Object> 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.
|
* Returns the user from an OAuth 2.0 login or resource server with JWT.
|
||||||
* Synchronizes the user in the local repository.
|
* Synchronizes the user in the local repository.
|
||||||
@@ -143,6 +191,10 @@ public class UserService {
|
|||||||
attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes();
|
attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes();
|
||||||
} else if (authToken instanceof JwtAuthenticationToken) {
|
} else if (authToken instanceof JwtAuthenticationToken) {
|
||||||
attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes();
|
attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes();
|
||||||
|
} else if (authToken instanceof RememberMeAuthenticationToken) {
|
||||||
|
attributes = extractUserAttributes(authToken.getName());
|
||||||
|
// attributes = new HashMap<>();
|
||||||
|
// attributes = ((RememberMeAuthenticationToken) authToken).getTokenAttributes();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!");
|
throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ import java.io.Serializable;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
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.
|
* A DTO representing a user, with his authorities.
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
|
@RequestScope
|
||||||
public class AdminUserDTO implements Serializable {
|
public class AdminUserDTO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
import com.sasiedzi.event.service.UserService;
|
import com.sasiedzi.event.service.UserService;
|
||||||
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -44,13 +46,16 @@ public class AccountResource {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/account")
|
@GetMapping("/account")
|
||||||
public AdminUserDTO getAccount(Principal principal) {
|
public AdminUserDTO getAccount(Principal principal) {
|
||||||
if (principal instanceof AbstractAuthenticationToken) {
|
if (currentUser != null) {
|
||||||
return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
|
return currentUser.getAdminUser();
|
||||||
} else {
|
} else {
|
||||||
throw new AccountResourceException("User could not be found");
|
throw new AccountResourceException("User could not be found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code GET /authenticate} : check if the user is authenticated, and return its login.
|
* {@code GET /authenticate} : check if the user is authenticated, and return its login.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
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.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.ResponseEntity;
|
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.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
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.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@@ -23,24 +31,47 @@ public class LogoutResource {
|
|||||||
this.registration = registrations.findByRegistrationId("oidc");
|
this.registration = registrations.findByRegistrationId("oidc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code POST /api/logout} : logout the current user.
|
* {@code POST /api/logout} : logout the current user.
|
||||||
*
|
*
|
||||||
* @param request the {@link HttpServletRequest}.
|
* @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.
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL.
|
||||||
*/
|
*/
|
||||||
@PostMapping("/api/logout")
|
@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();
|
StringBuilder logoutUrl = new StringBuilder();
|
||||||
|
|
||||||
logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString());
|
|
||||||
|
|
||||||
String originUrl = request.getHeader(HttpHeaders.ORIGIN);
|
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()));
|
return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
import com.sasiedzi.event.domain.User;
|
import com.sasiedzi.event.domain.User;
|
||||||
import com.sasiedzi.event.domain.UserAccount;
|
import com.sasiedzi.event.domain.UserAccount;
|
||||||
import com.sasiedzi.event.repository.UserAccountRepository;
|
import com.sasiedzi.event.repository.UserAccountRepository;
|
||||||
@@ -174,10 +175,12 @@ public class UserAccountResource {
|
|||||||
|
|
||||||
@GetMapping("/currentUser")
|
@GetMapping("/currentUser")
|
||||||
public UserAccount getCurrentUserAccount() {
|
public UserAccount getCurrentUserAccount() {
|
||||||
UserAccount userAccount = eventService.getOrCreateForCurrentUser();
|
return currentUser.getUserAccount();
|
||||||
return userAccount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code DELETE /user-accounts/:id} : delete the "id" userAccount.
|
* {@code DELETE /user-accounts/:id} : delete the "id" userAccount.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user